Public API

This page lists exported symbols of CTSolvers.Strategies.


From CTSolvers.Strategies

CTSolvers.Strategies

CTSolvers.StrategiesModule

Strategy management and registry for CTSolvers.

This module provides:

  • Abstract strategy contract and interface
  • Strategy registry for explicit dependency management
  • Strategy building and validation utilities
  • Metadata management for strategy families

The Strategies module depends on Options for option handling but provides higher-level strategy management capabilities.

AbstractStrategy

CTSolvers.Strategies.AbstractStrategyType
abstract type AbstractStrategy

Abstract base type for all strategies in the CTSolvers ecosystem.

Every concrete strategy must implement a two-level contract separating static type metadata from dynamic instance configuration.

Contract Overview

Type-Level Contract (Static Metadata)

Methods defined on the type that describe what the strategy can do:

  • id(::Type{<:MyStrategy})::Symbol - Unique identifier for routing and introspection
  • metadata(::Type{<:MyStrategy})::StrategyMetadata - Option specifications and validation rules

Why type-level? These methods enable:

  • Introspection without instantiation - Query capabilities without creating objects
  • Routing and dispatch - Select strategies by symbol for automated construction
  • Validation before construction - Verify compatibility before resource allocation

Instance-Level Contract (Configured State)

Methods defined on instances that provide the actual configuration:

  • options(strategy::MyStrategy)::StrategyOptions - Current option values with provenance tracking

Why instance-level? These methods enable:

  • Multiple configurations - Different instances with different settings
  • Provenance tracking - Know which options came from user vs defaults
  • Encapsulation - Configuration state belongs to the executing object

Implementation Requirements

Every concrete strategy must provide:

  1. Type definition with an options::StrategyOptions field (recommended)
  2. Type-level methods for id and metadata
  3. Constructor accepting keyword arguments (uses build_strategy_options)
  4. Instance-level access to configured options

Validation Modes

The strategy system supports two validation modes for option handling:

  • Strict Mode (default): Rejects unknown options with detailed error messages

    • Provides early error detection and safety
    • Suggests corrections for typos using Levenshtein distance
    • Ideal for development and production environments
  • Permissive Mode: Accepts unknown options with warnings

    • Allows backend-specific options without breaking changes
    • Maintains validation for known options (types, custom validators)
    • Ideal for advanced users and experimental features

The validation mode is controlled by the mode parameter in constructors:

# Strict mode (default) - rejects unknown options
julia> MyStrategy(unknown_option=123)  # ERROR

# Permissive mode - accepts unknown options with warning
julia> MyStrategy(unknown_option=123; mode=:permissive)  # WARNING but works

API Methods

The Strategies module provides these methods for working with strategies:

  • id(strategy_type) - Get the unique identifier
  • metadata(strategy_type) - Get option specifications
  • options(strategy) - Get current configuration
  • build_strategy_options(Type; mode=:strict, kwargs...) - Validate and merge options

Example

# Define strategy type
julia> struct MyStrategy <: AbstractStrategy
           options::StrategyOptions
       end

# Implement type-level contract
julia> id(::Type{<:MyStrategy}) = :mystrategy
julia> metadata(::Type{<:MyStrategy}) = StrategyMetadata(
           OptionDefinition(name=:max_iter, type=Int, default=100, description="Max iterations")
       )

# Implement constructor (required)
julia> function MyStrategy(; mode::Symbol=:strict, kwargs...)
           options = build_strategy_options(MyStrategy; mode=mode, kwargs...)
           return MyStrategy(options)
       end

# Use the strategy
julia> strategy = MyStrategy(max_iter=200)  # Instance with custom config (strict mode)
julia> id(typeof(strategy))                 # => :mystrategy (type-level)
julia> options(strategy)                    # => StrategyOptions (instance-level)

# Use with permissive mode for unknown options
julia> strategy = MyStrategy(max_iter=200, custom_option=123; mode=:permissive)

Notes

  • Type-level methods are called on the type: id(MyStrategy)
  • Instance-level methods are called on instances: options(strategy)
  • Constructor pattern is required for registry-based construction
  • Strategy families can be created with intermediate abstract types

AbstractStrategyParameter

CTSolvers.Strategies.AbstractStrategyParameterType

Abstract base type for strategy parameters.

Strategy parameters allow specialization of strategy behavior and default options. Every concrete parameter must implement:

  • id(::Type{<:AbstractStrategyParameter})::Symbol - Unique identifier

