From: Joe Jordan Date: Wed, 26 May 2021 09:14:47 +0000 (+0000) Subject: Move t_forcetable and table enums to forcetable header X-Git-Url: http://biod.pnpi.spb.ru/gitweb/?a=commitdiff_plain;h=f6babacfe5692ee225a4161b4aaac19c00d1feaf;p=alexxy%2Fgromacs.git Move t_forcetable and table enums to forcetable header --- diff --git a/src/gromacs/listed_forces/pairs.cpp b/src/gromacs/listed_forces/pairs.cpp index a7b1837571..c23c5f0a87 100644 --- a/src/gromacs/listed_forces/pairs.cpp +++ b/src/gromacs/listed_forces/pairs.cpp @@ -425,7 +425,7 @@ static real do_pairs_general(int ftype, 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, + fr->pairsTable->interaction == TableInteraction::ElectrostaticVdwRepulsionVdwDispersion, "Pair interaction kernels need a table with Coulomb, repulsion and dispersion entries"); const real epsfac = fr->ic->epsfac; @@ -488,13 +488,13 @@ static real do_pairs_general(int ftype, } r2 = norm2(dx); - if (r2 >= fr->pairsTable->r * fr->pairsTable->r) + if (r2 >= fr->pairsTable->interactionRange * fr->pairsTable->interactionRange) { /* 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 */ if (!warned_rlimit) { - warning_rlimit(x, ai, aj, global_atom_index, sqrt(r2), fr->pairsTable->r); + warning_rlimit(x, ai, aj, global_atom_index, sqrt(r2), fr->pairsTable->interactionRange); warned_rlimit = TRUE; } continue; diff --git a/src/gromacs/mdlib/dispersioncorrection.cpp b/src/gromacs/mdlib/dispersioncorrection.cpp index 4494d09f68..4c6c092cc1 100644 --- a/src/gromacs/mdlib/dispersioncorrection.cpp +++ b/src/gromacs/mdlib/dispersioncorrection.cpp @@ -45,7 +45,6 @@ #include "gromacs/mdtypes/inputrec.h" #include "gromacs/mdtypes/interaction_const.h" #include "gromacs/mdtypes/md_enums.h" -#include "gromacs/mdtypes/nblist.h" #include "gromacs/tables/forcetable.h" #include "gromacs/topology/mtop_util.h" #include "gromacs/topology/topology.h" @@ -407,7 +406,7 @@ void DispersionCorrection::setInteractionParameters(InteractionParams* i /* 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(iParams->dispersionCorrectionTable_->interaction == GMX_TABLE_INTERACTION_VDWREP_VDWDISP, + GMX_ASSERT(iParams->dispersionCorrectionTable_->interaction == TableInteraction::VdwRepulsionVdwDispersion, "Dispersion-correction code needs a table with both repulsion and dispersion " "terms"); const real scale = iParams->dispersionCorrectionTable_->scale; diff --git a/src/gromacs/mdlib/wall.cpp b/src/gromacs/mdlib/wall.cpp index 89a3adb2e7..e030591213 100644 --- a/src/gromacs/mdlib/wall.cpp +++ b/src/gromacs/mdlib/wall.cpp @@ -97,7 +97,7 @@ void make_wall_tables(FILE* fplog, fr->wall_tab[w][egp] = make_tables(fplog, fr->ic.get(), 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 i = 0; i <= fr->wall_tab[w][egp]->numTablePoints; i++) { for (int j = 0; j < 8; j++) { @@ -128,7 +128,7 @@ static void tableForce(real r, const t_forcetable& tab, real Cd, real Cr, real* real rt = r * tabscale; int n0 = static_cast(rt); - if (n0 >= tab.n) + if (n0 >= tab.numTablePoints) { /* Beyond the table range, set V and F to zero */ *V = 0; diff --git a/src/gromacs/mdtypes/nblist.h b/src/gromacs/mdtypes/nblist.h index 63fc565ae7..ff737514a1 100644 --- a/src/gromacs/mdtypes/nblist.h +++ b/src/gromacs/mdtypes/nblist.h @@ -39,43 +39,6 @@ #include -#include "gromacs/mdtypes/md_enums.h" -#include "gromacs/utility/alignedallocator.h" -#include "gromacs/utility/real.h" - -/* The interactions contained in a (possibly merged) table - * for computing electrostatic, VDW repulsion and/or VDW dispersion - * contributions. - */ -enum gmx_table_interaction -{ - GMX_TABLE_INTERACTION_ELEC, - GMX_TABLE_INTERACTION_VDWREP_VDWDISP, - GMX_TABLE_INTERACTION_VDWEXPREP_VDWDISP, - GMX_TABLE_INTERACTION_VDWDISP, - GMX_TABLE_INTERACTION_ELEC_VDWREP_VDWDISP, - GMX_TABLE_INTERACTION_ELEC_VDWEXPREP_VDWDISP, - GMX_TABLE_INTERACTION_ELEC_VDWDISP, - GMX_TABLE_INTERACTION_NR -}; - -/* Different formats for table data. Cubic spline tables are typically stored - * with the four Y,F,G,H intermediate values (check tables.c for format), which - * makes it easy to load with a single 4-way SIMD instruction too. - * Linear tables only need one value per table point, or two if both V and F - * are calculated. However, with SIMD instructions this makes the loads unaligned, - * and in that case we store the data as F, D=F(i+1)-F(i), V, and then a blank value, - * which again makes it possible to load as a single instruction. - */ -enum gmx_table_format -{ - GMX_TABLE_FORMAT_CUBICSPLINE_YFGH, - GMX_TABLE_FORMAT_LINEAR_VF, - GMX_TABLE_FORMAT_LINEAR_V, - GMX_TABLE_FORMAT_LINEAR_F, - GMX_TABLE_FORMAT_LINEAR_FDV0, - GMX_TABLE_FORMAT_NR -}; struct t_nblist { @@ -91,29 +54,4 @@ struct t_nblist std::vector excl_fep; /* Exclusions for FEP with Verlet scheme */ }; -/* 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; /* 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 */ - std::vector> 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 - */ - 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) */ -}; - #endif /* GMX_MDTYPES_NBLIST_H */ diff --git a/src/gromacs/tables/forcetable.cpp b/src/gromacs/tables/forcetable.cpp index 6614b8f9b0..54a08a6543 100644 --- a/src/gromacs/tables/forcetable.cpp +++ b/src/gromacs/tables/forcetable.cpp @@ -41,8 +41,6 @@ #include -#include - #include "gromacs/fileio/xvgr.h" #include "gromacs/math/functions.h" #include "gromacs/math/multidimarray.h" @@ -51,8 +49,6 @@ #include "gromacs/mdspan/extensions.h" #include "gromacs/mdtypes/fcdata.h" #include "gromacs/mdtypes/interaction_const.h" -#include "gromacs/mdtypes/md_enums.h" -#include "gromacs/mdtypes/nblist.h" #include "gromacs/utility/arrayref.h" #include "gromacs/utility/cstringutil.h" #include "gromacs/utility/fatalerror.h" @@ -105,7 +101,7 @@ static const t_tab_props tprops[etabNR] = { struct t_tabledata { t_tabledata() = default; - t_tabledata(int n, int nx0, double tabscale, bool bAlloc); + t_tabledata(int n, int firstTableNum, double scale, bool bAlloc); int nx; int nx0; double tabscale; @@ -431,8 +427,8 @@ static void copy2table(int n, } } -t_tabledata::t_tabledata(int n, int nx0, double tabscale, bool bAlloc) : - nx(n), nx0(nx0), tabscale(tabscale) +t_tabledata::t_tabledata(int n, int firstTableNum, double scale, bool bAlloc) : + nx(n), nx0(firstTableNum), tabscale(scale) { if (bAlloc) { @@ -1261,8 +1257,8 @@ make_tables(FILE* fp, const interaction_const_t* ic, const char* fn, real rtab, int nx0, tabsel[etiNR]; real scalefactor; - auto table = std::make_unique(GMX_TABLE_INTERACTION_ELEC_VDWREP_VDWDISP, - GMX_TABLE_FORMAT_CUBICSPLINE_YFGH); + auto table = std::make_unique( + TableInteraction::ElectrostaticVdwRepulsionVdwDispersion, TableFormat::CubicsplineYfgh); b14only = ((flags & GMX_MAKETABLES_14ONLY) != 0); @@ -1277,13 +1273,12 @@ make_tables(FILE* fp, const interaction_const_t* ic, const char* fn, real rtab, set_table_type(tabsel, ic, b14only); } std::vector td; - table->r = rtab; - table->scale = 0; - table->n = 0; + table->interactionRange = rtab; + table->scale = 0; + table->numTablePoints = 0; - table->formatsize = 4; - table->ninteractions = etiNR; - table->stride = table->formatsize * table->ninteractions; + table->numInteractions = etiNR; + table->stride = table->formatsize * table->numInteractions; /* Check whether we have to read or generate */ useUserTable = FALSE; @@ -1299,7 +1294,7 @@ make_tables(FILE* fp, const interaction_const_t* ic, const char* fn, real rtab, td = read_tables(fp, fn, etiNR, 0); if (rtab == 0 || (flags & GMX_MAKETABLES_14ONLY)) { - table->n = td[0].nx; + table->numTablePoints = td[0].nx; } else { @@ -1311,7 +1306,7 @@ make_tables(FILE* fp, const interaction_const_t* ic, const char* fn, real rtab, fn, rtab); } - table->n = gmx::roundToInt(rtab * td[0].tabscale); + table->numTablePoints = gmx::roundToInt(rtab * td[0].tabscale); } table->scale = td[0].tabscale; nx0 = td[0].nx0; @@ -1325,15 +1320,15 @@ make_tables(FILE* fp, const interaction_const_t* ic, const char* fn, real rtab, #else table->scale = 500.0; #endif - table->n = static_cast(rtab * table->scale); - nx0 = 10; + table->numTablePoints = static_cast(rtab * table->scale); + nx0 = 10; } /* Each table type (e.g. coul,lj6,lj12) requires four - * numbers per table->n+1 data points. For performance reasons we want + * numbers per table->numTablePoints+1 data points. For performance reasons we want * the table data to be aligned to (at least) a 32-byte boundary. */ - table->data.resize(table->stride * (table->n + 1) * sizeof(real)); + table->data.resize(table->stride * (table->numTablePoints + 1) * sizeof(real)); for (int k = 0; (k < etiNR); k++) { @@ -1347,7 +1342,7 @@ make_tables(FILE* fp, const interaction_const_t* ic, const char* fn, real rtab, { scale /= ic->buckinghamBMax; } - td[k] = t_tabledata(table->n, nx0, scale, !useUserTable); + td[k] = t_tabledata(table->numTablePoints, nx0, scale, !useUserTable); fill_table(&(td[k]), tabsel[k], ic, b14only); if (fp) @@ -1381,7 +1376,14 @@ make_tables(FILE* fp, const interaction_const_t* ic, const char* fn, real rtab, 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->numTablePoints, + k * table->formatsize, + table->stride, + td[k].x, + td[k].v, + td[k].f, + scalefactor, + table->data); } return table; @@ -1423,19 +1425,18 @@ makeDispersionCorrectionTable(FILE* fp, const interaction_const_t* ic, real rtab * 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); - dispersionCorrectionTable->r = fullTable->r; - dispersionCorrectionTable->n = fullTable->n; - dispersionCorrectionTable->scale = fullTable->scale; - dispersionCorrectionTable->formatsize = fullTable->formatsize; - dispersionCorrectionTable->ninteractions = 2; + std::unique_ptr dispersionCorrectionTable = std::make_unique( + TableInteraction::VdwRepulsionVdwDispersion, fullTable->format); + dispersionCorrectionTable->interactionRange = fullTable->interactionRange; + dispersionCorrectionTable->numTablePoints = fullTable->numTablePoints; + dispersionCorrectionTable->scale = fullTable->scale; + dispersionCorrectionTable->numInteractions = 2; dispersionCorrectionTable->stride = - dispersionCorrectionTable->formatsize * dispersionCorrectionTable->ninteractions; + dispersionCorrectionTable->formatsize * dispersionCorrectionTable->numInteractions; dispersionCorrectionTable->data.resize(dispersionCorrectionTable->stride - * (dispersionCorrectionTable->n + 1)); + * (dispersionCorrectionTable->numTablePoints + 1)); - for (int i = 0; i <= fullTable->n; i++) + for (int i = 0; i <= fullTable->numTablePoints; i++) { for (int j = 0; j < 8; j++) { @@ -1446,8 +1447,14 @@ makeDispersionCorrectionTable(FILE* fp, const interaction_const_t* ic, real rtab return dispersionCorrectionTable; } -t_forcetable::t_forcetable(enum gmx_table_interaction interaction, enum gmx_table_format format) : - interaction(interaction), format(format), r(0), n(0), scale(0), formatsize(0), ninteractions(0), stride(0) +t_forcetable::t_forcetable(enum TableInteraction interaction, enum TableFormat format) : + interaction(interaction), + format(format), + interactionRange(0), + numTablePoints(0), + scale(0), + numInteractions(0), + stride(0) { } diff --git a/src/gromacs/tables/forcetable.h b/src/gromacs/tables/forcetable.h index 14cbfd7384..d2cde89c96 100644 --- a/src/gromacs/tables/forcetable.h +++ b/src/gromacs/tables/forcetable.h @@ -48,19 +48,76 @@ #include #include +#include +#include "gromacs/utility/alignedallocator.h" #include "gromacs/utility/real.h" struct EwaldCorrectionTables; struct bondedtable_t; struct interaction_const_t; -struct t_forcetable; /*! \brief Flag to select user tables for make_tables */ #define GMX_MAKETABLES_FORCEUSER (1 << 0) /*! \brief Flag to only make 1,4 pair tables for make_tables */ #define GMX_MAKETABLES_14ONLY (1 << 1) +//! \brief The types of interactions contained in the table +enum class TableInteraction : int +{ + VdwRepulsionVdwDispersion, + ElectrostaticVdwRepulsionVdwDispersion, + Count +}; + +/* Different formats for table data. Cubic spline tables are typically stored + * with the four Y,F,G,H intermediate values (check tables.c for format), which + * makes it easy to load with a single 4-way SIMD instruction too. + * Linear tables only need one value per table point, or two if both V and F + * are calculated. However, with SIMD instructions this makes the loads unaligned, + * and in that case we store the data as F, D=F(i+1)-F(i), V, and then a blank value, + * which again makes it possible to load as a single instruction. + */ +enum class TableFormat : int +{ + CubicsplineYfgh, + Count +}; + +//! \internal \brief Structure describing the data in a single table +struct t_forcetable +{ + t_forcetable(TableInteraction interaction, TableFormat format); + + ~t_forcetable(); + + //! Types of interactions stored in this table + TableInteraction interaction; + //! Interpolation type and data format + TableFormat format; + //! range of the table + real interactionRange; + //! n+1 is the number of table points + int numTablePoints; + //! distance (nm) between two table points + real scale; + //! The actual table data + std::vector> 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 + */ + + //! Number of fp variables for each table point (1 for F, 2 for VF, 4 for YFGH, etc.), only YFGH is implemented + static constexpr int formatsize = 4; + //! Number of interactions in table, 1 for coul-only, 3 for coul+rep+disp. + int numInteractions; + //! Distance to next table point (number of fp variables per table point in total) + int stride; +}; + /*! \brief Enumerated type to describe the interaction types in a table */ enum {