11# SourceCodeMcCormick.jl
22
33This package is an experimental approach to use source-code transformation to apply McCormick relaxations
4- to symbolic functions for use in deterministic global optimization. While packages like ` McCormick.jl `
4+ to symbolic functions for use in deterministic global optimization. While packages like ` McCormick.jl ` [ 1 ]
55take set-valued McCormick objects and utilize McCormick relaxation rules to overload standard math operations,
6- ` SourceCodeMcCormick.jl ` aims to interpret symbolic expressions, apply McCormick transformations, and
7- return a new symbolic expression representing those relaxations. This functionality is designed to be
8- used for both algebraic and dynamic systems.
6+ ` SourceCodeMcCormick.jl ` (SCMC) aims to interpret symbolic expressions, apply generalized McCormick rules,
7+ create source code that computes the McCormick relaxations and natural interval extension of the input,
8+ and compile the source code into functions that return pointwise values of the natural interval extension
9+ and convex/concave relaxations. This functionality is designed to be used for both algebraic and dynamic
10+ (in development) systems.
911
1012## Algebraic Systems
1113
12- For a given algebraic equation or system of equations, ` SourceCodeMcCormick ` is designed to provide
13- symbolic transformations that represent the lower/upper bounds and convex/concave relaxations of the
14- provided equation(s). Most notably, ` SourceCodeMcCormick ` uses this symbolic transformation to
15- generate "evaluation functions" which, for a given expression, return the lower/upper bounds and
16- convex/concave relaxations of an expression. E.g.:
14+ For a given algebraic equation or system of equations, ` SCMC ` is designed to provide symbolic transformations
15+ that represent the lower/upper bounds and convex/concave relaxations of the provided equation(s). Most notably,
16+ ` SCMC ` uses this symbolic transformation to generate "evaluation functions" which, for a given expression,
17+ return the natural interval extension and convex/concave relaxations of an expression. E.g.:
1718
1819```
1920using SourceCodeMcCormick, Symbolics
2021
21- @variables x
22- to_compute = x*(15+x)^2
23- x_lo_eval, x_hi_eval, x_cv_eval, x_cc_eval , order = all_evaluators(to_compute )
22+ @variables x, y
23+ expr = exp(x/y) - (x*y^2)/(y+1)
24+ expr_lo_eval, expr_hi_eval, expr_cv_eval, expr_cc_eval , order = all_evaluators(expr )
2425```
2526
2627Here, the outputs marked ` _eval ` are the evaluation functions for the lower bound (` lo ` ), upper
27- bound (` hi ` ), convex underestimator (` cv ` ), and concave overestimator (` cc ` ) of the ` to_compute `
28- expression. The inputs to each of these functions are described by the ` order ` vector, which
29- in this case is ` [x_cc, x_cv, x_hi, x_lo] ` .
30-
31- There are several important benefits of using these functions. First, they are fast. Normally,
32- applying McCormick relaxations takes some time as the relaxation depends on the provided bounds
33- and relaxation values of the input(s), but also on the form of the expression itself. Packages
34- like ` McCormick.jl ` use control flow to quickly determine the form of the relaxations and provide
35- McCormick objects of the results, but because the forms of the expressions are not known * a priori* ,
36- this control flow takes time to process. In contrast, ` SourceCodeMcCormick ` effectively hard-codes
37- the relaxations for a specific, pre-defined function into the evaluation functions, making it
38- inherently faster. For example:
28+ bound (` hi ` ), convex underestimator (` cv ` ), and concave overestimator (` cc ` ) of the symbolic
29+ expression given by ` expr ` . The inputs to each of these functions are described by the ` order `
30+ vector, which in this case is ` [x_cc, x_cv, x_hi, x_lo, y_cc, y_cv, y_hi, y_lo] ` , representing
31+ the concave/convex relaxations and interval bounds of the variables ` x ` and ` y ` . E.g., if being
32+ used in a branch-and-bound (B&B) scheme, the interval bounds for each variable will be the lower and
33+ upper bounds of the B&B node for that variable, and the convex/concave relaxations will take the
34+ value where the relaxation of the original expression is desired.
35+
36+ One benefit of using a source code transformation approach such as this over a multiple dispatch
37+ approach like ` McCormick.jl ` is speed. When McCormick relaxations of functions are evaluated using
38+ ` McCormick.jl ` , there is overhead associated with finding the correct functions to call for each
39+ overloaded math operation. The functions generated by ` SCMC ` , however, eliminate this overhead by
40+ creating static functions with the correct McCormick rules already applied. While the ` McCormick.jl `
41+ approach is flexible in quickly evaluating any new expression you provide, in the ` SCMC ` approach,
42+ one expression is selected up front, and relaxations and interval extension values are calculated
43+ for that expression quickly. For example:
3944
4045```
4146using BenchmarkTools, McCormick
4247
43- xMC = MC{1, NS}(2.5, Interval(-1.0, 4.0), 1)
48+ xMC = MC{2, NS}(2.5, Interval(-1.0, 4.0), 1)
49+ yMC = MC{2, NS}(1.5, Interval(0.5, 3.0), 2)
4450
45- @btime xMC*(15+ xMC)^2
46- # 228.381 ns (15 allocations: 384 bytes)
51+ @btime exp( xMC/yMC) - (xMC*yMC^2)/(yMC+1)
52+ # 497.382 ns (7 allocations: 560 bytes)
4753
48- @btime x_cv_eval (2.5, 2.5, 4.0, -1.0)
49- # 30.382 ns (1 allocation: 16 bytes)
54+ @btime expr_cv_eval (2.5, 2.5, 4.0, -1.0, 1.5, 1.5, 3.0, 0.5 )
55+ # 184.964 ns (1 allocation: 16 bytes)
5056```
5157
52- This is not an * entirely* fair example because the operation with xMC is simultaneously calculating
53- lower/upper bounds, both relaxations, and (sub)gradients of the convex/concave relaxations, but the
54- ` SourceCodeMcCormick ` result is just under an order of magnitude faster. As the expression inceases
55- in complexity, this speedup becomes even more apparent.
58+ Note that this is not an entirely fair comparison because ` McCormick.jl ` , by using the ` MC ` type and
59+ multiple dispatch, simultaneously calculates all of the following: natural interval extensions,
60+ convex and concave relaxations, and corresponding subgradients.
5661
57- Second, these evaluation functions are compatible with ` CUDA.jl ` in that they are broadcastable
58- over ` CuArray ` s. Depending on the GPU, number of evaluations, and complexity of the function,
59- this can dramatically decrease the time to compute the numerical values of function bounds and
60- relaxations. E.g.:
62+ Another benefit of the ` SCMC ` approach is its compatibility with ` CUDA.jl ` [ 2 ] : ` SCMC ` functions are
63+ broadcastable over ` CuArray ` s. Depending on the GPU, number of evaluations, and complexity of the
64+ function, this can dramatically decrease the time to compute the numerical values of interval
65+ extensions and relaxations. E.g.:
6166
6267```
6368using CUDA
6469
6570# Using McCormick.jl
66- xMC_array = MC{1,NS}.(rand(10000), Interval.(zeros(10000), ones(10000)), ones(Int, 10000))
71+ xMC_array = MC{2,NS}.(rand(10000), Interval.(zeros(10000), ones(10000)), ones(Int, 10000))
72+ yMC_array = MC{2,NS}.(rand(10000), Interval.(zeros(10000), ones(10000)), ones(Int, 10000).*2)
6773
68- @btime xMC_array.*(15 .+ xMC_array).^2
69- # 1.616 ms (120012 allocations: 2.37 MiB )
74+ @btime @. exp(xMC_array/yMC_array) - ( xMC_array*yMC_array^2)/(yMC_array+1)
75+ # 2.365 ms (18 allocations: 703.81 KiB )
7076
7177
7278# Using SourceCodeMcCormick.jl, broadcast using CPU
@@ -75,33 +81,40 @@ xcv = copy(xcc)
7581xhi = ones(10000)
7682xlo = zeros(10000)
7783
78- @btime x_cv_eval.(xcc, xcv, xhi, xlo)
79- # 100.100 μs (4 allocations: 78.27 KiB)
84+ ycc = rand(10000)
85+ ycv = copy(xcv)
86+ yhi = ones(10000)
87+ ylo = zeros(10000)
8088
89+ @btime expr_cv_eval.(xcc, xcv, xhi, xlo, ycc, ycv, yhi, ylo);
90+ # 1.366 ms (20 allocations: 78.84 KiB)
8191
82- # Using SourceCodeMcCormick.jl and CUDA.jl, broadcast using GPU
83- xcc_GPU = cu(xcc)
84- xcv_GPU = cu(xcv)
85- xhi_GPU = cu(xhi)
86- xlo_GPU = cu(xlo)
8792
88- @btime x_cv_eval.(xcc_GPU, xcv_GPU, xhi_GPU, xlo_GPU)
89- # 6.575 μs (33 allocations: 2.34 KiB)
93+ # Using SourceCodeMcCormick.jl and CUDA.jl, broadcast using GPU
94+ xcc_GPU = CuArray(xcc)
95+ xcv_GPU = CuArray(xcv)
96+ xhi_GPU = CuArray(xhi)
97+ xlo_GPU = CuArray(xlo)
98+ ycc_GPU = CuArray(ycc)
99+ ycv_GPU = CuArray(ycv)
100+ yhi_GPU = CuArray(yhi)
101+ ylo_GPU = CuArray(ylo)
102+
103+ @btime CUDA.@sync expr_cv_eval.(xcc_GPU, xcv_GPU, xhi_GPU, xlo_GPU, ycc_GPU, ycv_GPU, yhi_GPU, ylo_GPU);
104+ # 29.800 μs (52 allocations: 3.88 KiB)
90105```
91106
92107
93108## Dynamic Systems
94109
95- For dynamic systems, ` SourceCodeMcCormick ` was built with a differential inequalities
96- approach in mind where the relaxations of derivatives are calculated in advance and
97- the resulting (larger) differential equation system, with explicit definitions of
98- the relaxations of derivatives, can be solved. For algebraic systems, the main
99- product of this package is the broadcastable evaluation functions. For dynamic
100- systems, this package follows the same idea as in algebraic systems but stops at
101- the symbolic representations of relaxations. This functionality is designed to work
102- with a ` ModelingToolkit ` -type ` ODESystem ` with factorable equations--` SourceCodeMcCormick `
103- will take such a system and return a new ` ODESystem ` with expanded equations to
104- provide interval extensions and (if desired) McCormick relaxations. E.g.:
110+ (In development) For dynamic systems, ` SCMC ` assumes a differential inequalities approach where the
111+ relaxations of derivatives are calculated in advance and the resulting (larger) differential equation
112+ system, with explicit definitions of the relaxations of derivatives, can be solved. For algebraic
113+ systems, the main product of this package is the broadcastable evaluation functions. For dynamic
114+ systems, this package follows the same idea as in algebraic systems but stops at the symbolic
115+ representations of relaxations. This functionality is designed to work with a ` ModelingToolkit ` -type
116+ ` ODESystem ` with factorable equations [ 3] --` SCMC ` will take such a system and return a new ` ODESystem `
117+ with expanded equations to provide interval extensions and (if desired) McCormick relaxations. E.g.:
105118
106119```
107120using SourceCodeMcCormick, ModelingToolkit
@@ -150,8 +163,35 @@ using `DiffEqGPU.jl`.
150163
151164## Limitations
152165
153- Currently, as proof-of-concept, ` SourceCodeMcCormick ` can only handle functions with
154- addition (+), subtraction (-), multiplication (\* ), division (/), powers of 2 (^2), natural base
155- exponentials (exp), and minimum/maximum (min/max) expressions. Future work will include
156- adding other operations found in ` McCormick.jl ` .
157-
166+ ` SCMC ` has several limitations, some of which are described here. Ongoing research effort seeks
167+ to address several of these.
168+ - SCMC does not calculate subgradients, which are used in the lower bounding routines of many
169+ global optimizers
170+ - Complicated expressions may cause significant compilation time. This can be manually avoided
171+ by combining results together in a user-defined function
172+ - ` SCMC ` is currently compatible with elementary arithmetic operations +, -, * , /, and the
173+ univariate intrinsic functions ^2 and exp. More diverse functions will be added in the future
174+ - Functions created with ` SCMC ` may only accept 32 CUDA arrays as inputs, so functions with more
175+ than 8 unique variables will need to be split/factored by the user to be accommodated
176+ - Due to the large number of floating point calculations required to calculate McCormick-based
177+ relaxations, it is highly recommended to use double-precision floating point numbers, including
178+ for operations on a GPU. Since most GPUs are designed for single-precision floating point operation,
179+ forcing double-precision will often result in a significant performance hit. GPUs designed for
180+ scientific computing, with a higher proportion of double-precision-capable cores, are recommended
181+ for optimal performance with ` SCMC ` .
182+ - Due to the high branching factor of McCormick-based relaxations and the possibility of warp
183+ divergence, there will likely be a performance gap between optimizations with variables covering
184+ positive-only domains and variables with mixed domains. Additionally, more complicated expressions
185+ where the structure of a McCormick relaxation changes more frequently with respect to the bounds
186+ on its domain will likely perform worse than problems where the structure of the relaxation is
187+ more consistent.
188+
189+ ## References
190+
191+ 1 . M.E. Wilhelm, R.X. Gottlieb, and M.D. Stuber, PSORLab/McCormick.jl (2020), URL
192+ https://github.com/PSORLab/McCormick.jl .
193+ 2 . T. Besard, C. Foket, and B. De Sutter, Effective extensible programming: Unleashing Julia
194+ on GPUs, IEEE Transactions on Parallel and Distributed Systems (2018).
195+ 3 . Y. Ma, S. Gowda, R. Anantharaman, C. Laughman, V. Shah, C. Rackauckas, ModelingToolkit:
196+ A composable graph transformation system for equation-based modeling. arXiv preprint
197+ arXiv:2103.05244, 2021. doi: 10.48550/ARXIV.2103.05244.
0 commit comments