diff --git a/examples/lj_func.py b/examples/lj_func.py index 97d72009dd5a2ebeeab57f2c4ee72c851c4b3457..162d88df4b4a658b4d2cd520de41751cb3f4d770 100644 --- a/examples/lj_func.py +++ b/examples/lj_func.py @@ -31,4 +31,5 @@ psim.periodic(2.8) psim.vtk_output("output/test") psim.compute(lj, cutoff_radius, {'sigma6': sigma6, 'epsilon': epsilon}) psim.compute(euler, symbols={'dt': dt}) +psim.target(pairs.target_gpu()) psim.generate() diff --git a/src/pairs/__init__.py b/src/pairs/__init__.py index 98e050f763d8a0d64ab244ce37b96ebea28d8d93..75615c3f6bad7c19758e874342791649fed055d1 100644 --- a/src/pairs/__init__.py +++ b/src/pairs/__init__.py @@ -1,6 +1,13 @@ from pairs.code_gen.cgen import CGen +from pairs.code_gen.target import Target from pairs.sim.simulation import Simulation def simulation(ref, dims=3, timesteps=100, debug=False): return Simulation(CGen(f"{ref}.cpp", debug), dims, timesteps) + +def target_cpu(): + return Target(Target.Backend_CPP, Target.Feature_CPU) + +def target_gpu(): + return Target(Target.Backend_CUDA, Target.Feature_GPU) diff --git a/src/pairs/code_gen/target.py b/src/pairs/code_gen/target.py new file mode 100644 index 0000000000000000000000000000000000000000..30acef52b2dd7399a74742e5b943063c94183716 --- /dev/null +++ b/src/pairs/code_gen/target.py @@ -0,0 +1,39 @@ +class Target: + # Architectures + Arch_x86 = 0 + Arch_Nvidia = 1 + + # Backend + Backend_CPP = 0 + Backend_CUDA = 1 + Backend_LLVM = 2 + + # Features + Feature_CPU = 1 + Feature_AVX = 2 + Feature_AVX2 = 3 + Feature_AVX512 = 4 + Feature_GPU = 5 + + # Operating system + OS_Unknown = 0 + OS_Linux = 1 + OS_Windows = 2 + + def __init__(self, backend, features, arch=None, os=None): + self.backend = backend + self.features = features if isinstance(features, list) else [features] + self.arch = arch if arch is not None else Target.Arch_x86 if Target.Feature_CPU in self.features else Target.Arch_Nvidia + self.os = os if os is not None else Target.OS_Unknown + + def add_feature(self, feature): + self.features.append(feature) + + def has_feature(self, feature): + return feature in self.features + + def is_cpu(self): + return self.has_feature(Target.Feature_CPU) + + def is_gpu(self): + return self.has_feature(Target.Feature_GPU) diff --git a/src/pairs/sim/simulation.py b/src/pairs/sim/simulation.py index ba8e8f79f7be9f3052f7439f6566bd406aa196a5..5aa9c4ca42bfb9c8936a92bfce2d0c13bd963a67 100644 --- a/src/pairs/sim/simulation.py +++ b/src/pairs/sim/simulation.py @@ -63,6 +63,7 @@ class Simulation: self.expr_id = 0 self.iter_id = 0 self.vtk_file = None + self._target = None self.nparticles = self.nlocal + self.nghost self.properties.add_capacity(self.particle_capacity) @@ -214,7 +215,12 @@ class Simulation: def vtk_output(self, filename): self.vtk_file = filename + def target(self, target): + self._target = target + def generate(self): + assert self._target is not None, "Target not specified!" + timestep = Timestep(self, self.ntimesteps, [ (EnforcePBC(self, self.pbc), 20), (SetupPBC(self, self.pbc), UpdatePBC(self, self.pbc), 20), @@ -242,7 +248,8 @@ class Simulation: ]) program = Module(self, name='main', block=Block.merge_blocks(decls, body)) - add_copies = AddDeviceCopies(program) + if self._target.is_gpu(): + add_copies = AddDeviceCopies(program) # Transformations lower_everything(program) @@ -254,7 +261,9 @@ class Simulation: set_used_bin_ops(program) modularize(program) merge_adjacent_blocks(program) - add_copies.mutate() + + if self._target.is_gpu(): + add_copies.mutate() # For this part on, all bin ops are generated without usage verification self.check_decl_usage = False