Examples

struct CPU <: AbstractStrategyParameter end
id(::Type{CPU}) = :cpu

struct GPU <: AbstractStrategyParameter end
id(::Type{GPU}) = :gpu

Notes

  • Parameters are singleton types (no fields) - they exist only for type dispatch
  • IDs must be globally unique across all strategies and parameters
  • Parameters are used to specialize default options in strategy metadata

CPU

CTSolvers.Strategies.CPUType

CPU parameter type for CPU-based computation.

This parameter indicates that a strategy should use CPU-based backends and default options optimized for CPU execution.

GPU

CTSolvers.Strategies.GPUType

GPU parameter type for GPU-based computation.

This parameter indicates that a strategy should use GPU-based backends and default options optimized for GPU execution.

Notes

  • Requires CUDA.jl to be loaded and functional
  • Strategies may throw CTBase.Exceptions.ExtensionError if CUDA is not available

StrategyMetadata

CTSolvers.Strategies.StrategyMetadataType
struct StrategyMetadata{NT<:NamedTuple}

Metadata about a strategy type, wrapping option definitions.

This type serves as a container for OptionDefinition objects that define the contract for a strategy's configuration options. It is returned by the type-level metadata(::Type{<:AbstractStrategy}) method and provides a convenient interface for accessing and managing option definitions.

Strategy Contract

Every concrete strategy type must implement the metadata method to return a StrategyMetadata instance describing its configurable options:

function metadata(::Type{<:MyStrategy})
    return StrategyMetadata(
        OptionDefinition(...),
        OptionDefinition(...),
        # ... more option definitions
    )
end

This metadata is used by:

  • Validation: Check option types and values before construction
  • Documentation: Auto-generate option documentation
  • Introspection: Query available options without instantiation
  • Construction: Build StrategyOptions with build_strategy_options

Fields

  • specs::NamedTuple: NamedTuple mapping option names to their definitions (type-stable)

Type Parameter

  • NT <: NamedTuple: The concrete NamedTuple type holding the option definitions

Constructor

The constructor accepts a variable number of OptionDefinition arguments and automatically builds the internal NamedTuple, validating that all option names are unique. The type parameter is inferred automatically.

Collection Interface

StrategyMetadata implements standard Julia collection interfaces:

  • meta[:option_name] - Access definition by name
  • keys(meta) - Get all option names
  • values(meta) - Get all definitions
  • pairs(meta) - Iterate over name-definition pairs
  • length(meta) - Number of options

Example - Standalone Usage

julia> using CTSolvers.Strategies

julia> meta = StrategyMetadata(
           OptionDefinition(
               name = :max_iter,
               type = Int,
               default = 100,
               description = "Maximum iterations",
               aliases = (:max, :maxiter),
               validator = x -> x > 0 || throw(ArgumentError("$x must be positive"))
           ),
           OptionDefinition(
               name = :tol,
               type = Float64,
               default = 1e-6,
               description = "Convergence tolerance"
           )
       )
StrategyMetadata with 2 options:
  max_iter (max, maxiter) :: Int64
    default: 100
    description: Maximum iterations
  tol :: Float64
    default: 1.0e-6
    description: Convergence tolerance

julia> meta[:max_iter].name
:max_iter

julia> collect(keys(meta))
2-element Vector{Symbol}:
 :max_iter
 :tol

Example - Strategy Implementation

# Define a concrete strategy type
struct MyOptimizer <: AbstractStrategy
    options::StrategyOptions
end

# Implement the metadata contract (type-level)
function metadata(::Type{<:MyOptimizer})
    return StrategyMetadata(
        OptionDefinition(
            name = :max_iter,
            type = Int,
            default = 100,
            description = "Maximum number of iterations",
            validator = x -> x > 0 || throw(ArgumentError("max_iter must be positive"))
        ),
        OptionDefinition(
            name = :tol,
            type = Float64,
            default = 1e-6,
            description = "Convergence tolerance",
            validator = x -> x > 0 || throw(ArgumentError("tol must be positive"))
        )
    )
end

# Implement the id contract (type-level)
id(::Type{<:MyOptimizer}) = :myoptimizer

# Implement constructor using build_strategy_options
function MyOptimizer(; kwargs...)
    options = build_strategy_options(MyOptimizer; kwargs...)
    return MyOptimizer(options)
end

