

'''simple docstring'''






import torch

from diffusers import HeunDiscreteScheduler
from diffusers.utils import torch_device

from .test_schedulers import SchedulerCommonTest
class 	SCREAMING_SNAKE_CASE__			(				_UpperCAmelCase      ):
    _A			    =							(HeunDiscreteScheduler,)
    _A			    =							10




    def   __lowerCamelCase      (					self				,     **lowercase__			):






          """simple docstring"""






          SCREAMING_SNAKE_CASE_      :			List[Any]     =       {
              "num_train_timesteps": 1100,
              "beta_start": 0.0001,
              "beta_end": 0.02,
              "beta_schedule": "linear",
          }

          config.update(**lowercase__			)
          return config




    def   __lowerCamelCase      (					self			):






          """simple docstring"""






          for timesteps in [10, 50, 100, 1000]:
                self.check_over_configs(num_train_timesteps=lowercase__			)




    def   __lowerCamelCase      (					self			):






          """simple docstring"""






          for beta_start, beta_end in zip([0.00001, 0.0001, 0.001]				,     [0.0002, 0.002, 0.02]			):
                self.check_over_configs(beta_start=lowercase__				,     beta_end=lowercase__			)




    def   __lowerCamelCase      (					self			):






          """simple docstring"""






          for schedule in ["linear", "scaled_linear", "exp"]:
                self.check_over_configs(beta_schedule=lowercase__			)




    def   __lowerCamelCase      (					self			):






          """simple docstring"""






          for clip_sample_range in [1.0, 2.0, 3.0]:
                self.check_over_configs(clip_sample_range=lowercase__				,     clip_sample=lowercase__			)




    def   __lowerCamelCase      (					self			):






          """simple docstring"""






          for prediction_type in ["epsilon", "v_prediction", "sample"]:
                self.check_over_configs(prediction_type=lowercase__			)




    def   __lowerCamelCase      (					self			):






          """simple docstring"""






          SCREAMING_SNAKE_CASE_      :			Tuple     =       self.scheduler_classes[0]
          SCREAMING_SNAKE_CASE_      :			List[str]     =       self.get_scheduler_config()
          SCREAMING_SNAKE_CASE_      :			List[str]     =       scheduler_class(**lowercase__			)

          scheduler.set_timesteps(self.num_inference_steps			)

          SCREAMING_SNAKE_CASE_      :			int     =       self.dummy_model()
          SCREAMING_SNAKE_CASE_      :			Dict     =       self.dummy_sample_deter * scheduler.init_noise_sigma
          SCREAMING_SNAKE_CASE_      :			Optional[int]     =       sample.to(lowercase__			)

          for i, t in enumerate(scheduler.timesteps			):
                SCREAMING_SNAKE_CASE_      :			Optional[Any]     =       scheduler.scale_model_input(lowercase__				,     lowercase__			)

                SCREAMING_SNAKE_CASE_      :			Dict     =       model(lowercase__				,     lowercase__			)

                SCREAMING_SNAKE_CASE_      :			str     =       scheduler.step(lowercase__				,     lowercase__				,     lowercase__			)
                SCREAMING_SNAKE_CASE_      :			Dict     =       output.prev_sample

          SCREAMING_SNAKE_CASE_      :			List[Any]     =       torch.sum(torch.abs(lowercase__			)			)
          SCREAMING_SNAKE_CASE_      :			List[str]     =       torch.mean(torch.abs(lowercase__			)			)

          if torch_device in ["cpu", "mps"]:
                assert abs(result_sum.item() - 0.1233			) < 1e-2
                assert abs(result_mean.item() - 0.0002			) < 1e-3
          else:
                # CUDA
                assert abs(result_sum.item() - 0.1233			) < 1e-2
                assert abs(result_mean.item() - 0.0002			) < 1e-3




    def   __lowerCamelCase      (					self			):






          """simple docstring"""






          SCREAMING_SNAKE_CASE_      :			Optional[Any]     =       self.scheduler_classes[0]
          SCREAMING_SNAKE_CASE_      :			Optional[int]     =       self.get_scheduler_config(prediction_type="v_prediction"			)
          SCREAMING_SNAKE_CASE_      :			Any     =       scheduler_class(**lowercase__			)

          scheduler.set_timesteps(self.num_inference_steps			)

          SCREAMING_SNAKE_CASE_      :			Any     =       self.dummy_model()
          SCREAMING_SNAKE_CASE_      :			Union[str, Any]     =       self.dummy_sample_deter * scheduler.init_noise_sigma
          SCREAMING_SNAKE_CASE_      :			List[str]     =       sample.to(lowercase__			)

          for i, t in enumerate(scheduler.timesteps			):
                SCREAMING_SNAKE_CASE_      :			Tuple     =       scheduler.scale_model_input(lowercase__				,     lowercase__			)

                SCREAMING_SNAKE_CASE_      :			int     =       model(lowercase__				,     lowercase__			)

                SCREAMING_SNAKE_CASE_      :			Optional[Any]     =       scheduler.step(lowercase__				,     lowercase__				,     lowercase__			)
                SCREAMING_SNAKE_CASE_      :			Optional[int]     =       output.prev_sample

          SCREAMING_SNAKE_CASE_      :			Union[str, Any]     =       torch.sum(torch.abs(lowercase__			)			)
          SCREAMING_SNAKE_CASE_      :			int     =       torch.mean(torch.abs(lowercase__			)			)

          if torch_device in ["cpu", "mps"]:
                assert abs(result_sum.item() - 4.69_34e-07			) < 1e-2
                assert abs(result_mean.item() - 6.11_12e-10			) < 1e-3
          else:
                # CUDA
                assert abs(result_sum.item() - 4.6_93_42_86_50_17_09_72e-07			) < 1e-2
                assert abs(result_mean.item() - 0.0002			) < 1e-3




    def   __lowerCamelCase      (					self			):






          """simple docstring"""






          SCREAMING_SNAKE_CASE_      :			List[str]     =       self.scheduler_classes[0]
          SCREAMING_SNAKE_CASE_      :			Union[str, Any]     =       self.get_scheduler_config()
          SCREAMING_SNAKE_CASE_      :			List[Any]     =       scheduler_class(**lowercase__			)

          scheduler.set_timesteps(self.num_inference_steps				,     device=lowercase__			)

          SCREAMING_SNAKE_CASE_      :			Any     =       self.dummy_model()
          SCREAMING_SNAKE_CASE_      :			str     =       self.dummy_sample_deter.to(lowercase__			) * scheduler.init_noise_sigma

          for t in scheduler.timesteps:
                SCREAMING_SNAKE_CASE_      :			Optional[int]     =       scheduler.scale_model_input(lowercase__				,     lowercase__			)

                SCREAMING_SNAKE_CASE_      :			Dict     =       model(lowercase__				,     lowercase__			)

                SCREAMING_SNAKE_CASE_      :			Optional[Any]     =       scheduler.step(lowercase__				,     lowercase__				,     lowercase__			)
                SCREAMING_SNAKE_CASE_      :			List[Any]     =       output.prev_sample

          SCREAMING_SNAKE_CASE_      :			str     =       torch.sum(torch.abs(lowercase__			)			)
          SCREAMING_SNAKE_CASE_      :			List[Any]     =       torch.mean(torch.abs(lowercase__			)			)

          if str(lowercase__			).startswith("cpu"			):
                # The following sum varies between 148 and 156 on mps. Why?
                assert abs(result_sum.item() - 0.1233			) < 1e-2
                assert abs(result_mean.item() - 0.0002			) < 1e-3
          elif str(lowercase__			).startswith("mps"			):
                # Larger tolerance on mps
                assert abs(result_mean.item() - 0.0002			) < 1e-2
          else:
                # CUDA
                assert abs(result_sum.item() - 0.1233			) < 1e-2
                assert abs(result_mean.item() - 0.0002			) < 1e-3







    def   __lowerCamelCase      (					self			):






          """simple docstring"""






          SCREAMING_SNAKE_CASE_      :			Union[str, Any]     =       self.scheduler_classes[0]
          SCREAMING_SNAKE_CASE_      :			int     =       self.get_scheduler_config()
          SCREAMING_SNAKE_CASE_      :			Optional[int]     =       scheduler_class(**lowercase__				,     use_karras_sigmas=lowercase__			)

          scheduler.set_timesteps(self.num_inference_steps				,     device=lowercase__			)

          SCREAMING_SNAKE_CASE_      :			List[str]     =       self.dummy_model()
          SCREAMING_SNAKE_CASE_      :			Optional[int]     =       self.dummy_sample_deter.to(lowercase__			) * scheduler.init_noise_sigma
          SCREAMING_SNAKE_CASE_      :			Any     =       sample.to(lowercase__			)

          for t in scheduler.timesteps:
                SCREAMING_SNAKE_CASE_      :			Optional[int]     =       scheduler.scale_model_input(lowercase__				,     lowercase__			)

                SCREAMING_SNAKE_CASE_      :			List[str]     =       model(lowercase__				,     lowercase__			)

                SCREAMING_SNAKE_CASE_      :			Union[str, Any]     =       scheduler.step(lowercase__				,     lowercase__				,     lowercase__			)
                SCREAMING_SNAKE_CASE_      :			Tuple     =       output.prev_sample

          SCREAMING_SNAKE_CASE_      :			Any     =       torch.sum(torch.abs(lowercase__			)			)
          SCREAMING_SNAKE_CASE_      :			Union[str, Any]     =       torch.mean(torch.abs(lowercase__			)			)

          assert abs(result_sum.item() - 0.00015			) < 1e-2
          assert abs(result_mean.item() - 1.98_69_55_45_35_03_46_95e-07			) < 1e-2




