Skip to content

Commit

Permalink
[Utilities] fix stackoverflow in operate(+,...) with many arguments (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
odow authored Sep 21, 2023
1 parent 89a1cf5 commit 9893e0b
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 3 deletions.
16 changes: 13 additions & 3 deletions src/Utilities/operate.jl
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,12 @@ end
### 1c: operate(+, T, args...)

function operate(::typeof(+), ::Type{T}, f, g, h, args...) where {T<:Number}
return operate!(+, T, operate(+, T, f, g), h, args...)
ret = operate(+, T, f, g)
ret = operate!(+, T, ret, h)
for a in args
ret = operate!(+, T, ret, a)
end
return ret
end

### 2a: operate(::typeof(-), ::Type{T}, ::F)
Expand Down Expand Up @@ -1167,8 +1172,13 @@ end

### 1c: operate!(+, T, args...)

function operate!(op::typeof(+), ::Type{T}, f, g, h, args...) where {T<:Number}
return operate!(+, T, operate!(op, T, f, g), h, args...)
function operate!(::typeof(+), ::Type{T}, f, g, h, args...) where {T<:Number}
ret = operate!(+, T, f, g)
ret = operate!(+, T, ret, h)
for a in args
ret = operate!(+, T, ret, a)
end
return ret
end

### 2a: operate!(::typeof(-), ::Type{T}, ::F)
Expand Down
14 changes: 14 additions & 0 deletions test/Utilities/test_operate!.jl
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,20 @@ function test_operate_1c()
return
end

function test_operate_1c_many_arguments()
x = [i + i * MOI.VariableIndex(i) for i in 1:1_000]
y = MOI.Utilities.operate(+, Int, x...)
f = MOI.ScalarAffineFunction(
[MOI.ScalarAffineTerm(i, MOI.VariableIndex(i)) for i in 1:1_000],
sum(i for i in 1:1_000),
)
@test (y, f)
z = zero(MOI.ScalarAffineFunction{Int})
z = MOI.Utilities.operate!(+, Int, z, x...)
@test (z, f)
return
end

function test_operate_2a()
T = Int
for (f, g) in (
Expand Down

0 comments on commit 9893e0b

Please sign in to comment.