# Now the strategy can be used with automatic validation
julia> strategy = MyOptimizer(max_iter=200, tol=1e-8)
julia> options(strategy)
StrategyOptions(max_iter=200, tol=1.0e-8)

Throws

  • Exceptions.IncorrectArgument: If duplicate option names are provided

See also: OptionDefinition, AbstractStrategy, build_strategy_options

StrategyOptions

CTSolvers.Strategies.StrategyOptionsType
struct StrategyOptions{NT<:NamedTuple}

Wrapper for strategy option values with provenance tracking.

This type stores options as a collection of OptionValue objects, each containing both the value and its source (:user, :default, or :computed).

Validation Modes

Strategy options are built using build_strategy_options() which supports two validation modes:

  • Strict Mode (default): Only known options are accepted

    • Unknown options trigger detailed error messages with suggestions
    • Type validation and custom validators are enforced
    • Provides early error detection and safety
  • Permissive Mode: Unknown options are accepted with warnings

    • Unknown options are stored with :user source
    • Type validation and custom validators still apply to known options
    • Allows backend-specific options without breaking changes

Fields

  • options::NamedTuple: NamedTuple of OptionValue objects with provenance

Construction

julia> using CTSolvers.Strategies, CTSolvers.Options

julia> opts = StrategyOptions(
           max_iter = OptionValue(200, :user),
           tol = OptionValue(1e-6, :default)
       )
StrategyOptions with 2 options:
  max_iter = 200  [user]
  tol = 1.0e-6  [default]

Building Options with Validation

# Strict mode (default) - rejects unknown options
julia> opts = build_strategy_options(MyStrategy; max_iter=200)
StrategyOptions(...)

# Permissive mode - accepts unknown options with warning
julia> opts = build_strategy_options(MyStrategy; max_iter=200, custom_opt=123; mode=:permissive)
StrategyOptions(...)  # with warning about custom_opt

Access patterns

# Get value only
julia> opts[:max_iter]
200

# Get OptionValue (value + source)
julia> opts.max_iter
OptionValue(200, :user)

# Get source only
julia> source(opts, :max_iter)
:user

# Check if user-provided
julia> is_user(opts, :max_iter)
true

Iteration

# Iterate over values
julia> for value in opts
           println(value)
       end

# Iterate over (name, value) pairs
julia> for (name, value) in opts
           println("$name = $value")
       end

See also: OptionValue, source, is_user, is_default, is_computed

describe

CTSolvers.Strategies.describeFunction

Display detailed information about a strategy type, including its id, supertype, and full metadata with all available option definitions.

This function is useful for discovering what options a strategy accepts before constructing an instance.

Arguments

  • strategy_type::Type{<:AbstractStrategy}: The strategy type to describe

Example

julia> describe(Modelers.ADNLP)
Modelers.ADNLP (strategy type)
├─ id: :adnlp
├─ supertype: AbstractNLPModeler
└─ metadata: 4 options defined
   ├─ show_time :: Bool (default: false)
   │  description: Whether to show timing information
   ├─ backend :: Symbol (default: optimized)
   │  description: AD backend used by ADNLPModels
   └─ matrix_free :: Bool (default: false)
      description: Enable matrix-free mode

See also: metadata, id, options

id

CTSolvers.Strategies.idFunction

Return the unique identifier for this strategy type.

Arguments

  • strategy_type::Type{<:AbstractStrategy}: The strategy type

Returns

  • Symbol: Unique identifier for the strategy

Example

# For a concrete strategy type MyStrategy:
julia> id(MyStrategy)
:mystrategy

metadata

CTSolvers.Strategies.metadataFunction

Return metadata about a strategy type.

Arguments

  • strategy_type::Type{<:AbstractStrategy}: The strategy type

Returns

  • StrategyMetadata: Option specifications and validation rules

Example

# For a concrete strategy type MyStrategy:
julia> meta = metadata(MyStrategy)
julia> meta
StrategyMetadata with option definitions for max_iter, etc.

options

CTSolvers.Strategies.optionsFunction

Return the current options of a strategy as a StrategyOptions.

Arguments

  • strategy::AbstractStrategy: The strategy instance

Returns

  • StrategyOptions: Current option values with provenance tracking

Example

# For a concrete strategy instance:
julia> strategy = MyStrategy(backend=:sparse)
julia> opts = options(strategy)
julia> opts
StrategyOptions with values=(backend=:sparse), sources=(backend=:user)