'''simple docstring'''






from __future__ import annotations

from PIL import Image

# Define the first generation of cells
# fmt: off
snake_case_       =       [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]


def 					__lowerCamelCase			(      SCREAMING_SNAKE_CASE_     :	int    )							->   list[int]:
      """simple docstring"""

      return [int(SCREAMING_SNAKE_CASE_    ) for c in F"{ruleset:08}"[:8]]


def 					__lowerCamelCase			(      SCREAMING_SNAKE_CASE_     :	list[list[int]]  ,  SCREAMING_SNAKE_CASE_     :	list[int]  ,  SCREAMING_SNAKE_CASE_     :	int    )							->   list[int]:
      """simple docstring"""

      SCREAMING_SNAKE_CASE_      :			List[str]     =       len(cells[0]    )  # 31
      SCREAMING_SNAKE_CASE_      :			Optional[Any]     =       []
      for i in range(SCREAMING_SNAKE_CASE_    ):
            # Get the neighbors of each cell
            # Handle neighbours outside bounds by using 0 as their value
            SCREAMING_SNAKE_CASE_      :			Optional[Any]     =       0 if i == 0 else cells[time][i - 1]
            SCREAMING_SNAKE_CASE_      :			Tuple     =       0 if i == population - 1 else cells[time][i + 1]
            # Define a new cell and add it to the new generation
            SCREAMING_SNAKE_CASE_      :			Dict     =       7 - int(F"{left_neighbor}{cells[time][i]}{right_neighbor}"  ,  2    )
            next_generation.append(rule[situation]    )
      return next_generation


def 					__lowerCamelCase			(      SCREAMING_SNAKE_CASE_     :	list[list[int]]    )							->   Image.Image:
      """simple docstring"""

      SCREAMING_SNAKE_CASE_      :			List[Any]     =       Image.new("RGB"  ,  (len(cells[0]    ), len(SCREAMING_SNAKE_CASE_    ))    )
      SCREAMING_SNAKE_CASE_      :			Optional[int]     =       img.load()
      # Generates image
      for w in range(img.width    ):
            for h in range(img.height    ):
                  SCREAMING_SNAKE_CASE_      :			List[str]     =       2_5_5 - int(2_5_5 * cells[h][w]    )
                  SCREAMING_SNAKE_CASE_      :			str     =       (color, color, color)
      return img


if __name__ == "__main__":
      snake_case_       =       bin(int(input('Rule:\n').strip()))[2:]
      snake_case_       =       format_ruleset(int(rule_num))
      for time in range(1_6):
            CELLS.append(new_generation(CELLS, rule, time))
      snake_case_       =       generate_image(CELLS)
      # Uncomment to save the image
      # img.save(f"rule_{rule_num}.png")
      img.show()

