@@ -225,12 +225,17 @@ def rectilinear_chunks(draw: st.DrawFn, *, shape: tuple[int, ...]) -> list[list[
225225
226226 For each dimension, generate a list of chunk sizes that sum to the dimension size.
227227 Sometimes uses uniform chunks, sometimes uses variable-sized chunks.
228+
229+ Note: We limit the number of chunks to max 20 per dimension to avoid performance issues
230+ in property tests. With higher dimensions, the total chunk count grows multiplicatively.
228231 """
229232 chunk_shapes : list [list [int ]] = []
230233 for size in shape :
231234 assert size > 0
232235 if size > 1 :
233- nchunks = draw (st .integers (min_value = 1 , max_value = size - 1 ))
236+ # Limit max chunks to 20 to avoid performance issues with large chunk grids
237+ max_chunks = min (size - 1 , 20 )
238+ nchunks = draw (st .integers (min_value = 1 , max_value = max_chunks ))
234239 dividers = sorted (
235240 draw (
236241 st .lists (
@@ -486,10 +491,8 @@ def basic_indices(
486491 allow_ellipsis = allow_ellipsis ,
487492 ).filter (
488493 lambda idxr : (
489- not (
490- is_negative_slice (idxr )
491- or (isinstance (idxr , tuple ) and any (is_negative_slice (idx ) for idx in idxr ))
492- )
494+ not is_negative_slice (idxr )
495+ and not (isinstance (idxr , tuple ) and any (is_negative_slice (idx ) for idx in idxr )) # type: ignore[redundant-expr]
493496 )
494497 )
495498 if math .prod (shape ) >= 3 :
@@ -575,27 +578,26 @@ def chunk_paths(draw: st.DrawFn, ndim: int, numblocks: tuple[int, ...], subset:
575578@st .composite
576579def complex_chunk_grids (draw : st .DrawFn ) -> RectilinearChunkGrid :
577580 ndim = draw (st .integers (min_value = 1 , max_value = 3 ))
578- nchunks = draw ( st . integers ( min_value = 10 , max_value = 100 ))
579- # Don't require unique chunk sizes - rectilinear grids can have repeated sizes
580- dim_chunks = st .lists (
581- st . integers ( min_value = 1 , max_value = 10 ), min_size = nchunks , max_size = nchunks
582- )
581+ # Limit to 5-10 chunks per dimension with small sizes to keep array size reasonable
582+ # Max array size: 10 chunks * 5 size = 50 elements per dim, 50^3 = 125k elements max
583+ nchunks = draw ( st .integers ( min_value = 5 , max_value = 10 ))
584+ # Keep chunk sizes small (1-5) to avoid creating huge arrays
585+ dim_chunks = st . lists ( st . integers ( min_value = 1 , max_value = 5 ), min_size = nchunks , max_size = nchunks )
583586 if draw (st .booleans ()):
584587 event ("using RectilinearChunkGrid" )
585588 chunk_shapes = draw (st .lists (dim_chunks , min_size = ndim , max_size = ndim ))
586589 return RectilinearChunkGrid (chunk_shapes = chunk_shapes )
587590
588591 else :
589592 event ("using RectilinearChunkGrid (run length encoded)" )
590- # For RLE, we need to carefully control the total expanded chunks
591- # to avoid creating arrays that are too large
592- # Use a small number of RLE entries with small repeat counts
593- num_rle_entries = draw (st .integers (min_value = 5 , max_value = 20 ))
593+ # For RLE, keep total expanded chunks small: 3-5 entries * 2-3 repeats = 6-15 chunks
594+ # With chunk sizes 1-5, max array size: 15 * 5 = 75 per dim, 75^3 = 421k elements max
595+ num_rle_entries = draw (st .integers (min_value = 3 , max_value = 5 ))
594596 chunk_shapes_rle = [
595597 [
596598 [
597- draw (st .integers (min_value = 1 , max_value = 10 )), # chunk size
598- draw (st .integers (min_value = 1 , max_value = 3 )), # repeat count
599+ draw (st .integers (min_value = 1 , max_value = 5 )), # chunk size
600+ draw (st .integers (min_value = 2 , max_value = 3 )), # repeat count
599601 ]
600602 for _ in range (num_rle_entries )
601603 ]
@@ -613,7 +615,7 @@ def complex_chunked_arrays(
613615 draw : st .DrawFn ,
614616 * ,
615617 stores : st .SearchStrategy [StoreLike ] = stores ,
616- ) -> Array :
618+ ) -> AnyArray :
617619 store = draw (stores , label = "store" )
618620 chunks = draw (complex_chunk_grids (), label = "chunk grid" )
619621 assert isinstance (chunks , RectilinearChunkGrid )
0 commit comments