* Implements PME force gathering tests.
*
* \author Aleksei Iupinov <a.yupinov@gmail.com>
+ * \author Mark Abraham <mark.j.abraham@gmail.com>
* \ingroup module_ewald
*/
namespace
{
-/* Valid input instances */
-
-//! A couple of valid inputs for boxes.
-std::vector<Matrix3x3> const c_sampleBoxes{
- // normal box
- 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 } },
-};
-
//! A couple of valid inputs for grid sizes
-std::vector<IVec> const c_sampleGridSizes{ IVec{ 16, 12, 14 }, IVec{ 13, 15, 11 } };
-//! Random charges
-std::vector<real> 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<IVec> 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<IVec> const c_inputGridSizes{ IVec{ 16, 12, 14 }, IVec{ 13, 15, 11 } };
-// 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<real> 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 structure for all the spline data which depends in size both on the PME order and atom count
+struct SplineData
+{
+ //! Spline values
+ SplineParamsVector splineValues;
+ //! Spline derivatives
+ SplineParamsVector splineDerivatives;
};
-//! 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<real> 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,
-};
+//! Return synthetic spline data to gather
+SplineData getSplineData(const int pmeOrder, const int atomCount)
+{
+ // Spline values/derivatives below are also generated randomly, so
+ // they are bogus, but that should not affect the reproducibility,
+ // which is what we're after.
+
+ //! A lot of random input spline values - should have at least (max PME order = 5) * (DIM = 3) * (total unique atom number in all test cases = 13) values
+ static const std::vector<real> s_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 random input spline derivatives - should have at least (max PME order = 5) * (DIM = 3) * (total unique atom number in all test cases = 13) values
+ static const std::vector<real> s_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,
+ };
+
+ SplineData splineData;
+ const int dimSize = atomCount * pmeOrder;
+ for (int dimIndex = 0; dimIndex < DIM; dimIndex++)
+ {
+ splineData.splineValues[dimIndex] =
+ SplineParamsDimVector(s_sampleSplineValuesFull).subArray(dimIndex * dimSize, dimSize);
+ splineData.splineDerivatives[dimIndex] =
+ SplineParamsDimVector(s_sampleSplineDerivativesFull).subArray(dimIndex * dimSize, dimSize);
+ }
+ return splineData;
+}
-//! 2 c_sample grids - only non-zero values have to be listed
-std::vector<SparseRealGridValuesInput> 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 },
- } };
+//! Two input grids - only non-zero values have to be listed
+const std::map<std::string, SparseRealGridValuesInput> c_inputGrids = {
+ { "first",
+ 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 },
+ } },
+ { "second",
+ 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<RVec> const c_sampleForcesFull{
RVec{ 0.47F, 0.04F, 0.47F }, RVec{ 0.34F, 0.71F, 0.52F }
};
-//! PME orders to test
-std::vector<int> const pmeOrders{ 3, 4, 5 };
-//! Atom counts to test
-std::vector<size_t> const atomCounts{ 1, 2, 13 };
-
-/* Helper structures for test input */
-
-//! A structure for all the spline data which depends in size both on the PME order and atom count
-struct AtomAndPmeOrderSizedData
-{
- //! Spline values
- SplineParamsVector splineValues;
- //! Spline derivatives
- SplineParamsVector splineDerivatives;
-};
-
-//! A structure for all the input atom data which depends in size on atom count - including a range of spline data for different PME orders
-struct AtomSizedData
+/*! \brief A structure for the input atom data, which depends in size on atom count */
+struct TestSystem
{
//! Gridline indices
GridLineIndicesVector gridLineIndices;
ChargesVector charges;
//! Coordinates
CoordinatesVector coordinates;
- //! Spline data for different orders
- std::map<int, AtomAndPmeOrderSizedData> splineDataByPmeOrder;
};
-//! A range of the test input data sets, uniquely identified by the atom count
-typedef std::map<size_t, AtomSizedData> InputDataByAtomCount;
+/*! \brief Test systems to use
+ *
+ * The coordinates are intentionally bogus in this test - only the
+ * size matters; the gridline indices are fed directly as inputs */
+// TODO use NaN?
+std::map<std::string, TestSystem> c_testSystems = {
+ { "1 atom",
+ { GridLineIndicesVector{ { IVec(4, 2, 6) } },
+ ChargesVector{ 4.95F },
+ CoordinatesVector(1, { 1e6, 1e7, -1e8 }) } },
+ { "2 atoms",
+ { GridLineIndicesVector{ { IVec(1, 4, 10), IVec(0, 6, 6) } },
+ ChargesVector{ { 3.11F, 3.97F } },
+ CoordinatesVector(2, { 1e6, 1e7, -1e8 }) } },
+ { "13 atoms",
+ { GridLineIndicesVector{ {
+ 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 },
+ } },
+ ChargesVector{ { 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 } },
+ CoordinatesVector(13, { 1e6, 1e7, -1e8 }) } },
+};
/*! \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.
*/
-typedef std::tuple<Matrix3x3, int, IVec, SparseRealGridValuesInput, size_t> GatherInputParameters;
+typedef std::tuple<std::string, int, IVec, std::string, std::string> GatherInputParameters;
-//! Test fixture
-class PmeGatherTest : public ::testing::TestWithParam<GatherInputParameters>
+//! Help GoogleTest name our test cases
+std::string nameOfTest(const testing::TestParamInfo<GatherInputParameters>& info)
{
-private:
- //! Storage of all the input atom datasets
- static InputDataByAtomCount s_inputAtomDataSets_;
+ std::string testName = formatString(
+ "box_%s_"
+ "order_%d_"
+ "grid_%d_%d_%d_"
+ "gridvalues_%s_"
+ "system_%s",
+ std::get<0>(info.param).c_str(),
+ std::get<1>(info.param),
+ std::get<2>(info.param)[XX],
+ std::get<2>(info.param)[YY],
+ std::get<2>(info.param)[ZZ],
+ std::get<3>(info.param).c_str(),
+ std::get<4>(info.param).c_str());
+
+ // Note that the returned names must be unique and may use only
+ // alphanumeric ASCII characters. It's not supposed to contain
+ // underscores (see the GoogleTest FAQ
+ // why-should-test-suite-names-and-test-names-not-contain-underscore),
+ // but doing so works for now, is likely to remain so, and makes
+ // such test names much more readable.
+ testName = replaceAll(testName, "-", "_");
+ testName = replaceAll(testName, ".", "_");
+ testName = replaceAll(testName, " ", "_");
+ return testName;
+}
+//! Test fixture
+class GatherTest : public ::testing::TestWithParam<GatherInputParameters>
+{
public:
- PmeGatherTest() = default;
+ GatherTest() = default;
//! Sets the input atom data references and programs once
static void SetUpTestSuite()
{
- 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)
- {
- 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;
- }
- s_inputAtomDataSets_[atomCount] = atomData;
- }
s_pmeTestHardwareContexts = createPmeTestHardwareContextList();
- g_allowPmeWithSyclForTesting = true; // We support PmeGather with SYCL
+ g_allowPmeWithSyclForTesting = true; // We support Gather with SYCL
}
static void TearDownTestSuite()
static void runTest()
{
/* Getting the input */
- Matrix3x3 box;
- int pmeOrder;
- IVec gridSize;
- size_t atomCount;
- SparseRealGridValuesInput nonZeroGridValues;
- std::tie(box, pmeOrder, gridSize, nonZeroGridValues, atomCount) = GetParam();
- auto inputAtomData = s_inputAtomDataSets_[atomCount];
- auto inputAtomSplineData = inputAtomData.splineDataByPmeOrder[pmeOrder];
+ int pmeOrder;
+ IVec gridSize;
+ std::string boxName, gridValuesName, testSystemName;
+ std::tie(boxName, pmeOrder, gridSize, gridValuesName, testSystemName) = GetParam();
+ Matrix3x3 box = c_inputBoxes.at(boxName);
+ const SparseRealGridValuesInput& nonZeroGridValues = c_inputGrids.at(gridValuesName);
+ TestSystem testSystem = c_testSystems.at(testSystemName);
+ int atomCount = testSystem.coordinates.size();
+ SplineData splineData = getSplineData(pmeOrder, atomCount);
/* Storing the input where it's needed, running the test */
t_inputrec inputRec;
/* Describing the test uniquely */
SCOPED_TRACE(
formatString("Testing force gathering on %s for PME grid size %d %d %d"
- ", order %d, %zu atoms",
+ ", order %d, %d atoms",
pmeTestHardwareContext->description().c_str(),
gridSize[XX],
gridSize[YY],
pmeTestHardwareContext->deviceStream())
: nullptr;
- pmeInitAtoms(pmeSafe.get(),
- stateGpu.get(),
- codePath,
- inputAtomData.coordinates,
- inputAtomData.charges);
+ pmeInitAtoms(pmeSafe.get(), stateGpu.get(), codePath, testSystem.coordinates, testSystem.charges);
/* Setting some more inputs */
pmeSetRealGrid(pmeSafe.get(), codePath, nonZeroGridValues);
- pmeSetGridLineIndices(pmeSafe.get(), codePath, inputAtomData.gridLineIndices);
+ pmeSetGridLineIndices(pmeSafe.get(), codePath, testSystem.gridLineIndices);
for (int dimIndex = 0; dimIndex < DIM; dimIndex++)
{
pmeSetSplineData(pmeSafe.get(),
codePath,
- inputAtomSplineData.splineValues[dimIndex],
+ splineData.splineValues[dimIndex],
PmeSplineDataType::Values,
dimIndex);
pmeSetSplineData(pmeSafe.get(),
codePath,
- inputAtomSplineData.splineDerivatives[dimIndex],
+ splineData.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");
+ GMX_RELEASE_ASSERT(ssize(inputForcesFull) >= atomCount, "Bad input forces size");
auto forces = ForcesVector(inputForcesFull).subArray(0, atomCount);
/* Running the force gathering itself */
static std::vector<std::unique_ptr<PmeTestHardwareContext>> s_pmeTestHardwareContexts;
};
-std::vector<std::unique_ptr<PmeTestHardwareContext>> PmeGatherTest::s_pmeTestHardwareContexts;
-
-// An instance of static atom data
-InputDataByAtomCount PmeGatherTest::s_inputAtomDataSets_;
+std::vector<std::unique_ptr<PmeTestHardwareContext>> GatherTest::s_pmeTestHardwareContexts;
//! Test for PME force gathering
-TEST_P(PmeGatherTest, ReproducesOutputs)
+TEST_P(GatherTest, WorksWith)
{
EXPECT_NO_THROW_GMX(runTest());
}
+//! Moved out from instantiations for readability
+const auto c_inputBoxNames = ::testing::Values("rect", "tric");
+//! Moved out from instantiations for readability
+const auto c_inputGridNames = ::testing::Values("first", "second");
+//! Moved out from instantiations for readability
+const auto c_inputTestSystemNames = ::testing::Values("1 atom", "2 atoms", "13 atoms");
+
//! Instantiation of the PME gathering test
-INSTANTIATE_TEST_SUITE_P(SaneInput,
- PmeGatherTest,
- ::testing::Combine(::testing::ValuesIn(c_sampleBoxes),
- ::testing::ValuesIn(pmeOrders),
- ::testing::ValuesIn(c_sampleGridSizes),
- ::testing::ValuesIn(c_sampleGrids),
- ::testing::ValuesIn(atomCounts)));
+INSTANTIATE_TEST_SUITE_P(Pme,
+ GatherTest,
+ ::testing::Combine(c_inputBoxNames,
+ ::testing::ValuesIn(c_inputPmeOrders),
+ ::testing::ValuesIn(c_inputGridSizes),
+ c_inputGridNames,
+ c_inputTestSystemNames),
+ nameOfTest);
} // namespace
} // namespace test
* Implements PME solving tests.
*
* \author Aleksei Iupinov <a.yupinov@gmail.com>
+ * \author Mark Abraham <mark.j.abraham@gmail.com>
* \ingroup module_ewald
*/
{
namespace
{
+
+//! A couple of valid inputs for grid sizes
+std::vector<IVec> const c_inputGridSizes{ IVec{ 16, 12, 28 }, IVec{ 9, 7, 23 } };
+
+//! Two input complex grids - only non-zero values have to be listed
+const std::map<std::string, SparseComplexGridValuesInput> c_inputGridValues = {
+ { "first",
+ 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 } },
+ } },
+ { "second",
+ 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 } },
+ } },
+};
+
/*! \brief Convenience typedef of the test input parameters - unit cell box, complex grid dimensions, complex grid values,
* electrostatic constant epsilon_r, Ewald splitting parameters ewaldcoeff_q and ewaldcoeff_lj, solver type
* Output: transformed local grid (Fourier space); optionally reciprocal energy and virial matrix.
* TODO:
* Implement and test Lorentz-Berthelot
*/
-typedef std::tuple<Matrix3x3, IVec, SparseComplexGridValuesInput, double, double, double, PmeSolveAlgorithm> SolveInputParameters;
+typedef std::tuple<std::string, IVec, std::string, double, double, double, PmeSolveAlgorithm> SolveInputParameters;
+
+const char* enumValueToString(PmeSolveAlgorithm enumValue)
+{
+ static constexpr gmx::EnumerationArray<PmeSolveAlgorithm, const char*> s_pmeSolveAlgorithmNames = {
+ "Coulomb", "LJ"
+ };
+ return s_pmeSolveAlgorithmNames[enumValue];
+}
+
+//! Help GoogleTest name our test cases
+std::string nameOfTest(const testing::TestParamInfo<SolveInputParameters>& info)
+{
+ std::string testName = formatString(
+ "box_%s_"
+ "grid_%d_%d_%d_"
+ "gridvalues_%s_"
+ "eps_%g_"
+ "ewaldq_%g_"
+ "ewaldlj_%g_"
+ "method_%s",
+ std::get<0>(info.param).c_str(),
+ std::get<1>(info.param)[XX],
+ std::get<1>(info.param)[YY],
+ std::get<1>(info.param)[ZZ],
+ std::get<2>(info.param).c_str(),
+ std::get<3>(info.param),
+ std::get<4>(info.param),
+ std::get<5>(info.param),
+ enumValueToString(std::get<6>(info.param)));
+
+ // Note that the returned names must be unique and may use only
+ // alphanumeric ASCII characters. It's not supposed to contain
+ // underscores (see the GoogleTest FAQ
+ // why-should-test-suite-names-and-test-names-not-contain-underscore),
+ // but doing so works for now, is likely to remain so, and makes
+ // such test names much more readable.
+ testName = replaceAll(testName, "-", "_");
+ testName = replaceAll(testName, ".", "_");
+ testName = replaceAll(testName, " ", "_");
+ return testName;
+}
//! Test fixture
-class PmeSolveTest : public ::testing::TestWithParam<SolveInputParameters>
+class SolveTest : public ::testing::TestWithParam<SolveInputParameters>
{
public:
- PmeSolveTest() = default;
+ SolveTest() = default;
//! Sets the programs once
static void SetUpTestSuite()
{
s_pmeTestHardwareContexts = createPmeTestHardwareContextList();
- g_allowPmeWithSyclForTesting = true; // We support PmeSolve with SYCL
+ g_allowPmeWithSyclForTesting = true; // We support Solve with SYCL
}
static void TearDownTestSuite()
static 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) =
+ IVec gridSize;
+ double epsilon_r;
+ double ewaldCoeff_q;
+ double ewaldCoeff_lj;
+ PmeSolveAlgorithm method;
+ std::string boxName, gridValuesName;
+ std::tie(boxName, gridSize, gridValuesName, epsilon_r, ewaldCoeff_q, ewaldCoeff_lj, method) =
GetParam();
+ Matrix3x3 box = c_inputBoxes.at(boxName);
+ const SparseComplexGridValuesInput& nonZeroGridValues = c_inputGridValues.at(gridValuesName);
/* Storing the input where it's needed, running the test */
t_inputrec inputRec;
static std::vector<std::unique_ptr<PmeTestHardwareContext>> s_pmeTestHardwareContexts;
};
-std::vector<std::unique_ptr<PmeTestHardwareContext>> PmeSolveTest::s_pmeTestHardwareContexts;
+std::vector<std::unique_ptr<PmeTestHardwareContext>> SolveTest::s_pmeTestHardwareContexts;
/*! \brief Test for PME solving */
-TEST_P(PmeSolveTest, ReproducesOutputs)
+TEST_P(SolveTest, WorksWith)
{
EXPECT_NO_THROW_GMX(runTest());
}
-/* Valid input instances */
-
-//! A couple of valid inputs for boxes.
-std::vector<Matrix3x3> const c_sampleBoxes{
- // normal box
- 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 } },
-};
-
-//! A couple of valid inputs for grid sizes
-std::vector<IVec> 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);
-//! 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<SparseComplexGridValuesInput> 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 } },
- }
-};
-
+const auto c_inputBoxNames = ::testing::Values("rect", "tric");
//! Moved out from instantiations for readability
-const auto c_inputGrids = ::testing::ValuesIn(c_sampleGrids);
+const auto c_inputGridNames = ::testing::Values("first", "second");
//! Moved out from instantiations for readability
const auto c_inputEpsilon_r = ::testing::Values(1.2);
//! Moved out from instantiations for readability
const auto c_inputMethods = ::testing::Values(PmeSolveAlgorithm::Coulomb, PmeSolveAlgorithm::LennardJones);
//! Instantiation of the PME solving test
-INSTANTIATE_TEST_SUITE_P(SaneInput,
- PmeSolveTest,
- ::testing::Combine(c_inputBoxes,
- c_inputGridSizes,
- c_inputGrids,
+INSTANTIATE_TEST_SUITE_P(Pme,
+ SolveTest,
+ ::testing::Combine(c_inputBoxNames,
+ ::testing::ValuesIn(c_inputGridSizes),
+ c_inputGridNames,
c_inputEpsilon_r,
c_inputEwaldCoeff_q,
c_inputEwaldCoeff_lj,
- c_inputMethods));
+ c_inputMethods),
+ nameOfTest);
//! A few more instances to check that different ewaldCoeff_q actually affects results of the Coulomb solver
-INSTANTIATE_TEST_SUITE_P(DifferentEwaldCoeffQ,
- PmeSolveTest,
- ::testing::Combine(c_inputBoxes,
- c_inputGridSizes,
- c_inputGrids,
+INSTANTIATE_TEST_SUITE_P(PmeDiffEwaldQ,
+ SolveTest,
+ ::testing::Combine(c_inputBoxNames,
+ ::testing::ValuesIn(c_inputGridSizes),
+ c_inputGridNames,
c_inputEpsilon_r,
::testing::Values(0.4),
c_inputEwaldCoeff_lj,
- ::testing::Values(PmeSolveAlgorithm::Coulomb)));
+ ::testing::Values(PmeSolveAlgorithm::Coulomb)),
+ nameOfTest);
//! 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_SUITE_P(DifferentEwaldCoeffLJ,
- PmeSolveTest,
- ::testing::Combine(c_inputBoxes,
- c_inputGridSizes,
- c_inputGrids,
+INSTANTIATE_TEST_SUITE_P(PmeDiffEwaldLJ,
+ SolveTest,
+ ::testing::Combine(c_inputBoxNames,
+ ::testing::ValuesIn(c_inputGridSizes),
+ c_inputGridNames,
c_inputEpsilon_r,
c_inputEwaldCoeff_q,
::testing::Values(2.35),
- ::testing::Values(PmeSolveAlgorithm::LennardJones)));
+ ::testing::Values(PmeSolveAlgorithm::LennardJones)),
+ nameOfTest);
//! A few more instances to check that different epsilon_r actually affects results of all solvers
-INSTANTIATE_TEST_SUITE_P(DifferentEpsilonR,
- PmeSolveTest,
- ::testing::Combine(c_inputBoxes,
- c_inputGridSizes,
- c_inputGrids,
+INSTANTIATE_TEST_SUITE_P(PmeDiffEps,
+ SolveTest,
+ ::testing::Combine(c_inputBoxNames,
+ ::testing::ValuesIn(c_inputGridSizes),
+ c_inputGridNames,
testing::Values(1.9),
c_inputEwaldCoeff_q,
c_inputEwaldCoeff_lj,
- c_inputMethods));
+ c_inputMethods),
+ nameOfTest);
} // namespace
} // namespace test
* Implements PME spline computation and charge spreading tests.
*
* \author Aleksei Iupinov <a.yupinov@gmail.com>
+ * \author Mark Abraham <mark.j.abraham@gmail.com>
* \ingroup module_ewald
*/
namespace
{
+//! A couple of valid inputs for grid sizes
+std::vector<IVec> const c_inputGridSizes{ IVec{ 16, 12, 14 }, IVec{ 19, 17, 11 } };
+
//! PME spline and spread code path being tested
-enum class PmeSplineAndSpreadOptions
+enum class SplineAndSpreadOptions
{
SplineOnly,
SpreadOnly,
- SplineAndSpreadUnified
+ SplineAndSpreadUnified,
+ Count
};
+struct TestSystem
+{
+ CoordinatesVector coordinates;
+ ChargesVector charges;
+};
+
+const std::unordered_map<std::string, TestSystem> c_testSystems = {
+ { "1 atom", { CoordinatesVector{ { 5.59F, 1.37F, 0.95F } }, ChargesVector{ 4.95F } } },
+ { "2 atoms",
+ { CoordinatesVector{
+ // 2 box lengths in x
+ { 16.0F, 1.02F, 0.22F },
+ { 0.034F, 1.65F, 0.22F },
+ },
+ ChargesVector{ {
+ 3.11F,
+ 3.97F,
+ } } } },
+ { "13 atoms",
+ { CoordinatesVector{
+ { 0.33F, 0.92F, 1.56F },
+ { 1.16F, 0.75F, 0.39F },
+ { 0.5F, 1.63F, 1.14F },
+ // > 2 box lengths in x
+ { 16.0001F, 1.52F, 1.19F },
+ // > 2 box lengths in z
+ { 1.43F, 1.1F, 4.1F },
+ // negative x
+ { -1.08F, 1.19F, 0.08F },
+ { 1.6F, 0.93F, 0.53F },
+ // negative y
+ { 1.32F, -1.48F, 0.16F },
+ { 0.87F, 0.0F, 0.33F },
+ // > 2 box lengths in y, negative z
+ { 0.95F, 7.7F, -0.48F },
+ { 1.23F, 0.91F, 0.68F },
+ { 0.19F, 1.45F, 0.94F },
+ { 1.28F, 0.46F, 0.38F },
+ },
+ ChargesVector{ 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 } } },
+};
+
+/* Valid input instances */
+
/*! \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<Matrix3x3, int, IVec, CoordinatesVector, ChargesVector> SplineAndSpreadInputParameters;
+typedef std::tuple<std::string, int, IVec, std::string> SplineAndSpreadInputParameters;
+
+//! Help GoogleTest name our test cases
+std::string nameOfTest(const testing::TestParamInfo<SplineAndSpreadInputParameters>& info)
+{
+ std::string testName = formatString(
+ "box_%s_"
+ "order_%d_"
+ "grid_%d_%d_%d_"
+ "system_%s",
+ std::get<0>(info.param).c_str(),
+ std::get<1>(info.param),
+ std::get<2>(info.param)[XX],
+ std::get<2>(info.param)[YY],
+ std::get<2>(info.param)[ZZ],
+ std::get<3>(info.param).c_str());
+
+ // Note that the returned names must be unique and may use only
+ // alphanumeric ASCII characters. It's not supposed to contain
+ // underscores (see the GoogleTest FAQ
+ // why-should-test-suite-names-and-test-names-not-contain-underscore),
+ // but doing so works for now, is likely to remain so, and makes
+ // such test names much more readable.
+ testName = replaceAll(testName, "-", "_");
+ testName = replaceAll(testName, ".", "_");
+ testName = replaceAll(testName, " ", "_");
+ return testName;
+}
+
+const char* enumValueToString(SplineAndSpreadOptions enumValue)
+{
+ static constexpr gmx::EnumerationArray<SplineAndSpreadOptions, const char*> s_splineAndSpreadOptionsNames = {
+ "spline computation",
+ "charge spreading",
+ "spline computation and charge spreading (fused)",
+ };
+ return s_splineAndSpreadOptionsNames[enumValue];
+}
/*! \brief Test fixture for testing both atom spline parameter computation and charge spreading.
* These 2 stages of PME are tightly coupled in the code.
*/
-class PmeSplineAndSpreadTest : public ::testing::TestWithParam<SplineAndSpreadInputParameters>
+class SplineAndSpreadTest : public ::testing::TestWithParam<SplineAndSpreadInputParameters>
{
public:
- PmeSplineAndSpreadTest() = default;
+ SplineAndSpreadTest() = default;
- //! Sets the programs once
static void SetUpTestSuite()
{
s_pmeTestHardwareContexts = createPmeTestHardwareContextList();
static void runTest()
{
/* Getting the input */
- Matrix3x3 box;
- int pmeOrder;
- IVec gridSize;
- CoordinatesVector coordinates;
- ChargesVector charges;
+ int pmeOrder;
+ IVec gridSize;
+ std::string boxName, testSystemName;
- std::tie(box, pmeOrder, gridSize, coordinates, charges) = GetParam();
- const size_t atomCount = coordinates.size();
+ std::tie(boxName, pmeOrder, gridSize, testSystemName) = GetParam();
+ Matrix3x3 box = c_inputBoxes.at(boxName);
+ const CoordinatesVector& coordinates = c_testSystems.at(testSystemName).coordinates;
+ const ChargesVector& charges = c_testSystems.at(testSystemName).charges;
+ const size_t atomCount = coordinates.size();
/* Storing the input where it's needed */
t_inputrec inputRec;
inputRec.coulombtype = CoulombInteractionType::Pme;
inputRec.epsilon_r = 1.0;
- const std::map<PmeSplineAndSpreadOptions, std::string> 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
continue;
}
- for (const auto& option : optionsToTest)
+ for (SplineAndSpreadOptions option : EnumerationWrapper<SplineAndSpreadOptions>())
{
/* Describing the test uniquely in case it fails */
SCOPED_TRACE(
formatString("Testing %s on %s for PME grid size %d %d %d"
", order %d, %zu atoms",
- option.second.c_str(),
+ enumValueToString(option),
pmeTestHardwareContext->description().c_str(),
gridSize[XX],
gridSize[YY],
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 == SplineAndSpreadOptions::SplineOnly)
+ || (option == SplineAndSpreadOptions::SplineAndSpreadUnified);
+ const bool spreadCharges = (option == SplineAndSpreadOptions::SpreadOnly)
+ || (option == SplineAndSpreadOptions::SplineAndSpreadUnified);
if (!computeSplines)
{
static std::vector<std::unique_ptr<PmeTestHardwareContext>> s_pmeTestHardwareContexts;
};
-std::vector<std::unique_ptr<PmeTestHardwareContext>> PmeSplineAndSpreadTest::s_pmeTestHardwareContexts;
+std::vector<std::unique_ptr<PmeTestHardwareContext>> SplineAndSpreadTest::s_pmeTestHardwareContexts;
/*! \brief Test for spline parameter computation and charge spreading. */
-TEST_P(PmeSplineAndSpreadTest, ReproducesOutputs)
+TEST_P(SplineAndSpreadTest, WorksWith)
{
EXPECT_NO_THROW_GMX(runTest());
}
-/* Valid input instances */
-
-//! A couple of valid inputs for boxes.
-std::vector<Matrix3x3> const c_sampleBoxes{
- // normal box
- 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 } },
-};
+//! Moved out from instantiations for readability
+const auto c_inputBoxNames = ::testing::Values("rect", "tric");
+//! Moved out from instantiations for readability
+const auto c_inputGridNames = ::testing::Values("first", "second");
+//! Moved out from instantiations for readability
+const auto c_inputTestSystemNames = ::testing::Values("1 atom", "2 atoms", "13 atoms");
+
+INSTANTIATE_TEST_SUITE_P(Pme,
+ SplineAndSpreadTest,
+ ::testing::Combine(c_inputBoxNames,
+ ::testing::ValuesIn(c_inputPmeOrders),
+ ::testing::ValuesIn(c_inputGridSizes),
+ c_inputTestSystemNames),
+ nameOfTest);
-//! A couple of valid inputs for grid sizes.
-std::vector<IVec> const c_sampleGridSizes{ IVec{ 16, 12, 14 }, IVec{ 19, 17, 11 } };
-
-//! Random charges
-std::vector<real> 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
-auto const c_sampleCharges2 = ChargesVector(c_sampleChargesFull).subArray(1, 2);
-//! 13 charges
-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 } };
-//! 1 coordinate vector
-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);
-//! 13 coordinate vectors
-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);
-//! 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_SUITE_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_SUITE_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_SUITE_P(SaneInput13,
- PmeSplineAndSpreadTest,
- ::testing::Combine(c_inputBoxes,
- c_inputPmeOrders,
- c_inputGridSizes,
- ::testing::Values(c_sampleCoordinates13),
- ::testing::Values(c_sampleCharges13)));
} // namespace
} // namespace test
} // namespace gmx