



'''simple docstring'''




# We ignore warnings about stepping the scheduler since we step it ourselves during gradient accumulation

import warnings

from .state import AcceleratorState, GradientState


warnings.filterwarnings('''ignore''', category=UserWarning, module='''torch.optim.lr_scheduler''')







class 	_lowerCAmelCase							:


	def __init__(self       ,      lowercase       ,      lowercase       ,      lowercase = True       ,      lowercase = False							):
				A_	:						Optional[Any]	=     scheduler
				A_	:						Any	=     optimizers if isinstance(lowercase       ,      (list, tuple)							) else [optimizers]
				A_	:						Tuple	=     split_batches
				A_	:						Tuple	=     step_with_optimizer
				A_	:						Optional[int]	=     GradientState()


	def     _a	(self       ,      *lowercase       ,      **lowercase							):
				if not self.step_with_optimizer:
							# No link between scheduler and optimizer -> just step
							self.scheduler.step(*lowercase       ,      **lowercase							)
							return

				# Otherwise, first make sure the optimizer was stepped.
				if not self.gradient_state.sync_gradients:
							if self.gradient_state.adjust_scheduler:
										self.scheduler._step_count += 1
							return

				for opt in self.optimizers:
							if opt.step_was_skipped:
										return
				if self.split_batches:
							# Split batches -> the training dataloader batch size is not changed so one step per training step
							self.scheduler.step(*lowercase       ,      **lowercase							)
				else:
							# Otherwise the training dataloader batch size was multiplied by `num_processes`, so we need to do
							# num_processes steps per training step
							A_	:						Optional[Any]	=     AcceleratorState().num_processes
							for _ in range(lowercase							):
										# Special case when using OneCycle and `drop_last` was not used
										if hasattr(self.scheduler       ,      """total_steps"""							):
													if self.scheduler._step_count <= self.scheduler.total_steps:
																self.scheduler.step(*lowercase       ,      **lowercase							)
										else:
													self.scheduler.step(*lowercase       ,      **lowercase							)


	def     _a	(self							):
				return self.scheduler.get_last_lr()


	def     _a	(self							):
				return self.scheduler.state_dict()


	def     _a	(self       ,      lowercase							):
				self.scheduler.load_state_dict(lowercase							)


	def     _a	(self							):
				return self.scheduler.get_lr()


	def     _a	(self       ,      *lowercase       ,      **lowercase							):
				return self.scheduler.print_lr(*lowercase       ,      **lowercase							)




'''simple docstring'''




from math import pow



def 	a			( lowerCamelCase__						,      lowerCamelCase__						,      lowerCamelCase__						,      lowerCamelCase__						,      lowerCamelCase__						,      ):
			'''simple docstring'''





			if current_sum == needed_sum:
						# If the sum of the powers is equal to needed_sum, then we have a solution.
						solutions_count += 1
						return current_sum, solutions_count

			A_	:						Optional[int]	=     int(pow(lowerCamelCase__						,      lowerCamelCase__    )    )
			if current_sum + i_to_n <= needed_sum:
						# If the sum of the powers is less than needed_sum, then continue adding powers.
						current_sum += i_to_n
						A_,    A_	:						int	=     backtrack(
						    lowerCamelCase__						,      lowerCamelCase__						,      current_number + 1						,      lowerCamelCase__						,      lowerCamelCase__    )
						current_sum -= i_to_n
			if i_to_n < needed_sum:
						# If the power of i is less than needed_sum, then try with the next power.
						A_,    A_	:						int	=     backtrack(
						    lowerCamelCase__						,      lowerCamelCase__						,      current_number + 1						,      lowerCamelCase__						,      lowerCamelCase__    )
			return current_sum, solutions_count



def 	a			( lowerCamelCase__						,      lowerCamelCase__    ):
			'''simple docstring'''





			if not (1 <= needed_sum <= 10_00 and 2 <= power <= 10):
						raise ValueError(
						    """Invalid input\n"""
						    """needed_sum must be between 1 and 1000, power between 2 and 10."""    )

			return backtrack(lowerCamelCase__						,      lowerCamelCase__						,      1						,      0						,      0    )[1]  # Return the solutions_count


if __name__ == "__main__":
						import doctest

						doctest.testmod()