namespace Nbnxm
{
-#ifndef DOXYGEN
+/*! \internal
+ * \brief Bounding box for a nbnxm atom cluster
+ *
+ * \note Should be aligned in memory to enable 4-wide SIMD operations.
+ */
+struct BoundingBox
+{
+ /*! \internal
+ * \brief Corner for the bounding box, padded with one element to enable 4-wide SIMD operations
+ */
+ struct Corner
+ {
+ //! Returns a corner with the minimum coordinates along each dimension
+ static Corner min(const Corner &c1,
+ const Corner &c2)
+ {
+ Corner cMin;
-// TODO: Convert macros to constexpr int and replace BB_? indexing by struct with x,y,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.
+ */
+ cMin.padding = std::min(c1.padding, c2.padding);
-/* Pair search box lower and upper corner in x,y,z.
- * Store this in 4 iso 3 reals, which is useful with 4-wide SIMD.
- * To avoid complicating the code we also use 4 without 4-wide SIMD.
- */
-#define NNBSBB_C 4
-/* Pair search box lower and upper bound in z only. */
-#define NNBSBB_D 2
-/* Pair search box lower and upper corner x,y,z indices, entry 3 is unused */
-#define BB_X 0
-#define BB_Y 1
-#define BB_Z 2
+ return cMin;
+ }
-#endif // !DOXYGEN
+ //! Returns a corner with the maximum coordinates along each dimension
+ static Corner max(const Corner &c1,
+ const Corner &c2)
+ {
+ Corner cMax;
+ cMax.x = std::max(c1.x, c2.x);
+ cMax.y = std::max(c1.y, c2.y);
+ cMax.z = std::max(c1.z, c2.z);
+ cMax.padding = std::max(c1.padding, c2.padding);
-/* Bounding box for a nbnxn atom cluster */
-struct BoundingBox
-{
- float lower[NNBSBB_C];
- float upper[NNBSBB_C];
+ return cMax;
+ }
+
+ //! Returns a pointer for SIMD loading of a Corner object
+ const float *ptr() const
+ {
+ return &x;
+ }
+
+ //! Returns a pointer for SIMD storing of a Corner object
+ float *ptr()
+ {
+ return &x;
+ }
+
+ float x; //!< x coordinate
+ float y; //!< y coordinate
+ float z; //!< z coordinate
+ float padding; //!< padding, unused, but should be set to avoid operations on unitialized data
+ };
+
+ Corner lower; //!< lower, along x and y and z, corner
+ Corner upper; //!< upper, along x and y and z, corner
};
// TODO: Convert macros to constexpr int
+/* Pair search box lower and upper bound in z only. */
+#define NNBSBB_D 2
+
/* Bounding box calculations are (currently) always in single precision, so
* we only need to check for single precision support here.
* This uses less (cache-)memory and SIMD is faster, at least on x86.
/* Store bounding boxes corners as quadruplets: xxxxyyyyzzzz */
# define NBNXN_BBXXXX 1
-/* Size of bounding box corners quadruplet */
-# define NNBSBB_XXXX (NNBSBB_D*DIM*STRIDE_PBB)
+/* Size of a quadruplet of bounding boxes, each 2 corners, stored packed */
+# define NNBSBB_XXXX (2*DIM*STRIDE_PBB)
#else /* NBNXN_SEARCH_BB_SIMD4 */