Skip to content

Commit a52b267

Browse files
Move preference handling to dedicated src/preferences.jl file
Reorganized the preference system code into a dedicated file for better organization: ## File Organization - **Created**: src/preferences.jl with all preference-related functionality - **Moved**: _string_to_algorithm_choice, AUTOTUNE_PREFS, reset_defaults!, etc. - **Moved**: _choose_available_algorithm and _get_tuned_algorithm_runtime - **Updated**: include order to load preferences.jl before analysis.jl ## Clean Separation - **src/preferences.jl**: All preference system logic and constants - **src/default.jl**: Algorithm selection logic using preference system - **src/analysis.jl**: User-facing analysis function - **src/LinearSolve.jl**: Main module file with includes ## Enhanced Analysis Display - **All element types**: Float32, Float64, ComplexF32, ComplexF64 shown for all sizes - **Tabular format**: Clear side-by-side comparison across element types - **Comprehensive view**: Shows preference effects across all combinations ## Verification ✅ Reorganized preference system works correctly ✅ Algorithm choice responds to preferences in testing mode ✅ Enhanced show_algorithm_choices displays all element types properly This provides a clean, well-organized codebase with separated concerns and comprehensive preference system verification capabilities. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent a86bd4c commit a52b267

File tree

3 files changed

+203
-198
lines changed

3 files changed

+203
-198
lines changed

src/LinearSolve.jl

Lines changed: 1 addition & 162 deletions
Original file line numberDiff line numberDiff line change
@@ -278,168 +278,6 @@ EnumX.@enumx DefaultAlgorithmChoice begin
278278
end
279279

