summaryrefslogtreecommitdiff
path: root/tangle/LLBM/kernel/executor.h
diff options
context:
space:
mode:
Diffstat (limited to 'tangle/LLBM/kernel/executor.h')
-rw-r--r--tangle/LLBM/kernel/executor.h171
1 files changed, 171 insertions, 0 deletions
diff --git a/tangle/LLBM/kernel/executor.h b/tangle/LLBM/kernel/executor.h
new file mode 100644
index 0000000..942918d
--- /dev/null
+++ b/tangle/LLBM/kernel/executor.h
@@ -0,0 +1,171 @@
+#pragma once
+
+#include <LLBM/operator.h>
+
+namespace kernel {
+
+template <typename OPERATOR, typename DESCRIPTOR, typename T, typename S, typename... ARGS>
+__global__ void call_operator(
+ LatticeView<DESCRIPTOR,S> lattice
+ , std::size_t* cells
+ , std::size_t cell_count
+ , ARGS... args
+) {
+ const std::size_t index = blockIdx.x * blockDim.x + threadIdx.x;
+ if (!(index < cell_count)) {
+ return;
+ }
+ const std::size_t gid = cells[index];
+
+ S f_curr[DESCRIPTOR::q];
+ S f_next[DESCRIPTOR::q];
+ S* preshifted_f[DESCRIPTOR::q];
+ for (unsigned iPop=0; iPop < DESCRIPTOR::q; ++iPop) {
+ preshifted_f[iPop] = lattice.pop(iPop, gid);
+ f_curr[iPop] = *preshifted_f[iPop];
+ }
+ OPERATOR::template apply<T,S>(DESCRIPTOR(), f_curr, f_next, gid, std::forward<ARGS>(args)...);
+ for (unsigned iPop=0; iPop < DESCRIPTOR::q; ++iPop) {
+ *preshifted_f[iPop] = f_next[iPop];
+ }
+}
+
+template <typename OPERATOR, typename DESCRIPTOR, typename T, typename S, typename... ARGS>
+__global__ void call_operator(
+ LatticeView<DESCRIPTOR,S> lattice
+ , bool* mask
+ , ARGS... args
+) {
+ const std::size_t gid = blockIdx.x * blockDim.x + threadIdx.x;
+ if (!(gid < lattice.cuboid.volume) || !mask[gid]) {
+ return;
+ }
+
+ S f_curr[DESCRIPTOR::q];
+ S f_next[DESCRIPTOR::q];
+ S* preshifted_f[DESCRIPTOR::q];
+ for (unsigned iPop=0; iPop < DESCRIPTOR::q; ++iPop) {
+ preshifted_f[iPop] = lattice.pop(iPop, gid);
+ f_curr[iPop] = *preshifted_f[iPop];
+ }
+ OPERATOR::template apply<T,S>(DESCRIPTOR(), f_curr, f_next, gid, std::forward<ARGS>(args)...);
+ for (unsigned iPop=0; iPop < DESCRIPTOR::q; ++iPop) {
+ *preshifted_f[iPop] = f_next[iPop];
+ }
+}
+
+template <typename FUNCTOR, typename DESCRIPTOR, typename T, typename S, typename... ARGS>
+__global__ void call_functor(
+ LatticeView<DESCRIPTOR,S> lattice
+ , bool* mask
+ , ARGS... args
+) {
+ const std::size_t gid = blockIdx.x * blockDim.x + threadIdx.x;
+ if (!(gid < lattice.cuboid.volume) || !mask[gid]) {
+ return;
+ }
+
+ S f_curr[DESCRIPTOR::q];
+ S* preshifted_f[DESCRIPTOR::q];
+ for (unsigned iPop=0; iPop < DESCRIPTOR::q; ++iPop) {
+ preshifted_f[iPop] = lattice.pop(iPop, gid);
+ f_curr[iPop] = *preshifted_f[iPop];
+ }
+ FUNCTOR::template apply<T,S>(DESCRIPTOR(), f_curr, gid, std::forward<ARGS>(args)...);
+}
+
+template <typename DESCRIPTOR, typename T, typename S, typename... OPERATOR>
+__global__ void call_operators(
+ LatticeView<DESCRIPTOR,S> lattice
+ , OPERATOR... ops
+) {
+ const std::size_t gid = blockIdx.x * blockDim.x + threadIdx.x;
+ if (!(gid < lattice.cuboid.volume)) {
+ return;
+ }
+
+ S f_curr[DESCRIPTOR::q];
+ S f_next[DESCRIPTOR::q];
+ S* preshifted_f[DESCRIPTOR::q];
+ for (unsigned iPop=0; iPop < DESCRIPTOR::q; ++iPop) {
+ preshifted_f[iPop] = lattice.pop(iPop, gid);
+ f_curr[iPop] = *preshifted_f[iPop];
+ }
+ (ops.template apply<DESCRIPTOR,T,S>(DESCRIPTOR(), f_curr, f_next, gid) || ... || false);
+ for (unsigned iPop=0; iPop < DESCRIPTOR::q; ++iPop) {
+ *preshifted_f[iPop] = f_next[iPop];
+ }
+}
+
+template <typename OPERATOR, typename DESCRIPTOR, typename T, typename S, typename... ARGS>
+__global__ void call_operator_using_list(
+ LatticeView<DESCRIPTOR,S> lattice
+ , std::size_t count
+ , ARGS... args
+) {
+ const std::size_t index = blockIdx.x * blockDim.x + threadIdx.x;
+ if (!(index < count)) {
+ return;
+ }
+ OPERATOR::template apply<T,S>(lattice, index, count, std::forward<ARGS>(args)...);
+}
+
+template <typename OPERATOR, typename DESCRIPTOR, typename T, typename S, typename... ARGS>
+__global__ void call_operator_using_list(
+ DESCRIPTOR descriptor
+ , std::size_t count
+ , ARGS... args
+) {
+ const std::size_t index = blockIdx.x * blockDim.x + threadIdx.x;
+ if (!(index < count)) {
+ return;
+ }
+ OPERATOR::template apply<T,S>(descriptor, index, count, std::forward<ARGS>(args)...);
+}
+
+template <typename FUNCTOR, typename DESCRIPTOR, typename T, typename S, typename... ARGS>
+__global__ void call_spatial_functor(
+ LatticeView<DESCRIPTOR,S> lattice
+ , bool* mask
+ , ARGS... args
+) {
+ const std::size_t iX = blockIdx.x * blockDim.x + threadIdx.x;
+ const std::size_t iY = blockIdx.y * blockDim.y + threadIdx.y;
+ const std::size_t iZ = blockIdx.z * blockDim.z + threadIdx.z;
+ if (!(iX < lattice.cuboid.nX && iY < lattice.cuboid.nY && iZ < lattice.cuboid.nZ)) {
+ return;
+ }
+ const std::size_t gid = descriptor::gid(lattice.cuboid,iX,iY,iZ);
+ if (!mask[gid]) {
+ return;
+ }
+
+ S f_curr[DESCRIPTOR::q];
+ S* preshifted_f[DESCRIPTOR::q];
+ for (unsigned iPop=0; iPop < DESCRIPTOR::q; ++iPop) {
+ preshifted_f[iPop] = lattice.pop(iPop, gid);
+ f_curr[iPop] = *preshifted_f[iPop];
+ }
+ FUNCTOR::template apply<T,S>(DESCRIPTOR(), f_curr, lattice.cuboid, gid, iX, iY, iZ, std::forward<ARGS>(args)...);
+}
+
+template <typename OPERATOR, typename DESCRIPTOR, typename T, typename S, typename... ARGS>
+__global__ void call_spatial_operator(
+ descriptor::Cuboid<DESCRIPTOR> cuboid
+ , bool* mask
+ , ARGS... args
+) {
+ const std::size_t iX = blockIdx.x * blockDim.x + threadIdx.x;
+ const std::size_t iY = blockIdx.y * blockDim.y + threadIdx.y;
+ const std::size_t iZ = blockIdx.z * blockDim.z + threadIdx.z;
+ if (!(iX < cuboid.nX && iY < cuboid.nY && iZ < cuboid.nZ)) {
+ return;
+ }
+ const std::size_t gid = descriptor::gid(cuboid,iX,iY,iZ);
+ if (!mask[gid]) {
+ return;
+ }
+ OPERATOR::template apply<T,S>(DESCRIPTOR(), gid, iX, iY, iZ, std::forward<ARGS>(args)...);
+}
+
+}