From b44cd18a2daff94e5114dcb3c38873c8bf0793f5 Mon Sep 17 00:00:00 2001
From: James Willis <james.s.willis@durham.ac.uk>
Date: Mon, 28 Nov 2016 12:03:02 +0000
Subject: [PATCH] Implements a particle cache with an initialisation and read
 function.

---
 src/cache.h | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 115 insertions(+)
 create mode 100644 src/cache.h

diff --git a/src/cache.h b/src/cache.h
new file mode 100644
index 0000000000..ff09b5eb8d
--- /dev/null
+++ b/src/cache.h
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * This file is part of SWIFT.
+ * Copyright (c) 2016 James Willis (jame.s.willis@durham.ac.uk)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ ******************************************************************************/
+#ifndef SWIFT_CACHE_H
+#define SWIFT_CACHE_H
+
+/* Config parameters. */
+#include "../config.h"
+
+/* Local headers */
+#include "vector.h"
+#include "part.h"
+#include "cell.h"
+
+/* Cache struct to hold a local copy of a cells' particle 
+ * properties required for density/force calculations.*/
+struct cache {  
+
+  /* Particle x position. */
+  float *restrict x __attribute__((aligned(sizeof(float) * VEC_SIZE)));   
+  
+  /* Particle y position. */
+  float *restrict y __attribute__((aligned(sizeof(float) * VEC_SIZE)));
+
+  /* Particle z position. */
+  float *restrict z __attribute__((aligned(sizeof(float) * VEC_SIZE)));
+
+  /* Particle smoothing length. */
+  float *restrict h __attribute__((aligned(sizeof(float) * VEC_SIZE)));
+
+  /* Particle mass. */
+  float *restrict m __attribute__((aligned(sizeof(float) * VEC_SIZE)));
+
+  /* Particle x velocity. */
+  float *restrict vx __attribute__((aligned(sizeof(float) * VEC_SIZE)));
+
+  /* Particle y velocity. */
+  float *restrict vy __attribute__((aligned(sizeof(float) * VEC_SIZE)));
+
+  /* Particle z velocity. */
+  float *restrict vz __attribute__((aligned(sizeof(float) * VEC_SIZE)));
+
+  /* Cache size. */
+  int count;
+
+};
+
+struct cache cell_cache;
+
+/**
+ * @brief Allocate memory and initialise cache.
+ *
+ * @param c The cache.
+ * @param count Number of particles to allocate space for.
+ */
+__attribute__((always_inline)) INLINE void cache_init(struct cache *c, size_t count) {
+
+  /* Align cache on correct byte boundary and pad cache size to include 2 vector lengths for remainder operations. */
+  unsigned long alignment = sizeof(float) * VEC_SIZE;
+  unsigned int sizeBytes = (count + (2 * VEC_SIZE)) * sizeof(float);
+  int error = 0;
+
+  error += posix_memalign((void **)&c->x, alignment,sizeBytes);
+  error += posix_memalign((void **)&c->y, alignment,sizeBytes);
+  error += posix_memalign((void **)&c->z, alignment,sizeBytes);
+  error += posix_memalign((void **)&c->m, alignment,sizeBytes);
+  error += posix_memalign((void **)&c->vx, alignment,sizeBytes);
+  error += posix_memalign((void **)&c->vy, alignment,sizeBytes);
+  error += posix_memalign((void **)&c->vz, alignment,sizeBytes);
+  error += posix_memalign((void **)&c->h, alignment,sizeBytes);
+  
+  if (error !=0) error("Couldn't allocate cache, no. of particles: %d", (int)count);
+  c->count = count;
+}
+
+/**
+ * @brief Populate cache by reading in the particles in unsorted order.
+ *
+ * @param ci The #cell.
+ * @param ci_cache The cache.
+ */
+__attribute__((always_inline)) INLINE void cache_read_particles(const struct cell *const ci, struct cache *const ci_cache) {
+
+   /* Shift the particles positions to a local frame so single precision can be used instead of double precision. */
+   for (int i=0; i<ci->count; i++) {
+    ci_cache->x[i] = ci->parts[i].x[0] - ci->loc[0];
+    ci_cache->y[i] = ci->parts[i].x[1] - ci->loc[1];
+    ci_cache->z[i] = ci->parts[i].x[2] - ci->loc[2];
+    ci_cache->h[i] = ci->parts[i].h;
+    
+    ci_cache->m[i] = ci->parts[i].mass;
+    ci_cache->vx[i] = ci->parts[i].v[0];
+    ci_cache->vy[i] = ci->parts[i].v[1];
+    ci_cache->vz[i] = ci->parts[i].v[2];
+
+   }
+
+}
+
+#endif /* SWIFT_CACHE_H */
-- 
GitLab