def trackDelay(self, turn): if self.delay['delayed']: modturn = turn % self.delay['dcr'] if modturn < self.delay['init'] - 1: # Not need to do anything, just wait and collect stats pass elif modturn == self.delay['init'] - 1: # Last turn of the init interval, update the time values tconst = timing.get( ['serial:'], exclude_lst=['serial:sync', 'serial:intraSync']) tcomp = timing.get(['comp:']) # tcomm = timing.get(['comm:']) self.delay['tconst'] = ( tconst - self.delay['tconst']) / self.delay['init'] / 1000 self.delay['tcomp'] = ( tcomp - self.delay['tcomp']) / self.delay['init'] / 1000 assert self.delay['tconst'] >= 0 and self.delay['tcomp'] >= 0 # self.delay['tcomm'] = ( # tcomm - self.delay['tcomm']) / self.delay['init'] / 1000 else: # Here I need to apply some delay # I update the active_percent and then apply the delay if modturn < self.delay['incr']: self.delay['active%'] += self.delay['incr%'] elif modturn < self.delay['top']: pass elif modturn < self.delay['dcr']: self.delay['active%'] -= self.delay['dcr%'] # self.logger.critical('[{}]: tconst:{}, tcomp:{}, tcomm:{}'.format( # self.rank, tconst, tcomp, tcomm)) sleep = self.delay['active%'] * self.delay['tconst'] if sleep > 0.: with timing.timed_region('serial:artificial') as tr: time.sleep(sleep) # sleep = self.delay['active%']*self.delay['tcomm'] # if sleep > 0.: # with timing.timed_region('comm:artificial') as tr: # time.sleep(sleep) sleep = self.delay['active%'] * self.delay['tcomp'] if sleep > 0.: with timing.timed_region('comp:artificial') as tr: time.sleep(sleep) if modturn == self.delay['dcr'] - 1: # this should bring the added delay back to zero assert np.isclose(self.delay['active%'], 0) self.delay['tconst'] = timing.get( ['serial:'], exclude_lst=['serial:sync', 'serial:intraSync']) # self.delay['tcomm'] = timing.get(['comm:']) self.delay['tcomp'] = timing.get(['comp:'])
def pre_track(self): """ Gpu Equivalent for pre_track """ turn = self.counter[0] if self.phi_noise is not None: with timing.timed_region('serial:pretrack_phirf'): if self.noiseFB is not None: first_kernel_tracker(self.rf_params.dev_phi_rf, self.noiseFB.x, self.dev_phi_noise, self.rf_params.dev_phi_rf.shape[0], turn, slice=slice(0, self.rf_params.n_rf)) else: first_kernel_tracker(self.rf_params.dev_phi_rf, 1.0, self.rf_params.dev_phi_noise, self.rf_params.dev_phi_rf.shape[0], turn, slice=slice(0, self.rf_params.n_rf)) # self.phi_rf[:, turn] += \ # self.phi_noise[:, turn] # Add phase modulation directly to the cavity RF phase if self.phi_modulation is not None: with timing.timed_region('serial:pretrack_phimodulation'): second_kernel_tracker(self.dev_phi_rf, self.dev_phi_modulation[0], self.dev_phi_modulation[1], self.dev_phi_rf.shape[0], turn) # Determine phase loop correction on RF phase and frequency if self.beamFB is not None and turn >= self.beamFB.delay: self.beamFB.track() counter = turn + 1 tracker_fb_track_kernel(self.rf_params.dev_omega_rf, self.rf_params.dev_harmonic, self.rf_params.dev_dphi_rf, self.rf_params.dev_omega_rf_d, self.rf_params.dev_phi_rf, np.int32(self.rf_params.n_turns + 1), np.int32(counter), np.int32(self.rf_params.n_rf), block=(32, 1, 1), grid=(1, 1, 1)) self.rf_params.dphi_rf_obj.invalidate_cpu() self.rf_params.phi_rf_obj.invalidate_cpu() if self.periodicity: RuntimeError('periodicity feature is not supported in GPU.') else: if self.rf_params.empty is False: if self.interpolation: self.rf_voltage_calculation()
def pre_track(self): """Tracking method for the section. Applies first the kick, then the drift. Calls also RF/beam feedbacks if applicable. Updates the counter of the corresponding RFStation class and the energy-related variables of the Beam class. """ # Add phase noise directly to the cavity RF phase turn = self.counter[0] # Add phase noise directly to the cavity RF phase if self.phi_noise is not None: with timing.timed_region('serial:pretrack_phirf'): if self.noiseFB is not None: self.phi_rf[:, turn] += \ self.noiseFB.x * self.phi_noise[:, turn] else: self.phi_rf[:, turn] += \ self.phi_noise[:, turn] # Add phase modulation directly to the cavity RF phase if self.phi_modulation is not None: with timing.timed_region('serial:pretrack_phimodulation'): self.phi_rf[:, turn] += \ self.phi_modulation[0][:, turn] self.omega_rf[:, turn] += \ self.phi_modulation[1][:, turn] # Determine phase loop correction on RF phase and frequency if self.beamFB is not None and turn >= self.beamFB.delay: self.beamFB.track() # Update the RF phase of all systems for the next turn # Accumulated phase offset due to beam phase loop or frequency offset # self.rf_params.dphi_rf += 2.*np.pi*self.rf_params.harmonic[:,turn+1]* \ # (self.rf_params.omega_rf[:,turn+1] - # self.rf_params.omega_rf_d[:,turn+1]) / \ # self.rf_params.omega_rf_d[:,turn+1] # Total phase offset # self.rf_params.phi_rf[:,turn+1] += self.rf_params.dphi_rf if self.periodicity: pass else: if self.rf_params.empty is False: if self.interpolation: self.rf_voltage_calculation()
def induced_voltage_1turn(self, beam_spectrum_dict={}): """ Method to calculate the induced voltage at the current turn. DFTs are used for calculations in time and frequency domain (see classes below) """ # if induced_voltage_1turn.last_turn < self.RFParams.counter[0]: # induced_voltage_1turn.last_turn = self.RFParams.counter[0] # print('Inside induced_voltage_1turn') if self.n_fft not in beam_spectrum_dict: # print('Before calling beam_spectrum_generation') self.profile.beam_spectrum_generation(self.n_fft) beam_spectrum_dict[self.n_fft] = self.profile.beam_spectrum # print('After beam spectrum') beam_spectrum = beam_spectrum_dict[self.n_fft] with timing.timed_region('serial:indVolt1Turn'): with mpiprof.traced_region('serial:indVolt1Turn'): induced_voltage = - (self.beam.Particle.charge * e * self.beam.ratio * bm.irfft(self.total_impedance.astype(dtype=bm.precision.complex_t, order='C', copy=False) * beam_spectrum)) self.induced_voltage = induced_voltage[:self.n_induced_voltage].astype( dtype=bm.precision.real_t, order='C', copy=False)
def induced_voltage_sum_packed(self): """ Method to sum all the induced voltages in one single array. """ # self.profile.beam_spectrum_dict = {} # for obj in self.induced_voltage_list: # if isinstance(obj, (InducedVoltageTime, InducedVoltageFreq)) and \ # (obj.n_fft not in self.profile.beam_spectrum_dict): # self.profile.beam_spectrum_generation(obj.n_fft) # Assuming the same n_fft for all, we take only the first one self.induced_voltage_list[0].profile.beam_spectrum_generation( self.induced_voltage_list[0].n_fft) beam_spectrum = self.induced_voltage_list[0].profile.beam_spectrum with timing.timed_region('serial:ind_volt_sum_packed'): with mpiprof.traced_region('serial:ind_volt_sum_packed'): self.induced_voltage = [] min_idx = self.profile.n_slices for obj in self.induced_voltage_list: self.induced_voltage.append( bm.mul(obj.total_impedance, beam_spectrum)) min_idx = min(obj.n_induced_voltage, min_idx) self.induced_voltage = bm.irfft_packed( self.induced_voltage.astype(dtype=bm.precision.real_t, order='C', copy=False))[:, :min_idx] self.induced_voltage = -self.beam.Particle.charge * \ e * self.beam.ratio * self.induced_voltage self.induced_voltage = np.sum(self.induced_voltage, axis=0)
def reduce_histo(self): from ..utils.mpi_config import worker with timing.timed_region('serial:conversion'): with mpiprof.traced_region('serial:conversion'): self.n_macroparticles = self.n_macroparticles.astype(np.uint32, order='C') worker.allreduce(self.n_macroparticles, dtype=np.uint32, operator='custom_sum') with timing.timed_region('serial:conversion'): with mpiprof.traced_region('serial:conversion'): self.n_macroparticles = self.n_macroparticles.astype( dtype=bm.precision.real_t, order='C', copy=False)
def track_only(self): """ Gpu Equivalent for track_only """ turn = self.counter[0] if self.periodicity: pass else: if self.rf_params.empty is False: if self.interpolation: with timing.timed_region('comp:LIKick'): self.dev_total_voltage = get_gpuarray( (self.dev_rf_voltage.size, bm.precision.real_t, id(self), "dtv")) if self.totalInducedVoltage is not None: add_kernel( self.dev_total_voltage, self.dev_rf_voltage, self.totalInducedVoltage.dev_induced_voltage) else: self.dev_total_voltage = self.dev_rf_voltage bm.linear_interp_kick( self.beam.dev_dt, self.beam.dev_dE, self.dev_total_voltage, self.profile.dev_bin_centers, self.beam.Particle.charge, self.acceleration_kick[turn], ) self.beam.dE_obj.invalidate_cpu() # bm.LIKick_n_drift(dev_voltage=self.dev_total_voltage, # dev_bin_centers=self.profile.dev_bin_centers, # charge=self.beam.Particle.charge, # acceleration_kick=self.acceleration_kick[turn], # T0=self.t_rev[turn + 1], # length_ratio=self.length_ratio, # eta0=self.eta_0[turn + 1], # beta=self.rf_params.beta[turn+1], # energy=self.rf_params.energy[turn+1], # beam=self.beam) else: self.kick(turn) self.drift(turn + 1) # Updating the beam synchronous momentum etc. self.beam.beta = self.rf_params.beta[turn + 1] self.beam.gamma = self.rf_params.gamma[turn + 1] self.beam.energy = self.rf_params.energy[turn + 1] self.beam.momentum = self.rf_params.momentum[turn + 1] # Increment by one the turn counter self.counter[0] += 1
def reduce_histo(self, dtype=np.uint32): if not bm.mpiMode(): raise RuntimeError( 'ERROR: Cannot use this routine unless in MPI Mode') from ..utils.mpi_config import worker if self.Beam.is_splitted: worker.sync() with timing.timed_region('serial:conversion'): # with mpiprof.traced_region('serial:conversion'): self.n_macroparticles = self.n_macroparticles.astype( np.uint32, order='C') worker.allreduce(self.n_macroparticles, dtype=np.uint32, operator='custom_sum') with timing.timed_region('serial:conversion'): # with mpiprof.traced_region('serial:conversion'): self.n_macroparticles = self.n_macroparticles.astype(dtype=bm.precision.real_t, order='C', copy=False)
def track(self): """ Track method to apply the induced voltage kick on the beam. """ self.induced_voltage_sum() with timing.timed_region('comp:LIKick'): bm.linear_interp_kick(dt=self.beam.dt, dE=self.beam.dE, voltage=self.induced_voltage, bin_centers=self.profile.bin_centers, charge=self.beam.Particle.charge, acceleration_kick=0.)
def PSB(self): ''' Phase and radial loops for PSB. See documentation on-line for details. ''' # Average phase error while frequency is updated counter = self.rf_station.counter[0] self.beam_phase() self.phase_difference() self.dphi_sum += self.dphi with timing.timed_region('serial:PSBBeamFB'): # Phase and radial loop active on certain turns if counter == self.on_time[ self.PL_counter] and counter >= self.delay: # Phase loop self.dphi_av = self.dphi_sum / ( self.on_time[self.PL_counter] - self.on_time[self.PL_counter - 1]) if self.RFnoise != None: self.dphi_av += self.RFnoise.dphi[counter] self.domega_PL = 0.99803799*self.domega_PL \ + self.gain[counter]*(0.99901903*self.dphi_av - 0.99901003*self.dphi_av_prev) self.dphi_av_prev = self.dphi_av self.dphi_sum = 0. # Radial loop self.dR_over_R = ( self.rf_station.omega_rf[0, counter] - self.rf_station.omega_rf_d[0, counter]) / ( self.rf_station.omega_rf_d[0, counter] * (1. / (self.ring.alpha_0[0, counter] * self.rf_station.gamma[counter]**2) - 1.)) self.domega_RL = self.domega_RL + self.gain2[0][counter] * ( self.dR_over_R - self.dR_over_R_prev ) + self.gain2[1][counter] * self.dR_over_R self.dR_over_R_prev = self.dR_over_R # Counter to pick the next time step when the PL & RL will be active self.PL_counter += 1 # Apply frequency correction self.domega_rf = -self.domega_PL - self.domega_RL
def induced_voltage_1turn(self, beam_spectrum_dict={}): """ GPU implementation of induced_voltage_1turn """ if self.n_fft not in beam_spectrum_dict: self.profile.beam_spectrum_generation(self.n_fft) beam_spectrum_dict[self.n_fft] = self.profile.dev_beam_spectrum beam_spectrum = beam_spectrum_dict[self.n_fft] with timing.timed_region('serial:indVolt1Turn'): inp = get_gpuarray((beam_spectrum.size, bm.precision.complex_t, id(self), 'inp')) complex_mul(self.dev_total_impedance, beam_spectrum, inp) my_res = bm.irfft(inp, caller_id=id(self)) self.dev_induced_voltage = get_gpuarray( (self.n_induced_voltage, bm.precision.real_t, id(self), 'iv')) gpu_mul(self.dev_induced_voltage, my_res, bm.precision.real_t(-self.beam.Particle.charge * e * self.beam.ratio), slice=slice(0, self.n_induced_voltage))
def induced_voltage_1turn(self, beam_spectrum_dict={}): """ Method to calculate the induced voltage at the current turn. DFTs are used for calculations in time and frequency domain (see classes below) """ if self.n_fft not in beam_spectrum_dict: self.profile.beam_spectrum_generation(self.n_fft) beam_spectrum_dict[self.n_fft] = self.profile.dev_beam_spectrum beam_spectrum = beam_spectrum_dict[self.n_fft] with timing.timed_region('serial:indVolt1Turn'): inp = get_gpuarray( (beam_spectrum.size, bm.precision.complex_t, id(self), 'inp')) complex_mul(self.dev_total_impedance, beam_spectrum, inp) my_res = bm.irfft(inp, caller_id=id(self)) self.dev_induced_voltage = get_gpuarray( (self.n_induced_voltage, bm.precision.real_t, id(self), 'iv')) gpu_mul(self.dev_induced_voltage, my_res, bm.precision.real_t(-self.beam.Particle.charge * e * self.beam.ratio), slice=slice(0, self.n_induced_voltage))
def track_only(self): """Tracking method for the section. Applies first the kick, then the drift. Calls also RF/beam feedbacks if applicable. Updates the counter of the corresponding RFStation class and the energy-related variables of the Beam class. """ turn = self.counter[0] if self.periodicity: # Distinguish the particles inside the frame from the particles on # the right-hand side of the frame. self.indices_right_outside = \ np.where(self.beam.dt > self.t_rev[turn + 1])[0] self.indices_inside_frame = \ np.where(self.beam.dt < self.t_rev[turn + 1])[0] if len(self.indices_right_outside) > 0: # Change reference of all the particles on the right of the # current frame; these particles skip one kick and drift self.beam.dt[self.indices_right_outside] -= \ self.t_rev[turn + 1] # Synchronize the bunch with the particles that are on the # RHS of the current frame applying kick and drift to the # bunch # After that all the particles are in the new updated frame self.insiders_dt = np.ascontiguousarray( self.beam.dt[self.indices_inside_frame]) self.insiders_dE = np.ascontiguousarray( self.beam.dE[self.indices_inside_frame]) self.kick(self.insiders_dt, self.insiders_dE, turn) self.drift(self.insiders_dt, self.insiders_dE, turn + 1) self.beam.dt[self.indices_inside_frame] = self.insiders_dt self.beam.dE[self.indices_inside_frame] = self.insiders_dE # Check all the particles on the left of the just updated # frame and apply a second kick and drift to them with the # previous wave after having changed reference. self.indices_left_outside = np.where(self.beam.dt < 0)[0] else: self.kick(self.beam.dt, self.beam.dE, turn) self.drift(self.beam.dt, self.beam.dE, turn + 1) # Check all the particles on the left of the just updated # frame and apply a second kick and drift to them with the # previous wave after having changed reference. self.indices_left_outside = np.where(self.beam.dt < 0)[0] if len(self.indices_left_outside) > 0: left_outsiders_dt = np.ascontiguousarray( self.beam.dt[self.indices_left_outside]) left_outsiders_dE = np.ascontiguousarray( self.beam.dE[self.indices_left_outside]) left_outsiders_dt += self.t_rev[turn + 1] self.kick(left_outsiders_dt, left_outsiders_dE, turn) self.drift(left_outsiders_dt, left_outsiders_dE, turn + 1) self.beam.dt[self.indices_left_outside] = left_outsiders_dt self.beam.dE[self.indices_left_outside] = left_outsiders_dE else: if self.rf_params.empty is False: if self.interpolation: if self.totalInducedVoltage is not None: self.total_voltage = self.rf_voltage \ + self.totalInducedVoltage.induced_voltage else: self.total_voltage = self.rf_voltage with timing.timed_region('comp:LIKick'): # with mpiprof.traced_region('comp:LIKick'): bm.linear_interp_kick( dt=self.beam.dt, dE=self.beam.dE, voltage=self.total_voltage, bin_centers=self.profile.bin_centers, charge=self.beam.Particle.charge, acceleration_kick=self.acceleration_kick[turn]) else: self.kick(self.beam.dt, self.beam.dE, turn) self.drift(self.beam.dt, self.beam.dE, turn + 1) # Updating the beam synchronous momentum etc. self.beam.beta = self.rf_params.beta[turn + 1] self.beam.gamma = self.rf_params.gamma[turn + 1] self.beam.energy = self.rf_params.energy[turn + 1] self.beam.momentum = self.rf_params.momentum[turn + 1] # Increment by one the turn counter self.counter[0] += 1
n_turns = args.repetitions size = args.size block = args.block n_threads = args.threads os.environ['OMP_NUM_THREADS'] = str(n_threads) np.random.seed(0) A = np.random.randn(size) B = np.random.randn(size) papiprof = PAPIProf(metrics=['IPC', 'L2_MISS_RATE', 'LLC_MISS_RATE']) papiprof.list_events() papiprof.list_metrics() papiprof.list_avail_metrics() with timing.timed_region('tiled_vector_add') as tr: papiprof.start_counters() for s in range(0, size, block): e = min(s + block, size) for i in range(n_turns): result = A[s:e] + B[s:e] papiprof.stop_counters() with timing.timed_region('vector_add') as tr: papiprof.start_counters() # for s in range(0, size, block): # e = min(s+block, size) for i in range(n_turns): result = A + B papiprof.stop_counters()
if __name__ == "__main__": timing.mode = 'timing' args = parser.parse_args() n_turns = args.repetitions n_signal = args.size n_kernel = args.size n_threads = args.threads os.environ['OMP_NUM_THREADS'] = str(n_threads) np.random.seed(0) signal = np.random.randn(n_signal) kernel = np.random.randn(n_kernel) result = np.zeros(len(signal) + len(kernel) - 1) papiprof = PAPIProf(metrics=['IPC', 'L2_MISS_RATE', 'L3_MISS_RATE']) papiprof.list_events() papiprof.list_metrics() papiprof.list_avail_metrics() with timing.timed_region('fftconvolution') as tr: papiprof.start_counters() for i in range(n_turns): result = fftconvolve(signal, kernel) papiprof.stop_counters() timing.report() papiprof.report_counters() papiprof.report_metrics()
profile=profile, rf=rf_params, Nbunches=n_bunches) worker.sync() timing.reset() start_t = tm.time() t0 = tm.process_time() for turn in range(n_iterations): full_ring.track() profile.track() totalInduced.track() with timing.timed_region('serial:updateImp'): update_impedance(map_, turn) # for t in tIt: if turn < len(intensity_ramp): my_beam.intensity = intensity_ramp[turn] my_beam.ratio = my_beam.intensity/my_beam.n_macroparticles # else: # break if (args['monitor'] > 0) and (turn % args['monitor'] == 0): my_beam.statistics() my_beam.gather_statistics() profile.fwhm() if worker.isMaster:
worker.sendrecv(inducedVoltage.induced_voltage, tracker.rf_voltage) else: if (turn < 8 * int(FBtime)): longCavityImpedanceReduction.track() shortCavityImpedanceReduction.track() if (approx == 0) or (approx == 2): inducedVoltage.induced_voltage_sum() elif (approx == 1) and (turn % n_turns_reduce == 0): inducedVoltage.induced_voltage_sum() tracker.pre_track() tracker.track_only() if SPS_PHASELOOP is True: if turn % PL_save_turns == 0 and turn > 0: with timing.timed_region('serial:binShift') as tr: # present beam position beamPosFromPhase = (phaseLoop.phi_beam - rf_station.phi_rf[0, turn])\ / rf_station.omega_rf[0, turn] + t_batch_begin # how much to shift the bin_centers delta = beamPosPrev - beamPosFromPhase beamPosPrev = beamPosFromPhase profile.bin_centers -= delta profile.cut_left -= delta profile.cut_right -= delta profile.edges -= delta # shift time_offset of phase loop as well, so that it starts at correct # bin_center corresponding to time_offset
import numpy as np from pyprof import timing timing.mode = 'timing' # other modes available: 'disabled', 'line_profiler' num = 10000 # Method 1, wrapper @timing.timeit(filename='example.py', classname='', key='foo') def foo(num): return np.sum(np.random.randn(num)) a = foo(num) # ---------- # Method 2, code region with timing.timed_region('code_region') as tr: a = np.sum(np.random.randn(num)) # ---------- # Method 3, start/ stop timing.start_timing('start_stop') b = np.sum(np.random.randn(num)) timing.stop_timing() # ---------- timing.report()