Skip to content

API

API Documentation of OptiFloat.jl

# OptiFloat.optifloatFunction.
julia
optifloat(expr::Expr, T::Type, batchsize::Int, steps::Int, interval_compatible::Bool)

The main function of OptiFloat.jl. Optimizes a floating point expression and returns a result object which contains an improved expression.

Example

julia
julia> using OptiFloat
julia> expr = :(sqrt(x+1) - sqrt(x))
julia> optifloat(expr; T=Float16, batchsize=100, steps=1, interval_compatible=false)

For more convenient usage, see @optifloat

Arguments

  • expr::Expr: The floating point expression that should be optimized.

  • T::Type{<:AbstractFloat}: Floating point type that the expression should be evaluated on.

  • batchsize::Int: Number of samples that OptiFloat will compute errors for. The samples are computed via logsample such that only samples which do not cause DomainErrors/overflows are used.

  • steps::Int: Number of times search_candidates! is called.

  • interval_compatible::Bool: If false the improved function only accepts normal numbers otherwise the result.improved will be an expression that accepts Intervals. In the latter case you have to load IntervalArithmetic, otherwise eval(result.improved) will fail.

Returns

An OptiFloatResult.

source


# OptiFloat.@optifloatMacro.
julia
@optifloat expr kws...

The main macro of OptiFloat.jl. Optimizes a floating point expression and returns a result object which contains an improved expression. Accepts the same keyword arguments as optifloat.

Examples

julia
julia> using OptiFloat
julia> g = @optifloat sqrt(x+1) - sqrt(x) T=Float16 batchsize=1000
julia> g(Float16(3730))
Float16(0.00819)

source


Internals

# OptiFloat.REWRITE_THEORYConstant.

Rules that are used to generate new candidate expressions.

source


# OptiFloat.SIMPLIFY_THEORYConstant.

Rules that are used to simplify generated candidate expressions. This is a subset of REWRITE_THEORY.

source


# OptiFloat.CandidateType.
julia
Candidate{E<:Expression,A<:AbstractArray,F<:Function}

Holds an original and a candidate expression, as well as their biterror and an indication if the candidate has already been used in search_candidates! (used: ✓, unused: ⊚). Should only be constructed via one of the two constructors below:

  • Candidate(candidate::Expr, original::Expr, points::AbstractMatrix)

  • Candidate(candidate::Expr, points::AbstractMatrix) (if candidate and original are the same)

source


# OptiFloat.OptiFloatResultType.
julia
OptiFloatResult{O<:Expr,I<:Expr,C<:Candidate,R<:PiecewiseRegime}

Fields

  • original::Expr: The original expression that was attempted to be optimized.

  • improved::Expr: The (potentially) improved expression.

  • original_candidate::Candidate: The Candidate of the original expression. This struct includes the error on the sampled points.

  • improved_regimes::PiecewiseRegime: The struct that was used to generate improved.

source


# DynamicExpressions.ParseModule.parse_expressionMethod.
julia
parse_expression(T::Type{<:AbstractFloat}, expr::Expr; kws...)

Parse a Julia Expr to a dynamic Expression that can be used to efficiently compute local_biterrors. Convenience overload of DynamicExpressions.parse_expression.

source


# OptiFloat.biterrorMethod.
julia
biterror(x::T, y::T) where {T}

The biterror is defined as the logarithm of the ULP-distance (unit at the last place) biterror(x,y) = log2(ulpdistance(x,y)). For the example above to approximately 11 bits:

julia
julia> using OptiFloat
julia> f(x) = sqrt(x+1) - sqrt(x)
julia> g(x) = 1 / (sqrt(x+1) + sqrt(x))
julia> x = Float16(3730)
julia> OptiFloat.biterror(f(x), g(x))

source


# OptiFloat.infer_regimesMethod.
julia
infer_regimes(candidates::Vector{<:Candidate}, feature::Int, points::Matrix{T}; kws...)

Pick as few candidates and their corresponding good regimes to define a PiecewiseRegime that represents an expression that performs well on all points.

