def _track_cpu_gpu(self, list_of_maps, bunch1, bunch2, nturns=1): ''' Tracks both bunches through the list of maps (once GPU, once CPU) and checks whether it yields the same result. Returns True/False. Make sure bunch1, bunch2 are two identical objects (not one!) Change the actual implementation of the GPU interface/strategy here ''' # GPU with GPU(bunch1) as device: for n in range(nturns): for m in list_of_maps: m.track(bunch1) # CPU for n in range(nturns): for m in list_of_maps: m.track(bunch2) #print bunch1.x #print bunch2.x # make sure the beam is sorted according to it's id to be able to compare them # this is required since argsort for the slices is not unique # (particles within slices can be permuted, gpu/cpu might be different!) bunch1.sort_for('id') bunch2.sort_for('id') for att in bunch1.coords_n_momenta | set(['id']): if not np.allclose(getattr(bunch1, att), getattr(bunch2, att), rtol=1.e-5, atol=1.e-8): return False return True
def test_wakefield_platesresonator(self): ''' Track through a ParallelPlatesResonator wakefield ''' Dx = np.append(np.linspace(0., 20., self.nsegments), [0]) # add some dispersion/alpha lhc = m.LHC(n_segments=self.nsegments, machine_configuration='450GeV', app_x=1e-9, app_y=2e-9, app_xy=-1.5e-11, chromaticity_on=False, amplitude_detuning_on=True, alpha_x=1.2 * np.ones(self.nsegments), D_x=Dx, printer=SilentPrinter()) self.n_macroparticles = 200000 bunch_cpu = self.create_lhc_bunch(lhc) #self.create_gaussian_bunch() bunch_gpu = self.create_lhc_bunch(lhc) #self.create_gaussian_bunch() n_slices = 50 #5 frequency = 8e8 #1e9 R_shunt = 23e3 # [Ohm] Q = 1. unif_bin_slicer = UniformBinSlicer(n_slices=n_slices, n_sigma_z=1) #res = CircularResonator(R_shunt=R_shunt, frequency=frequency, Q=Q) res = ParallelPlatesResonator(R_shunt=R_shunt, frequency=frequency, Q=Q, printer=SilentPrinter()) wake_field = WakeField(unif_bin_slicer, res) self.assertTrue( self._track_cpu_gpu([wake_field], bunch_cpu, bunch_gpu), 'Tracking Wakefield CircularResonator CPU/GPU differs')
def test_PSB_linear(self): psb = m.PSB(n_segments=self.nsegments, printer=SilentPrinter(), machine_configuration='160MeV', longitudinal_focusing='linear') bunch_cpu = self.create_all1_bunch() bunch_gpu = self.create_all1_bunch() one_turn_map = psb.one_turn_map self.assertTrue( self._track_cpu_gpu(one_turn_map, bunch_cpu, bunch_gpu), 'Tracking through SPS Q26 injection one turn map CPU/GPU differs.')
def test_wakefield_wakefile(self): ''' Track an LHC bunch and a LHC wakefield ''' wakefile = 'autoruntests/wake_table.dat' #'./wakeforhdtl_PyZbase_Allthemachine_450GeV_B1_LHC_inj_450GeV_B1.dat' Qp_x, Qp_y = 1., 1. Q_s = 0.0049 n_macroparticles = 10 intensity = 1e11 longitudinal_focusing = 'linear' machine = m.LHC(n_segments=1, machine_configuration='450GeV', longitudinal_focusing=longitudinal_focusing, Qp_x=[Qp_x], Qp_y=[Qp_y], Q_s=Q_s, beta_x=[65.9756], beta_y=[71.5255], printer=SilentPrinter()) epsn_x = 3.5e-6 epsn_y = 3.5e-6 sigma_z = 1.56e-9 * c / 4. np.random.seed(0) bunch_cpu = machine.generate_6D_Gaussian_bunch(n_macroparticles, intensity, epsn_x, epsn_y, sigma_z=sigma_z) np.random.seed(0) bunch_gpu = machine.generate_6D_Gaussian_bunch(n_macroparticles, intensity, epsn_x, epsn_y, sigma_z=sigma_z) n_slices_wakefields = 55 n_sigma_z_wakefields = 3 slicer_for_wakefields_cpu = UniformBinSlicer( n_slices_wakefields, n_sigma_z=n_sigma_z_wakefields) wake_components = [ 'time', 'dipole_x', 'dipole_y', 'no_quadrupole_x', 'no_quadrupole_y', 'no_dipole_xy', 'no_dipole_yx' ] wake_table_cpu = WakeTable(wakefile, wake_components, printer=SilentPrinter()) wake_field_cpu = WakeField(slicer_for_wakefields_cpu, wake_table_cpu) # also checked for 100 turns! self.assertTrue( self._track_cpu_gpu([wake_field_cpu], bunch_cpu, bunch_gpu, nturns=2), 'Tracking through WakeField(waketable) differs')
def test_SPS_nonlinear(self): sps = m.SPS(n_segments=self.nsegments, printer=SilentPrinter(), machine_configuration='Q26-injection', Qp_x=2, Qp_y=-2.2, charge=e, mass=m_p) bunch_cpu = self.create_all1_bunch() bunch_gpu = self.create_all1_bunch() one_turn_map = sps.one_turn_map self.assertTrue( self._track_cpu_gpu(one_turn_map, bunch_cpu, bunch_gpu), 'Tracking through SPS Q26 injection one turn map CPU/GPU differs.')
def test_transverse_track_with_Adetuning(self): ''' Track the GPU bunch through a TransverseMap with amplitude detuning Check if results on CPU and GPU are the same Special test since it requires the PyCERNmachines module to create the LHC beam. Skip if not available. ''' # Use a real bunch (not all set to 1), otherwise the Action/detuning # gets too big and the numbers blow up. Dx = np.append(np.linspace(0., 20., self.nsegments), [0]) # add some dispersion/alpha lhc = m.LHC(n_segments=self.nsegments, machine_configuration='450GeV', app_x=1e-9, app_y=2e-9, app_xy=-1.5e-11, chromaticity_on=False, amplitude_detuning_on=True, alpha_x=1.2 * np.ones(self.nsegments), D_x=Dx, printer=SilentPrinter()) # create pure Python map, PyCERNmachine uses Cython. adetuner = AmplitudeDetuning(lhc.app_x, lhc.app_y, lhc.app_xy) transverse_map = tt.TransverseMap(lhc.s, lhc.alpha_x, lhc.beta_x, lhc.D_x, lhc.alpha_y, lhc.beta_y, lhc.D_y, lhc.Q_x, lhc.Q_y, adetuner, printer=SilentPrinter()) bunch_cpu = self.create_lhc_bunch(lhc) bunch_gpu = self.create_lhc_bunch(lhc) self.assertTrue( self._track_cpu_gpu(transverse_map, bunch_cpu, bunch_gpu), 'Transverse tracking with Adetuning CPU/GPU differs')