Swarm-NG  1.1
helpers.hpp
Go to the documentation of this file.
1 /*************************************************************************
2  * Copyright (C) 2011 by Saleh Dindar and the Swarm-NG Development Team *
3  * *
4  * This program is free software; you can redistribute it and/or modify *
5  * it under the terms of the GNU General Public License as published by *
6  * the Free Software Foundation; either version 3 of the License. *
7  * *
8  * This program is distributed in the hope that it will be useful, *
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
11  * GNU General Public License for more details. *
12  * *
13  * You should have received a copy of the GNU General Public License *
14  * along with this program; if not, write to the *
15  * Free Software Foundation, Inc., *
16  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
17  ************************************************************************/
18 
25 #pragma once
26 
27 #include "device_settings.hpp"
28 #include "utilities.hpp"
29 
30 
55 template<int Begin, int End, int Step = 1>
56 struct Unroller {
57  template<typename Action>
58  __device__ static void step(const Action& action) {
59  action(Begin);
61  }
62 };
63 
65 template<int End, int Step>
66 struct Unroller<End, End, Step> {
67  template<typename Action>
68  __device__ static void step(const Action& action) { }
69 };
70 
71 
97 template<template<int> class T,int N,int MAXN,class B,class P>
98 struct choose {
99 B operator ()(const int& n, const P& x){
100  if(n == N)
101  return T<N>::choose(x);
102  else if(n <= MAXN && n > N)
104  else
105  return B();
106 }
107 };
108 
109 namespace swarm {
110 
111 
115 template<int i>
117  const static int n = i;
118 };
119 
120 
124 template<class implementation,class T>
125 __global__ void generic_kernel(implementation* integ,T compile_time_param) {
126  integ->kernel(compile_time_param);
127 }
128 
132 template< class implementation, class T>
133 void launch_template(implementation* integ, implementation* gpu_integ, T compile_time_param)
134 {
135  if(integ->get_ensemble().nbod() == T::n)
136  generic_kernel<<<integ->gridDim(), integ->threadDim(), integ->shmemSize() >>>(gpu_integ,compile_time_param);
137  else
138  ERROR("Error launching kernel. Active ensemble has " + inttostr(integ->get_ensemble().nbod()) + " bodies per system.\n");
139 
140 }
141 
142 
167 template<int N>
169  template<class integ_pair>
170  static void choose(integ_pair p){
172  typename integ_pair::first_type integ = p.first;
173 
174  int sys_p_block = integ->override_system_per_block();
175  const int nsys = integ->get_ensemble().nsys();
176  const int tps = integ->thread_per_system(ctp);
177  const int shm = integ->shmem_per_system(ctp);
178  if(sys_p_block == 0){
179  sys_p_block = optimized_system_per_block(SHMEM_CHUNK_SIZE, tps, shm);
180  }
181 
182 
183  const int nblocks = ( nsys + sys_p_block - 1 ) / sys_p_block;
184  const int shmemSize = sys_p_block * shm;
185 
186  dim3 gridDim;
187  find_best_factorization(gridDim.x,gridDim.y,nblocks);
188 
189  dim3 threadDim;
190  threadDim.x = sys_p_block;
191  threadDim.y = tps;
192 
193  int blocksize = threadDim.x * threadDim.y;
194  if(!check_cuda_limits(blocksize, shmemSize )){
195  throw runtime_error("The block size settings exceed CUDA requirements");
196  }
197 
198  generic_kernel<<<gridDim, threadDim, shmemSize>>>(p.second, ctp);
199  }
200 };
201 
202 
216 template<class implementation>
217 void launch_templatized_integrator(implementation* integ){
218 
219  if(integ->get_ensemble().nbod() <= MAX_NBODIES){
220  implementation* gpu_integ;
221  cudaErrCheck ( cudaMalloc(&gpu_integ,sizeof(implementation)) );
222  cudaErrCheck ( cudaMemcpy(gpu_integ,integ,sizeof(implementation),cudaMemcpyHostToDevice) );
223 
224  typedef std::pair<implementation*,implementation*> integ_pair ;
225  integ_pair p ( integ, gpu_integ );
226  int nbod = integ->get_ensemble().nbod();
227 
229  c( nbod, p );
230 
231  cudaFree(gpu_integ);
232  } else {
233  char b[100];
234  snprintf(b,100,"Invalid number of bodies. (Swarm-NG was compiled with MAX_NBODIES = %d bodies per system.)",MAX_NBODIES);
235  ERROR(b);
236  }
237 
238 }
239 
240 
241 
242 }