source


# OptiFloat.local_biterrorFunction.
julia
function local_biterror(
    tree::Node{T},
    ops::AbstractOperatorEnum,
    X::AbstractMatrix{T};
    accum=default_accum
) where {T}

Compute the error of the root node in tree. The children are evaluated exactly, such that only the error of the root node is returned. local_biterrors computes the local error for all nodes in the tree.

source


# OptiFloat.local_biterrorMethod.
julia
function local_biterror(
    tree::Node{T},
    ops::AbstractOperatorEnum,
    X::AbstractMatrix{T};
    accum=default_accum
) where {T}

Compute the error per node/operation in tree. For each node, the children are evaluated exactly, such that only the error of the current node is returned. local_biterrors computes the error for all nodes in the tree.

source


# OptiFloat.local_biterrorsFunction.
julia
local_biterrors(expr::Expression, x::AbstractArray)

Recursively call local_biterror on all nodes in expr and return the local error for each node.

source


# OptiFloat.logsampleMethod.
julia
logsample(expr::Expression, batchsize::Int; eval_exact=true)

Sample valid inputs to expr. If eval_exact=false expr is evaluated with BigFloats so samples might be generated that cause overflow in the original floating point type of expr.

source


# OptiFloat.optifloatMethod.
julia
optifloat(expr::Expr, T::Type, batchsize::Int, steps::Int, interval_compatible::Bool)

The main function of OptiFloat.jl. Optimizes a floating point expression and returns a result object which contains an improved expression.

Example

julia
julia> using OptiFloat
julia> expr = :(sqrt(x+1) - sqrt(x))
julia> optifloat(expr; T=Float16, batchsize=100, steps=1, interval_compatible=false)

For more convenient usage, see @optifloat

Arguments

  • expr::Expr: The floating point expression that should be optimized.

  • T::Type{<:AbstractFloat}: Floating point type that the expression should be evaluated on.

  • batchsize::Int: Number of samples that OptiFloat will compute errors for. The samples are computed via logsample such that only samples which do not cause DomainErrors/overflows are used.

  • steps::Int: Number of times search_candidates! is called.

  • interval_compatible::Bool: If false the improved function only accepts normal numbers otherwise the result.improved will be an expression that accepts Intervals. In the latter case you have to load IntervalArithmetic, otherwise eval(result.improved) will fail.

Returns

An OptiFloatResult.

source


# OptiFloat.print_reportMethod.
julia
print_report(io::IO, original::Candidate, rs::PiecewiseRegime; rm_ansi=false)

Output a report including a copy-pasteable function representing the PiecewiseRegime.

source


# OptiFloat.sample_finiteMethod.

Generate samples from samplefn that yield finite results when called with testfn:

julia
x = samplefn(T, inputsize)
y = testfn(x)  <-- add to samples if isfinite(y)

source


# OptiFloat.search_candidates!Method.
julia
search_candidates!(candidates::Vector{<:Candidate}, points::Matrix{T}) where {T}

Try to find better candidate expressions than the ones that are already present in candidates. The first unused candidate will be attempted to improve and new candidate expression are added to candidates. Once a candidate is picked, this function goes through the following steps:

  1. Given an initial expression candidate, compute the local_biterror of every subexpression and pick the subexpression sub_expr with the worst error for further analysis.

  2. Recursively rewrite the sub_expr based on a set of rewrite rules, generating a number of new candidates.

  3. Simplify the candidates via equality saturation (implemented in Metatheory.jl)

  4. Compute error of new candidates and add every candidate that performs better on any of the points to the existing list.

source


# OptiFloat.@optifloatMacro.
julia
@optifloat expr kws...

The main macro of OptiFloat.jl. Optimizes a floating point expression and returns a result object which contains an improved expression. Accepts the same keyword arguments as optifloat.

Examples

julia
julia> using OptiFloat
julia> g = @optifloat sqrt(x+1) - sqrt(x) T=Float16 batchsize=1000
julia> g(Float16(3730))
Float16(0.00819)

source