1+ #!/usr/bin/env python3
12import argparse
23from pathlib import Path
34
45import numpy as np
56import cupy as cp
67
8+
79# ─────────────────────────────────────────────────────────────────────────────
810# 1) Core update functions (no plotting/animation)
911# ─────────────────────────────────────────────────────────────────────────────
@@ -59,29 +61,32 @@ def life_step_naive(grid: np.ndarray) -> np.ndarray:
5961# 2) Simulation functions (no animation)
6062# ─────────────────────────────────────────────────────────────────────────────
6163
62- def simulate_life_numpy (N : int , timesteps : int , p_alive : float = 0.2 ):
63- grid = np .random .choice ([0 , 1 ], size = (N , N ), p = [1 - p_alive , p_alive ])
64- history = []
64+ def simulate_life_numpy (N : int , timesteps : int , p_alive : float = 0.2 , record_history : bool = False ):
65+ grid = np .random .choice ([0 , 1 ], size = (N , N ), p = [1 - p_alive , p_alive ])
66+ history = [] if record_history else None
6567 for _ in range (timesteps ):
66- history .append (grid .copy ())
68+ if record_history :
69+ history .append (grid .copy ())
6770 grid = life_step_numpy (grid )
6871 return history
6972
7073
71- def simulate_life_cupy (N : int , timesteps : int , p_alive : float = 0.2 ):
74+ def simulate_life_cupy (N : int , timesteps : int , p_alive : float = 0.2 , record_history : bool = False ):
7275 grid_gpu = (cp .random .random ((N , N )) < p_alive ).astype (cp .int32 )
73- history = []
76+ history = [] if record_history else None
7477 for _ in range (timesteps ):
75- history .append (cp .asnumpy (grid_gpu ))
78+ if record_history :
79+ history .append (cp .asnumpy (grid_gpu ))
7680 grid_gpu = life_step_gpu (grid_gpu )
7781 return history
7882
7983
80- def simulate_life_naive (N : int , timesteps : int , p_alive : float = 0.2 ):
81- grid = np .random .choice ([0 , 1 ], size = (N , N ), p = [1 - p_alive , p_alive ])
82- history = []
84+ def simulate_life_naive (N : int , timesteps : int , p_alive : float = 0.2 , record_history : bool = False ):
85+ grid = np .random .choice ([0 , 1 ], size = (N , N ), p = [1 - p_alive , p_alive ])
86+ history = [] if record_history else None
8387 for _ in range (timesteps ):
84- history .append (grid .copy ())
88+ if record_history :
89+ history .append (grid .copy ())
8590 grid = life_step_naive (grid )
8691 return history
8792
@@ -113,7 +118,7 @@ def _update(idx):
113118
114119
115120# ─────────────────────────────────────────────────────────────────────────────
116- # 4) CLI entry-points (only --size and --timesteps)
121+ # 4) CLI entry-points (only --size, --timesteps, --save-gif )
117122# ─────────────────────────────────────────────────────────────────────────────
118123
119124def run_life_numpy ():
@@ -124,16 +129,18 @@ def run_life_numpy():
124129 args = p .parse_args ()
125130
126131 print (f"[NumPy] Args received: { args } " )
127-
128- history = simulate_life_numpy (args .size , args .timesteps )
132+ record = args . save_gif and args . size <= 100
133+ history = simulate_life_numpy (args .size , args .timesteps , record_history = record )
129134
130135 if args .save_gif :
131- output = Path ("game_of_life_cpu.gif" )
132- animate_life (history , output )
133- print (f"Saved CPU GIF to { output } " )
136+ if record :
137+ output = Path ("game_of_life_cpu.gif" )
138+ animate_life (history , output )
139+ print (f"Saved CPU GIF to { output } " )
140+ else :
141+ print ("[NumPy] Problem size > 100: cannot save history or create GIF." )
134142 else :
135- print ("[NumPy] GIF creation skipped." )
136-
143+ print ("[NumPy] GIF creation skipped; history not saved." )
137144
138145
139146def run_life_cupy ():
@@ -144,16 +151,18 @@ def run_life_cupy():
144151 args = p .parse_args ()
145152
146153 print (f"[CuPy] Args received: { args } " )
147-
148- history = simulate_life_cupy (args .size , args .timesteps )
154+ record = args . save_gif and args . size <= 100
155+ history = simulate_life_cupy (args .size , args .timesteps , record_history = record )
149156
150157 if args .save_gif :
151- output = Path ("game_of_life_gpu.gif" )
152- animate_life (history , output )
153- print (f"Saved GPU GIF to { output } " )
158+ if record :
159+ output = Path ("game_of_life_gpu.gif" )
160+ animate_life (history , output )
161+ print (f"Saved GPU GIF to { output } " )
162+ else :
163+ print ("[CuPy] Problem size > 100: cannot save history or create GIF." )
154164 else :
155- print ("[CuPy] GIF creation skipped." )
156-
165+ print ("[CuPy] GIF creation skipped; history not saved." )
157166
158167
159168def run_life_naive ():
@@ -163,14 +172,16 @@ def run_life_naive():
163172 p .add_argument ("--save-gif" , action = "store_true" , help = "Save GIF animation" )
164173 args = p .parse_args ()
165174
166- print (f"[Naive] Args received: { args } " )
167-
168- history = simulate_life_naive (args .size , args .timesteps )
175+ print (f"[Naive] Args received: { args } " )
176+ record = args . save_gif and args . size <= 100
177+ history = simulate_life_naive (args .size , args .timesteps , record_history = record )
169178
170179 if args .save_gif :
171- output = Path ("game_of_life_naive.gif" )
172- animate_life (history , output )
173- print (f"Saved Naive GIF to { output } " )
180+ if record :
181+ output = Path ("game_of_life_naive.gif" )
182+ animate_life (history , output )
183+ print (f"Saved Naive GIF to { output } " )
184+ else :
185+ print ("[Naive] Problem size > 100: cannot save history or create GIF." )
174186 else :
175- print ("[Naive] GIF creation skipped." )
176-
187+ print ("[Naive] GIF creation skipped; history not saved." )
0 commit comments