From 47c9b7d7929bd3ea85f6fea7b970579f2bf51c20 Mon Sep 17 00:00:00 2001 From: Leandro Martinez Date: Mon, 9 Feb 2026 17:24:01 -0300 Subject: [PATCH 1/3] implement size for RoundRobin() --- CHANGELOG.md | 3 ++- src/internals.jl | 27 ++++++++++++++++++++++++--- test/runtests.jl | 30 +++++++++++++----------------- 3 files changed, 39 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 82d0458..61945ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,9 @@ ChunkSplitters.jl Changelog =========================== -Version 3.1.3-DEV +Version 3.2.0-DEV ------------- +- ![FEATURE][badge-feature] Implement `size` option for `split=RoundRobin()`. - ![INFO][badge-info] Improve documentation of multithreading by adding `index_chunks` examples. Version 3.1.2 diff --git a/src/internals.jl b/src/internals.jl index 8af37c4..71e97c0 100644 --- a/src/internals.jl +++ b/src/internals.jl @@ -94,7 +94,13 @@ Base.firstindex(::AbstractChunks) = 1 Base.lastindex(c::AbstractChunks) = length(c) Base.length(c::AbstractChunks{T,FixedCount,S}) where {T,S} = c.n -Base.length(c::AbstractChunks{T,FixedSize,S}) where {T,S} = cld(length(c.collection), max(1, c.size)) +Base.length(c::AbstractChunks{T,FixedSize,Consecutive}) where {T} = cld(length(c.collection), max(1, c.size)) +function Base.length(c::AbstractChunks{T,FixedSize,RoundRobin}) where {T} + l = length(c.collection) + l == 0 && return 0 + s = min(l, max(1, c.size)) + return fld(l, s) + rem(l, s) +end Base.getindex(c::IndexChunks{T,C,S}, i::Int) where {T,C,S} = getchunkindices(c, i) Base.getindex(c::ViewChunks{T,C,S}, i::Int) where {T,C,S} = @view(c.collection[getchunkindices(c, i)]) @@ -158,7 +164,11 @@ function getchunkindices(c::AbstractChunks{T,C,S}, ichunk::Integer) where {T,C,S size = c.size l = length(c.collection) size = min(l, size) # handle size>length(c.collection) - n = cld(l, size) + if S == Consecutive + n = cld(l, size) + else # RoundRobin + n = fld(l, size) + rem(l, size) + end end else n = 0 @@ -192,7 +202,18 @@ function _getchunkindices(::Type{FixedSize}, ::Type{Consecutive}, collection, ic end function _getchunkindices(::Type{FixedSize}, ::Type{RoundRobin}, collection, ichunk; size, kwargs...) - throw(ArgumentError("split=RoundRobin() not yet supported in combination with size keyword argument.")) + l = length(collection) + fi = firstindex(collection) + step = fld(l, size) + if ichunk <= step + first = fi + ichunk - 1 + last = first + (size - 1) * step + return first:step:last + else + k = ichunk - step + pos = fi + step * size + k - 1 + return pos:step:pos + end end end # module diff --git a/test/runtests.jl b/test/runtests.jl index 26ac322..8cb0233 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -5,28 +5,14 @@ using TestItems: @testitem, @testsnippet @testsnippet Testing begin function test_index_chunks(; array_length, n, size, split, result) - if n === nothing - d, r = divrem(array_length, size) - nchunks = d + (r != 0) - elseif size === nothing - nchunks = n - else - throw(ArgumentError("both n and size === nothing")) - end c = index_chunks(rand(Int, array_length); n=n, size=size, split=split) + nchunks = length(c) ranges = [c[i] for i in 1:nchunks] all(ranges .== result) end function sum_parallel(x, n, size, split, which) - if n === nothing - d, r = divrem(length(x), size) - nchunks = d + (r != 0) - elseif size === nothing - nchunks = n - else - throw(ArgumentError("both n and size === nothing")) - end + nchunks = length(index_chunks(x; n=n, size=size, split=split)) s = zeros(eltype(x), nchunks) if which == "index_chunks" Threads.@threads for (ichunk, range) in enumerate(index_chunks(x; n=n, size=size, split=split)) @@ -128,7 +114,17 @@ end @test collect.(index_chunks(x; n=3, split=RoundRobin())) == [[-1, 2, 5], [0, 3], [1, 4]] # FixedSize - @test_throws ArgumentError collect(index_chunks(1:10; size=2, split=RoundRobin())) # not supported (yet?) + @test collect(index_chunks([1,2,3,4,5,6,7]; size=2, split=RoundRobin())) == [[1,4], [2,5], [3,6], [7]] + @test collect(chunks(['a','b','c','d','e','f','g']; size=2, split=RoundRobin())) == [['a','d'], ['b','e'], ['c','f'], ['g']] + @test collect(index_chunks(1:7; size=2, split=RoundRobin())) == [1:3:4, 2:3:5, 3:3:6, 7:3:7] + @test collect(index_chunks(1:6; size=2, split=RoundRobin())) == [1:3:4, 2:3:5, 3:3:6] + @test collect(index_chunks(1:10; size=3, split=RoundRobin())) == [1:3:7, 2:3:8, 3:3:9, 10:3:10] + @test collect(index_chunks(1:9; size=3, split=RoundRobin())) == [1:3:7, 2:3:8, 3:3:9] + x = OffsetArray(1:7, -1:5) + @test collect(index_chunks(x; size=2, split=RoundRobin())) == [-1:3:2, 0:3:3, 1:3:4, 5:3:5] + @test test_sum(; array_length=7, n=nothing, size=2, split=RoundRobin()) + @test test_sum(; array_length=15, n=nothing, size=4, split=RoundRobin()) + @test test_sum(; array_length=117, n=nothing, size=10, split=RoundRobin()) end @testitem "check input argument errors" begin From f61e489a04e932ceb4d3ae85c53cb1dca45b57dc Mon Sep 17 00:00:00 2001 From: Leandro Martinez Date: Mon, 9 Feb 2026 17:45:48 -0300 Subject: [PATCH 2/3] drop support for Julia 1.6-1.9 --- .github/workflows/ci.yml | 4 ---- CHANGELOG.md | 1 + Project.toml | 4 ++-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 72a64b0..9b716e8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,7 +12,6 @@ jobs: fail-fast: false matrix: version: - - '1.6' # remove at some point in the future, if needed. - 'lts' # currently 1.10 - '1' # latest stable 1.x release - 'pre' @@ -20,9 +19,6 @@ jobs: - ubuntu-latest - macOS-latest - windows-latest - exclude: - - version: '1.6' - os: macOS-latest steps: - uses: actions/checkout@v4 - uses: julia-actions/setup-julia@v2 diff --git a/CHANGELOG.md b/CHANGELOG.md index 61945ff..66da894 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ Version 3.2.0-DEV ------------- - ![FEATURE][badge-feature] Implement `size` option for `split=RoundRobin()`. - ![INFO][badge-info] Improve documentation of multithreading by adding `index_chunks` examples. +- ![INFO][badge-info] Drop support for Julia 1.6 (Requires 1.10.0 now). Version 3.1.2 ------------- diff --git a/Project.toml b/Project.toml index 1184395..0ce211a 100644 --- a/Project.toml +++ b/Project.toml @@ -10,10 +10,10 @@ Aqua = "0.8.5" BenchmarkTools = "1" Documenter = "1" OffsetArrays = "1" -Test = "1.6" +Test = "1.10" TestItemRunner = "1" TestItems = "1" -julia = "1.6" +julia = "1.10" [extras] Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595" From a05045dc602a1e65f923f7a2262fa43412791d6f Mon Sep 17 00:00:00 2001 From: Leandro Martinez Date: Mon, 9 Feb 2026 17:46:55 -0300 Subject: [PATCH 3/3] downgrade on 1.10 --- .github/workflows/downgrade.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/downgrade.yml b/.github/workflows/downgrade.yml index 8b0b9ff..d1dc30a 100644 --- a/.github/workflows/downgrade.yml +++ b/.github/workflows/downgrade.yml @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - version: ['1.6'] + version: ['1.10'] steps: - uses: actions/checkout@v4 - uses: julia-actions/setup-julia@v2