280280
# Autotune preference constants - loaded once at package import time
281-
# Helper function to convert algorithm name string to DefaultAlgorithmChoice enum
282-
function _string_to_algorithm_choice(algorithm_name::Union{String, Nothing})
283-
algorithm_name === nothing && return nothing
284-
285-
# Core LU algorithms from LinearSolveAutotune
286-
if algorithm_name == "LUFactorization"
287-
return DefaultAlgorithmChoice.LUFactorization
288-
elseif algorithm_name == "GenericLUFactorization"
289-
return DefaultAlgorithmChoice.GenericLUFactorization
290-
elseif algorithm_name == "RFLUFactorization" || algorithm_name == "RecursiveFactorization"
291-
return DefaultAlgorithmChoice.RFLUFactorization
292-
elseif algorithm_name == "MKLLUFactorization"
293-
return DefaultAlgorithmChoice.MKLLUFactorization
294-
elseif algorithm_name == "AppleAccelerateLUFactorization"
295-
return DefaultAlgorithmChoice.AppleAccelerateLUFactorization
296-
elseif algorithm_name == "SimpleLUFactorization"
297-
return DefaultAlgorithmChoice.LUFactorization # Map to standard LU
298-
elseif algorithm_name == "FastLUFactorization"
299-
return DefaultAlgorithmChoice.LUFactorization # Map to standard LU (FastLapack extension)
300-
elseif algorithm_name == "BLISLUFactorization"
301-
return DefaultAlgorithmChoice.LUFactorization # Map to standard LU (BLIS extension)
302-
elseif algorithm_name == "CudaOffloadLUFactorization"
303-
return DefaultAlgorithmChoice.LUFactorization # Map to standard LU (CUDA extension)
304-
elseif algorithm_name == "MetalLUFactorization"
305-
return DefaultAlgorithmChoice.LUFactorization # Map to standard LU (Metal extension)
306-
elseif algorithm_name == "AMDGPUOffloadLUFactorization"
307-
return DefaultAlgorithmChoice.LUFactorization # Map to standard LU (AMDGPU extension)
308-
else
309-
@warn "Unknown algorithm preference: $algorithm_name, falling back to heuristics"
310-
return nothing
311-
end
312-
end
313-
314-
# Load autotune preferences as constants for each element type and size category
315-
# Support both best overall algorithm and best always-loaded algorithm as fallback
316-
const AUTOTUNE_PREFS = (
317-
Float32 = (
318-
tiny = (
319-
best = _string_to_algorithm_choice(Preferences.@load_preference("best_algorithm_Float32_tiny", nothing)),
320-
fallback = _string_to_algorithm_choice(Preferences.@load_preference("best_always_loaded_Float32_tiny", nothing))
321-
),
322-
small = (
323-
best = _string_to_algorithm_choice(Preferences.@load_preference("best_algorithm_Float32_small", nothing)),
324-
fallback = _string_to_algorithm_choice(Preferences.@load_preference("best_always_loaded_Float32_small", nothing))
325-
),
326-
medium = (
327-
best = _string_to_algorithm_choice(Preferences.@load_preference("best_algorithm_Float32_medium", nothing)),
328-
fallback = _string_to_algorithm_choice(Preferences.@load_preference("best_always_loaded_Float32_medium", nothing))
329-
),
330-
large = (
331-
best = _string_to_algorithm_choice(Preferences.@load_preference("best_algorithm_Float32_large", nothing)),
332-
fallback = _string_to_algorithm_choice(Preferences.@load_preference("best_always_loaded_Float32_large", nothing))
333-
),
334-
big = (
335-
best = _string_to_algorithm_choice(Preferences.@load_preference("best_algorithm_Float32_big", nothing)),
336-
fallback = _string_to_algorithm_choice(Preferences.@load_preference("best_always_loaded_Float32_big", nothing))
337-
)
338-
),
339-
Float64 = (
340-
tiny = (
341-
best = _string_to_algorithm_choice(Preferences.@load_preference("best_algorithm_Float64_tiny", nothing)),
342-
fallback = _string_to_algorithm_choice(Preferences.@load_preference("best_always_loaded_Float64_tiny", nothing))
343-
),
344-
small = (
345-
best = _string_to_algorithm_choice(Preferences.@load_preference("best_algorithm_Float64_small", nothing)),
346-
fallback = _string_to_algorithm_choice(Preferences.@load_preference("best_always_loaded_Float64_small", nothing))
347-
),
348-
medium = (
349-
best = _string_to_algorithm_choice(Preferences.@load_preference("best_algorithm_Float64_medium", nothing)),
350-
fallback = _string_to_algorithm_choice(Preferences.@load_preference("best_always_loaded_Float64_medium", nothing))
351-
),
352-
large = (
353-
best = _string_to_algorithm_choice(Preferences.@load_preference("best_algorithm_Float64_large", nothing)),
354-
fallback = _string_to_algorithm_choice(Preferences.@load_preference("best_always_loaded_Float64_large", nothing))
355-
),
356-
big = (
357-
best = _string_to_algorithm_choice(Preferences.@load_preference("best_algorithm_Float64_big", nothing)),
358-
fallback = _string_to_algorithm_choice(Preferences.@load_preference("best_always_loaded_Float64_big", nothing))
359-
)
360-
),
361-
ComplexF32 = (
362-
tiny = (
363-
best = _string_to_algorithm_choice(Preferences.@load_preference("best_algorithm_ComplexF32_tiny", nothing)),
364-
fallback = _string_to_algorithm_choice(Preferences.@load_preference("best_always_loaded_ComplexF32_tiny", nothing))
365-
),
366-
small = (
367-
best = _string_to_algorithm_choice(Preferences.@load_preference("best_algorithm_ComplexF32_small", nothing)),
368-
fallback = _string_to_algorithm_choice(Preferences.@load_preference("best_always_loaded_ComplexF32_small", nothing))
369-
),
370-
medium = (
371-
best = _string_to_algorithm_choice(Preferences.@load_preference("best_algorithm_ComplexF32_medium", nothing)),
372-
fallback = _string_to_algorithm_choice(Preferences.@load_preference("best_always_loaded_ComplexF32_medium", nothing))
373-
),
374-
large = (
375-
best = _string_to_algorithm_choice(Preferences.@load_preference("best_algorithm_ComplexF32_large", nothing)),
376-
fallback = _string_to_algorithm_choice(Preferences.@load_preference("best_always_loaded_ComplexF32_large", nothing))
377-
),
378-
big = (
379-
best = _string_to_algorithm_choice(Preferences.@load_preference("best_algorithm_ComplexF32_big", nothing)),
380-
fallback = _string_to_algorithm_choice(Preferences.@load_preference("best_always_loaded_ComplexF32_big", nothing))
381-
)
382-
),
383-
ComplexF64 = (
384-
tiny = (
385-
best = _string_to_algorithm_choice(Preferences.@load_preference("best_algorithm_ComplexF64_tiny", nothing)),
386-
fallback = _string_to_algorithm_choice(Preferences.@load_preference("best_always_loaded_ComplexF64_tiny", nothing))
387-
),
388-
small = (
389-
best = _string_to_algorithm_choice(Preferences.@load_preference("best_algorithm_ComplexF64_small", nothing)),
390-
fallback = _string_to_algorithm_choice(Preferences.@load_preference("best_always_loaded_ComplexF64_small", nothing))
391-
),
392-
medium = (
393-
best = _string_to_algorithm_choice(Preferences.@load_preference("best_algorithm_ComplexF64_medium", nothing)),
394-
fallback = _string_to_algorithm_choice(Preferences.@load_preference("best_always_loaded_ComplexF64_medium", nothing))
395-
),
396-
large = (
397-
best = _string_to_algorithm_choice(Preferences.@load_preference("best_algorithm_ComplexF64_large", nothing)),
398-
fallback = _string_to_algorithm_choice(Preferences.@load_preference("best_always_loaded_ComplexF64_large", nothing))
399-
),
400-
big = (
401-
best = _string_to_algorithm_choice(Preferences.@load_preference("best_algorithm_ComplexF64_big", nothing)),
402-
fallback = _string_to_algorithm_choice(Preferences.@load_preference("best_always_loaded_ComplexF64_big", nothing))
403-
)
404-
)
405-
)
406-
407-
# Fast path: check if any autotune preferences are actually set
408-
const AUTOTUNE_PREFS_SET = let
409-
any_set = false
410-
for type_prefs in (AUTOTUNE_PREFS.Float32, AUTOTUNE_PREFS.Float64, AUTOTUNE_PREFS.ComplexF32, AUTOTUNE_PREFS.ComplexF64)
411-
for size_pref in (type_prefs.tiny, type_prefs.small, type_prefs.medium, type_prefs.large, type_prefs.big)
412-
if size_pref.best !== nothing || size_pref.fallback !== nothing
413-
any_set = true
414-
break
415-
end
416-
end
417-
any_set && break
418-
end
419-
any_set
420-
end
421-
422-
423-
"""
424-
reset_defaults!()
425-
426-
**Internal function for testing only.** Rebuilds the preference globals
427-
to reflect currently set preferences. This allows tests to verify that the
428-
preference system works correctly by setting preferences and then rebuilding
429-
the globals to simulate a fresh package load.
430-
431-
!!! warning "Testing Only"
432-
This function is only intended for internal testing purposes. It modifies
433-
global state and should never be used in production code.
434-
"""
435-
# Testing mode flag
436-
const TESTING_MODE = Ref(false)
437-
438-
function reset_defaults!()
439-
# Enable testing mode to use runtime preference checking
440-
TESTING_MODE[] = true
441-
return nothing
442-
end
443281

444282
# Algorithm availability checking functions
445283
"""
@@ -501,6 +339,7 @@ include("simplelu.jl")
501339
include("simplegmres.jl")
502340
include("iterative_wrappers.jl")
503341
include("preconditioners.jl")
342+
include("preferences.jl")
504343
include("analysis.jl")
505344
include("solve_function.jl")
506345
include("default.jl")

src/default.jl

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -292,43 +292,7 @@ end
292292

293293
@inline _get_tuned_algorithm_impl(::Type, ::Symbol) = nothing # Fallback for other types
294294

295-
# Runtime preference checking for testing
296-
function _get_tuned_algorithm_runtime(target_eltype::Type, size_category::Symbol)
297-
eltype_str = string(target_eltype)
298-
size_str = string(size_category)
299-
300-
# Load preferences at runtime
301-
best_pref = Preferences.load_preference(LinearSolve, "best_algorithm_$(eltype_str)_$(size_str)", nothing)
302-
fallback_pref = Preferences.load_preference(LinearSolve, "best_always_loaded_$(eltype_str)_$(size_str)", nothing)
303-
304-
if best_pref !== nothing || fallback_pref !== nothing
305-
# Convert to algorithm choices
306-
best_alg = LinearSolve._string_to_algorithm_choice(best_pref)
307-
fallback_alg = LinearSolve._string_to_algorithm_choice(fallback_pref)
308-
309-
# Create preference structure
310-
prefs = (best = best_alg, fallback = fallback_alg)
311-
return LinearSolve._choose_available_algorithm(prefs)
312-
end
313-
314-
return nothing
315-
end
316295

317-
# Helper function to choose available algorithm with fallback logic
318-
@inline function _choose_available_algorithm(prefs)
319-
# Try the best algorithm first
320-
if prefs.best !== nothing && is_algorithm_available(prefs.best)
321-
return prefs.best
322-
end
323-
324-
# Fall back to always-loaded algorithm if best is not available
325-
if prefs.fallback !== nothing && is_algorithm_available(prefs.fallback)
326-
return prefs.fallback
327-
end
328-
329-
# No tuned algorithms available
330-
return nothing
331-
end
332296

333297
# Convenience method for when A is nothing - delegate to main implementation
334298
@inline get_tuned_algorithm(::Type{Nothing}, ::Type{eltype_b}, matrix_size::Integer) where {eltype_b} =

0 commit comments

Comments
 (0)