From c12831b999312f8c79ebb1d118bde74e6e98e4b3 Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Thu, 9 Apr 2026 14:57:04 +0900 Subject: [PATCH 01/41] [lib] first try of `QuantumToolboxUtils` --- Project.toml | 7 + docs/make.jl | 1 + lib/QuantumToolboxUtils/LICENSE | 29 +++ lib/QuantumToolboxUtils/Project.toml | 17 ++ .../src/PhysicalConstants.jl | 80 +++++++ .../src/QuantumToolboxUtils.jl | 13 ++ lib/QuantumToolboxUtils/src/misc.jl | 48 +++++ lib/QuantumToolboxUtils/src/type_handle.jl | 70 ++++++ .../test/PhysicalConstants.jl | 38 ++++ lib/QuantumToolboxUtils/test/n_thermal.jl | 19 ++ src/QuantumToolbox.jl | 21 +- src/utilities.jl | 204 ------------------ src/versioninfo.jl | 1 + test/core-test/cite.jl | 21 ++ test/core-test/utilities.jl | 77 ------- 15 files changed, 364 insertions(+), 282 deletions(-) create mode 100644 lib/QuantumToolboxUtils/LICENSE create mode 100644 lib/QuantumToolboxUtils/Project.toml create mode 100644 lib/QuantumToolboxUtils/src/PhysicalConstants.jl create mode 100644 lib/QuantumToolboxUtils/src/QuantumToolboxUtils.jl create mode 100644 lib/QuantumToolboxUtils/src/misc.jl create mode 100644 lib/QuantumToolboxUtils/src/type_handle.jl create mode 100644 lib/QuantumToolboxUtils/test/PhysicalConstants.jl create mode 100644 lib/QuantumToolboxUtils/test/n_thermal.jl delete mode 100644 src/utilities.jl create mode 100644 test/core-test/cite.jl delete mode 100644 test/core-test/utilities.jl diff --git a/Project.toml b/Project.toml index 769867282..f218430f3 100644 --- a/Project.toml +++ b/Project.toml @@ -20,7 +20,9 @@ OrdinaryDiffEqLowOrderRK = "1344f307-1e59-4825-a18e-ace9aa3fa4c6" OrdinaryDiffEqVerner = "79d7bb75-1356-48c1-b8c0-6832512096c2" Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" ProgressMeter = "92933f4c-e287-5a05-a399-4b506db050ca" +QuantumToolboxUtils = "02afad9e-e2b8-4f9a-965f-b5dca5b538ca" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +Reexport = "189a3867-3050-52da-a836-e630ba90ab69" SciMLBase = "0bca4576-84f4-4d90-8ffe-ffa030f20462" SciMLOperators = "c0aeaf25-5076-4817-a8d5-81caf7dfa961" SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" @@ -36,6 +38,9 @@ GPUArrays = "0c68f7d7-f131-5f86-a1c3-88cf8149b2d7" KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c" Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" +[sources] +QuantumToolboxUtils = {path = "lib/QuantumToolboxUtils"} + [extensions] QuantumToolboxCUDAExt = "CUDA" QuantumToolboxChainRulesCoreExt = "ChainRulesCore" @@ -64,7 +69,9 @@ OrdinaryDiffEqLowOrderRK = "1" OrdinaryDiffEqVerner = "1" Pkg = "1" ProgressMeter = "1.11.0" +QuantumToolboxUtils = "0.1" Random = "1" +Reexport = "1" SciMLBase = "2.105" SciMLOperators = "1.12" SparseArrays = "1" diff --git a/docs/make.jl b/docs/make.jl index 59ab77ec9..6f8a0f930 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -83,6 +83,7 @@ const PAGES = [ makedocs(; modules = [ + QuantumToolboxUtils, QuantumToolbox, Base.get_extension(QuantumToolbox, :QuantumToolboxMakieExt), ], diff --git a/lib/QuantumToolboxUtils/LICENSE b/lib/QuantumToolboxUtils/LICENSE new file mode 100644 index 000000000..a3dbb37b8 --- /dev/null +++ b/lib/QuantumToolboxUtils/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2022 to 2026 inclusive, QuTiP developers and contributors. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/lib/QuantumToolboxUtils/Project.toml b/lib/QuantumToolboxUtils/Project.toml new file mode 100644 index 000000000..ba231cd15 --- /dev/null +++ b/lib/QuantumToolboxUtils/Project.toml @@ -0,0 +1,17 @@ +name = "QuantumToolboxUtils" +uuid = "02afad9e-e2b8-4f9a-965f-b5dca5b538ca" +authors = ["Alberto Mercurio", "Yi-Te Huang"] +version = "0.1.0" + +[deps] +Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +SciMLOperators = "c0aeaf25-5076-4817-a8d5-81caf7dfa961" +SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" +StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" + +[compat] +Random = "1" +SciMLOperators = "1.12" +SparseArrays = "1" +StaticArraysCore = "1" +julia = "1.10" diff --git a/lib/QuantumToolboxUtils/src/PhysicalConstants.jl b/lib/QuantumToolboxUtils/src/PhysicalConstants.jl new file mode 100644 index 000000000..c6fd8f366 --- /dev/null +++ b/lib/QuantumToolboxUtils/src/PhysicalConstants.jl @@ -0,0 +1,80 @@ +export PhysicalConstants, convert_unit + +@doc raw""" + const PhysicalConstants + +A `NamedTuple` which stores some constant values listed in [*CODATA recommended values of the fundamental physical constants: 2022*](https://physics.nist.gov/cuu/pdf/wall_2022.pdf) + +The current stored constants are: +- `c` : (exact) speed of light in vacuum with unit ``[\textrm{m}\cdot\textrm{s}^{-1}]`` +- `G` : Newtonian constant of gravitation with unit ``[\textrm{m}^3\cdot\textrm{kg}^{−1}\cdot\textrm{s}^{−2}]`` +- `h` : (exact) Planck constant with unit ``[\textrm{J}\cdot\textrm{s}]`` +- `ħ` : reduced Planck constant with unit ``[\textrm{J}\cdot\textrm{s}]`` +- `e` : (exact) elementary charge with unit ``[\textrm{C}]`` +- `μ0` : vacuum magnetic permeability with unit ``[\textrm{N}\cdot\textrm{A}^{-2}]`` +- `ϵ0` : vacuum electric permittivity with unit ``[\textrm{F}\cdot\textrm{m}^{-1}]`` +- `k` : (exact) Boltzmann constant with unit ``[\textrm{J}\cdot\textrm{K}^{-1}]`` +- `NA` : (exact) Avogadro constant with unit ``[\textrm{mol}^{-1}]`` + +# Examples + +```jldoctest +julia> PhysicalConstants.ħ +1.0545718176461565e-34 +``` +""" +const PhysicalConstants = ( + c = 299792458.0, + G = 6.6743e-11, + h = 6.62607015e-34, + ħ = 6.62607015e-34 / (2 * π), + e = 1.602176634e-19, + μ0 = 1.25663706127e-6, + ϵ0 = 8.8541878188e-12, + k = 1.380649e-23, + NA = 6.02214076e23, +) + +# common energy units (the values below are all in the unit of Joule) +const _energy_units::Dict{Symbol, Float64} = Dict( + :J => 1.0, + :eV => PhysicalConstants.e, + :meV => 1.0e-3 * PhysicalConstants.e, + :MHz => 1.0e6 * PhysicalConstants.h, + :GHz => 1.0e9 * PhysicalConstants.h, + :K => PhysicalConstants.k, + :mK => 1.0e-3 * PhysicalConstants.k, +) + +@doc raw""" + convert_unit(value::Real, unit1::Symbol, unit2::Symbol) + +Convert the energy `value` from `unit1` to `unit2`. The `unit1` and `unit2` can be either the following `Symbol`: +- `:J` : Joule +- `:eV` : electron volt +- `:meV` : milli-electron volt +- `:MHz` : Mega-Hertz multiplied by Planck constant ``h`` +- `:GHz` : Giga-Hertz multiplied by Planck constant ``h`` +- `:K` : Kelvin multiplied by Boltzmann constant ``k`` +- `:mK` : milli-Kelvin multiplied by Boltzmann constant ``k`` + +Note that we use the values stored in [`PhysicalConstants`](@ref) to do the conversion. + +# Examples + +```jldoctest +julia> convert_unit(1, :eV, :J) +1.602176634e-19 + +julia> convert_unit(1, :GHz, :J) +6.62607015e-25 + +julia> round(convert_unit(1, :meV, :mK), digits=4) +11604.5181 +``` +""" +function convert_unit(value::T, unit1::Symbol, unit2::Symbol) where {T <: Real} + !haskey(_energy_units, unit1) && throw(ArgumentError("Invalid unit :$(unit1)")) + !haskey(_energy_units, unit2) && throw(ArgumentError("Invalid unit :$(unit2)")) + return _float_type(T)(value * (_energy_units[unit1] / _energy_units[unit2])) +end \ No newline at end of file diff --git a/lib/QuantumToolboxUtils/src/QuantumToolboxUtils.jl b/lib/QuantumToolboxUtils/src/QuantumToolboxUtils.jl new file mode 100644 index 000000000..0c8d8415f --- /dev/null +++ b/lib/QuantumToolboxUtils/src/QuantumToolboxUtils.jl @@ -0,0 +1,13 @@ +module QuantumToolboxUtils + +using SparseArrays +import StaticArraysCore: SVector, MVector +import Random: AbstractRNG + +import SciMLOperators: AbstractSciMLOperator + +include("type_handle.jl") +include("PhysicalConstants.jl") +include("misc.jl") + +end \ No newline at end of file diff --git a/lib/QuantumToolboxUtils/src/misc.jl b/lib/QuantumToolboxUtils/src/misc.jl new file mode 100644 index 000000000..38dc9139b --- /dev/null +++ b/lib/QuantumToolboxUtils/src/misc.jl @@ -0,0 +1,48 @@ +export gaussian, n_thermal +export row_major_reshape, meshgrid + +@doc raw""" + row_major_reshape(Q::AbstractArray, shapes...) + +Reshapes `Q` in the row-major order, as numpy. +""" +row_major_reshape(Q::AbstractArray{T}, shapes...) where {T} = + PermutedDimsArray(reshape(Q, reverse(shapes)...), (length(shapes):-1:1)) + +@doc raw""" + meshgrid(x::AbstractVector, y::AbstractVector) + +Equivalent to [numpy meshgrid](https://numpy.org/doc/stable/reference/generated/numpy.meshgrid.html). +""" +function meshgrid(x::AbstractVector{T}, y::AbstractVector{T}) where {T} + X = reshape(repeat(x, inner = length(y)), length(y), length(x)) + Y = repeat(y, outer = (1, length(x))) + return X, Y +end + +@doc raw""" + gaussian(x::Number, μ::Number, σ::Number) + +Returns the gaussian function ``\exp \left[- \frac{(x - \mu)^2}{2 \sigma^2} \right]``, +where ``\mu`` and ``\sigma^2`` are the mean and the variance respectively. +""" +gaussian(x::Number, μ::Number, σ::Number) = exp(-(x - μ)^2 / (2 * σ^2)) + +@doc raw""" + n_thermal(ω::Real, ω_th::Real) + +Return the number of photons in thermal equilibrium for an harmonic oscillator mode with frequency ``\omega``, at the temperature described by ``\omega_{\textrm{th}} \equiv k_B T / \hbar``: +```math +n(\omega, \omega_{\textrm{th}}) = \frac{1}{e^{\omega/\omega_{\textrm{th}}} - 1}, +``` +where ``\hbar`` is the reduced Planck constant, and ``k_B`` is the Boltzmann constant. +""" +function n_thermal(ω::T1, ω_th::T2) where {T1 <: Real, T2 <: Real} + x = exp(ω / ω_th) + n = ((x != 1) && (ω_th > 0)) ? 1 / (x - 1) : 0 + return _float_type(promote_type(T1, T2))(n) +end + +_Ginibre_ensemble(rng::AbstractRNG, ::Type{T}, n::Int, rank::Int = n) where {T <: Complex} = randn(rng, T, n, rank) / sqrt(T(n)) + +_Boltzmann_weight(β::T, E::Int) where {T <: Real} = (E != 0 || isfinite(β)) ? exp(-β * E) : one(T) \ No newline at end of file diff --git a/lib/QuantumToolboxUtils/src/type_handle.jl b/lib/QuantumToolboxUtils/src/type_handle.jl new file mode 100644 index 000000000..8737c4034 --- /dev/null +++ b/lib/QuantumToolboxUtils/src/type_handle.jl @@ -0,0 +1,70 @@ +makeVal(x::Val{T}) where {T} = x +makeVal(x) = Val(x) + +getVal(x::Val{T}) where {T} = T +getVal(x) = x # getVal for any other type + +_non_static_array_warning(argname, arg::Tuple{}) = + throw(ArgumentError("The argument $argname must be a Tuple or a StaticVector of non-zero length.")) +_non_static_array_warning(argname, arg::Union{SVector{N, T}, MVector{N, T}, NTuple{N, T}}) where {N, T} = nothing +_non_static_array_warning(argname, arg::AbstractVector{T}) where {T} = + @warn "The argument $argname should be a Tuple or a StaticVector for better performance. Try to use `$argname = $(Tuple(arg))` instead of `$argname = $arg`. " * + "Alternatively, you can do `import QuantumToolbox: SVector` " * + "and use `$argname = SVector(" * + join(arg, ", ") * + ")`." maxlog = 1 + +# lazy tensor warning +for AType in (:AbstractArray, :AbstractSciMLOperator) + for BType in (:AbstractArray, :AbstractSciMLOperator) + if AType == BType == :AbstractArray + @eval begin + _lazy_tensor_warning(::$AType, ::$BType) = nothing + end + else + @eval begin + _lazy_tensor_warning(A::$AType, B::$BType) = + @warn "using lazy tensor (which can hurt performance) between data types: $(get_typename_wrapper(A)) and $(get_typename_wrapper(B))" + end + end + end +end + +get_typename_wrapper(A) = Base.typename(typeof(A)).wrapper + +_dense_similar(A::AbstractArray, args...) = similar(A, args...) +_dense_similar(A::AbstractSparseMatrix, args...) = similar(nonzeros(A), args...) + +_sparse_similar(A::AbstractArray, args...) = sparse(args...) + +# alias of abstract types +const FloatOrComplex = Union{T, Complex{T}} where {T <: AbstractFloat} + +# functions for getting Float or Complex element type +_float_type(::AbstractArray{T}) where {T <: Number} = _float_type(T) +_float_type(::AbstractSciMLOperator{T}) where {T <: Number} = _float_type(T) +_float_type(::Type{Int32}) = Float32 +_float_type(::Type{Int64}) = Float64 +_float_type(::Type{Complex{Int32}}) = Float32 +_float_type(::Type{Complex{Int64}}) = Float64 +_float_type(::Type{Complex{T}}) where {T <: Real} = T +_float_type(T::Type{<:AbstractFloat}) = T # Allow other untracked Real types, like ForwardDiff.Dual +_complex_float_type(::AbstractArray{T}) where {T <: Number} = _complex_float_type(T) +_complex_float_type(::AbstractSciMLOperator{T}) where {T <: Number} = _complex_float_type(T) +_complex_float_type(::Type{Int32}) = ComplexF32 +_complex_float_type(::Type{Int64}) = ComplexF64 +_complex_float_type(::Type{Float32}) = ComplexF32 +_complex_float_type(::Type{Float64}) = ComplexF64 +_complex_float_type(::Type{Complex{Int32}}) = ComplexF32 +_complex_float_type(::Type{Complex{Int64}}) = ComplexF64 +_complex_float_type(::Type{Complex{Float32}}) = ComplexF32 +_complex_float_type(::Type{Complex{Float64}}) = ComplexF64 +_complex_float_type(T::Type{<:AbstractFloat}) = Complex{T} # Allow other untracked Complex types, like ForwardDiff.Dual +_complex_float_type(T::Type{<:Complex}) = T # Allow other untracked Complex types, like ForwardDiff.Dual + +_convert_eltype_wordsize(::Type{T}, ::Val{64}) where {T <: Int} = Int64 +_convert_eltype_wordsize(::Type{T}, ::Val{32}) where {T <: Int} = Int32 +_convert_eltype_wordsize(::Type{T}, ::Val{64}) where {T <: AbstractFloat} = Float64 +_convert_eltype_wordsize(::Type{T}, ::Val{32}) where {T <: AbstractFloat} = Float32 +_convert_eltype_wordsize(::Type{Complex{T}}, ::Val{64}) where {T <: Union{Int, AbstractFloat}} = ComplexF64 +_convert_eltype_wordsize(::Type{Complex{T}}, ::Val{32}) where {T <: Union{Int, AbstractFloat}} = ComplexF32 diff --git a/lib/QuantumToolboxUtils/test/PhysicalConstants.jl b/lib/QuantumToolboxUtils/test/PhysicalConstants.jl new file mode 100644 index 000000000..eba203b55 --- /dev/null +++ b/lib/QuantumToolboxUtils/test/PhysicalConstants.jl @@ -0,0 +1,38 @@ +@testitem "CODATA Physical Constants" begin + c = PhysicalConstants.c + h = PhysicalConstants.h + ħ = PhysicalConstants.ħ + μ0 = PhysicalConstants.μ0 + ϵ0 = PhysicalConstants.ϵ0 + + @test h / ħ ≈ 2 * π + @test μ0 / (4.0e-7 * π) ≈ 1.0 + @test c^2 * μ0 * ϵ0 ≈ 1.0 + + @testset "convert unit" begin + V = 100 * rand(Float64) + _unit_list = [:J, :eV, :meV, :MHz, :GHz, :K, :mK] + for origin in _unit_list + for middle in _unit_list + for target in _unit_list + V_middle = convert_unit(V, origin, middle) + V_target = convert_unit(V_middle, middle, target) + V_origin = convert_unit(V_target, target, origin) + @test V ≈ V_origin + end + end + end + @test_throws ArgumentError convert_unit(V, :bad_unit, :J) + @test_throws ArgumentError convert_unit(V, :J, :bad_unit) + end + + @testset "Type Inference" begin + v = rand(Float64) + _unit_list = [:J, :eV, :meV, :GHz, :mK] + for u1 in _unit_list + for u2 in _unit_list + @inferred convert_unit(v, u1, u2) + end + end + end +end diff --git a/lib/QuantumToolboxUtils/test/n_thermal.jl b/lib/QuantumToolboxUtils/test/n_thermal.jl new file mode 100644 index 000000000..0dfd4f36a --- /dev/null +++ b/lib/QuantumToolboxUtils/test/n_thermal.jl @@ -0,0 +1,19 @@ +@testitem "n_thermal" begin + ω1 = rand(Float64) + ω2 = rand(Float64) + @test n_thermal(0, ω2) == 0.0 + @test n_thermal(ω1, 0) == 0.0 + @test n_thermal(ω1, -ω2) == 0.0 + @test n_thermal(ω1, ω2) == 1 / (exp(ω1 / ω2) - 1) + @test typeof(n_thermal(Int32(2), Int32(3))) == Float32 + @test typeof(n_thermal(Float32(2), Float32(3))) == Float32 + @test typeof(n_thermal(Int64(2), Int32(3))) == Float64 + @test typeof(n_thermal(Int32(2), Int64(3))) == Float64 + @test typeof(n_thermal(Float64(2), Float32(3))) == Float64 + @test typeof(n_thermal(Float32(2), Float64(3))) == Float64 + + @testset "Type Inference" begin + v = rand(Float64) + @inferred n_thermal(v, Int32(123)) + end +end diff --git a/src/QuantumToolbox.jl b/src/QuantumToolbox.jl index e4a0a740c..e0be157a4 100644 --- a/src/QuantumToolbox.jl +++ b/src/QuantumToolbox.jl @@ -11,6 +11,26 @@ import Pkg import Random: AbstractRNG, default_rng, seed! import Statistics: mean, std +## Re-export of QuantumToolbox libraries +import Reexport: @reexport +@reexport using QuantumToolboxUtils + +## internal functions of QuantumToolbox libraries +import QuantumToolboxUtils: + FloatOrComplex, + getVal, + makeVal, + get_typename_wrapper, + _float_type, + _complex_float_type, + _convert_eltype_wordsize, + _non_static_array_warning, + _lazy_tensor_warning, + _Ginibre_ensemble, + _Boltzmann_weight, + _dense_similar, + _sparse_similar + ## SciML packages (for QobjEvo, OrdinaryDiffEq, and LinearSolve) import SciMLBase: solve, @@ -89,7 +109,6 @@ export cache_operator, iscached, isconstant ## Utility include("settings.jl") -include("utilities.jl") include("versioninfo.jl") include("linear_maps.jl") diff --git a/src/utilities.jl b/src/utilities.jl deleted file mode 100644 index 0a58f429b..000000000 --- a/src/utilities.jl +++ /dev/null @@ -1,204 +0,0 @@ -#= -Utilities: - internal (or external) functions which will be used throughout the entire package -=# - -export gaussian, n_thermal -export PhysicalConstants, convert_unit -export row_major_reshape, meshgrid - -@doc raw""" - row_major_reshape(Q::AbstractArray, shapes...) - -Reshapes `Q` in the row-major order, as numpy. -""" -row_major_reshape(Q::AbstractArray{T}, shapes...) where {T} = - PermutedDimsArray(reshape(Q, reverse(shapes)...), (length(shapes):-1:1)) - -@doc raw""" - meshgrid(x::AbstractVector, y::AbstractVector) - -Equivalent to [numpy meshgrid](https://numpy.org/doc/stable/reference/generated/numpy.meshgrid.html). -""" -function meshgrid(x::AbstractVector{T}, y::AbstractVector{T}) where {T} - X = reshape(repeat(x, inner = length(y)), length(y), length(x)) - Y = repeat(y, outer = (1, length(x))) - return X, Y -end - -@doc raw""" - gaussian(x::Number, μ::Number, σ::Number) - -Returns the gaussian function ``\exp \left[- \frac{(x - \mu)^2}{2 \sigma^2} \right]``, -where ``\mu`` and ``\sigma^2`` are the mean and the variance respectively. -""" -gaussian(x::Number, μ::Number, σ::Number) = exp(-(x - μ)^2 / (2 * σ^2)) - -@doc raw""" - n_thermal(ω::Real, ω_th::Real) - -Return the number of photons in thermal equilibrium for an harmonic oscillator mode with frequency ``\omega``, at the temperature described by ``\omega_{\textrm{th}} \equiv k_B T / \hbar``: -```math -n(\omega, \omega_{\textrm{th}}) = \frac{1}{e^{\omega/\omega_{\textrm{th}}} - 1}, -``` -where ``\hbar`` is the reduced Planck constant, and ``k_B`` is the Boltzmann constant. -""" -function n_thermal(ω::T1, ω_th::T2) where {T1 <: Real, T2 <: Real} - x = exp(ω / ω_th) - n = ((x != 1) && (ω_th > 0)) ? 1 / (x - 1) : 0 - return _float_type(promote_type(T1, T2))(n) -end - -@doc raw""" - const PhysicalConstants - -A `NamedTuple` which stores some constant values listed in [*CODATA recommended values of the fundamental physical constants: 2022*](https://physics.nist.gov/cuu/pdf/wall_2022.pdf) - -The current stored constants are: -- `c` : (exact) speed of light in vacuum with unit ``[\textrm{m}\cdot\textrm{s}^{-1}]`` -- `G` : Newtonian constant of gravitation with unit ``[\textrm{m}^3\cdot\textrm{kg}^{−1}\cdot\textrm{s}^{−2}]`` -- `h` : (exact) Planck constant with unit ``[\textrm{J}\cdot\textrm{s}]`` -- `ħ` : reduced Planck constant with unit ``[\textrm{J}\cdot\textrm{s}]`` -- `e` : (exact) elementary charge with unit ``[\textrm{C}]`` -- `μ0` : vacuum magnetic permeability with unit ``[\textrm{N}\cdot\textrm{A}^{-2}]`` -- `ϵ0` : vacuum electric permittivity with unit ``[\textrm{F}\cdot\textrm{m}^{-1}]`` -- `k` : (exact) Boltzmann constant with unit ``[\textrm{J}\cdot\textrm{K}^{-1}]`` -- `NA` : (exact) Avogadro constant with unit ``[\textrm{mol}^{-1}]`` - -# Examples - -```jldoctest -julia> PhysicalConstants.ħ -1.0545718176461565e-34 -``` -""" -const PhysicalConstants = ( - c = 299792458.0, - G = 6.6743e-11, - h = 6.62607015e-34, - ħ = 6.62607015e-34 / (2 * π), - e = 1.602176634e-19, - μ0 = 1.25663706127e-6, - ϵ0 = 8.8541878188e-12, - k = 1.380649e-23, - NA = 6.02214076e23, -) - -# common energy units (the values below are all in the unit of Joule) -const _energy_units::Dict{Symbol, Float64} = Dict( - :J => 1.0, - :eV => PhysicalConstants.e, - :meV => 1.0e-3 * PhysicalConstants.e, - :MHz => 1.0e6 * PhysicalConstants.h, - :GHz => 1.0e9 * PhysicalConstants.h, - :K => PhysicalConstants.k, - :mK => 1.0e-3 * PhysicalConstants.k, -) - -@doc raw""" - convert_unit(value::Real, unit1::Symbol, unit2::Symbol) - -Convert the energy `value` from `unit1` to `unit2`. The `unit1` and `unit2` can be either the following `Symbol`: -- `:J` : Joule -- `:eV` : electron volt -- `:meV` : milli-electron volt -- `:MHz` : Mega-Hertz multiplied by Planck constant ``h`` -- `:GHz` : Giga-Hertz multiplied by Planck constant ``h`` -- `:K` : Kelvin multiplied by Boltzmann constant ``k`` -- `:mK` : milli-Kelvin multiplied by Boltzmann constant ``k`` - -Note that we use the values stored in [`PhysicalConstants`](@ref) to do the conversion. - -# Examples - -```jldoctest -julia> convert_unit(1, :eV, :J) -1.602176634e-19 - -julia> convert_unit(1, :GHz, :J) -6.62607015e-25 - -julia> round(convert_unit(1, :meV, :mK), digits=4) -11604.5181 -``` -""" -function convert_unit(value::T, unit1::Symbol, unit2::Symbol) where {T <: Real} - !haskey(_energy_units, unit1) && throw(ArgumentError("Invalid unit :$(unit1)")) - !haskey(_energy_units, unit2) && throw(ArgumentError("Invalid unit :$(unit2)")) - return _float_type(T)(value * (_energy_units[unit1] / _energy_units[unit2])) -end - -get_typename_wrapper(A) = Base.typename(typeof(A)).wrapper - -_dense_similar(A::AbstractArray, args...) = similar(A, args...) -_dense_similar(A::AbstractSparseMatrix, args...) = similar(nonzeros(A), args...) - -_sparse_similar(A::AbstractArray, args...) = sparse(args...) - -_Ginibre_ensemble(rng::AbstractRNG, ::Type{T}, n::Int, rank::Int = n) where {T <: Complex} = randn(rng, T, n, rank) / sqrt(T(n)) - -_Boltzmann_weight(β::T, E::Int) where {T <: Real} = (E != 0 || isfinite(β)) ? exp(-β * E) : one(T) - -makeVal(x::Val{T}) where {T} = x -makeVal(x) = Val(x) - -getVal(x::Val{T}) where {T} = T -getVal(x) = x # getVal for any other type - -_non_static_array_warning(argname, arg::Tuple{}) = - throw(ArgumentError("The argument $argname must be a Tuple or a StaticVector of non-zero length.")) -_non_static_array_warning(argname, arg::Union{SVector{N, T}, MVector{N, T}, NTuple{N, T}}) where {N, T} = nothing -_non_static_array_warning(argname, arg::AbstractVector{T}) where {T} = - @warn "The argument $argname should be a Tuple or a StaticVector for better performance. Try to use `$argname = $(Tuple(arg))` instead of `$argname = $arg`. " * - "Alternatively, you can do `import QuantumToolbox: SVector` " * - "and use `$argname = SVector(" * - join(arg, ", ") * - ")`." maxlog = 1 - -# lazy tensor warning -for AType in (:AbstractArray, :AbstractSciMLOperator) - for BType in (:AbstractArray, :AbstractSciMLOperator) - if AType == BType == :AbstractArray - @eval begin - _lazy_tensor_warning(::$AType, ::$BType) = nothing - end - else - @eval begin - _lazy_tensor_warning(A::$AType, B::$BType) = - @warn "using lazy tensor (which can hurt performance) between data types: $(get_typename_wrapper(A)) and $(get_typename_wrapper(B))" - end - end - end -end - -# alias of abstract types -const FloatOrComplex = Union{AbstractFloat, Complex} - -# functions for getting Float or Complex element type -_float_type(::AbstractArray{T}) where {T <: Number} = _float_type(T) -_float_type(::AbstractSciMLOperator{T}) where {T <: Number} = _float_type(T) -_float_type(::Type{Int32}) = Float32 -_float_type(::Type{Int64}) = Float64 -_float_type(::Type{Complex{Int32}}) = Float32 -_float_type(::Type{Complex{Int64}}) = Float64 -_float_type(::Type{Complex{T}}) where {T <: Real} = T -_float_type(T::Type{<:AbstractFloat}) = T # Allow other untracked Real types, like ForwardDiff.Dual -_complex_float_type(::AbstractArray{T}) where {T <: Number} = _complex_float_type(T) -_complex_float_type(::AbstractSciMLOperator{T}) where {T <: Number} = _complex_float_type(T) -_complex_float_type(::Type{Int32}) = ComplexF32 -_complex_float_type(::Type{Int64}) = ComplexF64 -_complex_float_type(::Type{Float32}) = ComplexF32 -_complex_float_type(::Type{Float64}) = ComplexF64 -_complex_float_type(::Type{Complex{Int32}}) = ComplexF32 -_complex_float_type(::Type{Complex{Int64}}) = ComplexF64 -_complex_float_type(::Type{Complex{Float32}}) = ComplexF32 -_complex_float_type(::Type{Complex{Float64}}) = ComplexF64 -_complex_float_type(T::Type{<:AbstractFloat}) = Complex{T} # Allow other untracked Complex types, like ForwardDiff.Dual -_complex_float_type(T::Type{<:Complex}) = T # Allow other untracked Complex types, like ForwardDiff.Dual - -_convert_eltype_wordsize(::Type{T}, ::Val{64}) where {T <: Int} = Int64 -_convert_eltype_wordsize(::Type{T}, ::Val{32}) where {T <: Int} = Int32 -_convert_eltype_wordsize(::Type{T}, ::Val{64}) where {T <: AbstractFloat} = Float64 -_convert_eltype_wordsize(::Type{T}, ::Val{32}) where {T <: AbstractFloat} = Float32 -_convert_eltype_wordsize(::Type{Complex{T}}, ::Val{64}) where {T <: Union{Int, AbstractFloat}} = ComplexF64 -_convert_eltype_wordsize(::Type{Complex{T}}, ::Val{32}) where {T <: Union{Int, AbstractFloat}} = ComplexF32 diff --git a/src/versioninfo.jl b/src/versioninfo.jl index 36a5fc584..4a99ddc26 100644 --- a/src/versioninfo.jl +++ b/src/versioninfo.jl @@ -22,6 +22,7 @@ function versioninfo(io::IO = stdout) # print package information pkg_tuple = ( QuantumToolbox, + QuantumToolboxUtils, SciMLOperators, LinearSolve, OrdinaryDiffEqCore, diff --git a/test/core-test/cite.jl b/test/core-test/cite.jl new file mode 100644 index 000000000..d1dc6dc83 --- /dev/null +++ b/test/core-test/cite.jl @@ -0,0 +1,21 @@ +@testitem "Cite" begin + + # citation bibtex + io_buffer = IOBuffer() + QuantumToolbox.cite(io_buffer) + captured_output = String(take!(io_buffer)) + @test captured_output == + """@article{QuantumToolbox.jl2025,\n""" * + """ title = {Quantum{T}oolbox.jl: {A}n efficient {J}ulia framework for simulating open quantum systems},\n""" * + """ author = {Mercurio, Alberto and Huang, Yi-Te and Cai, Li-Xun and Chen, Yueh-Nan and Savona, Vincenzo and Nori, Franco},\n""" * + """ journal = {{Quantum}},\n""" * + """ issn = {2521-327X},\n""" * + """ publisher = {{Verein zur F{\\"{o}}rderung des Open Access Publizierens in den Quantenwissenschaften}},\n""" * + """ volume = {9},\n""" * + """ pages = {1866},\n""" * + """ month = sep,\n""" * + """ year = {2025},\n""" * + """ doi = {10.22331/q-2025-09-29-1866},\n""" * + """ url = {https://doi.org/10.22331/q-2025-09-29-1866}\n""" * + """}\n""" +end diff --git a/test/core-test/utilities.jl b/test/core-test/utilities.jl deleted file mode 100644 index e0cdf96e1..000000000 --- a/test/core-test/utilities.jl +++ /dev/null @@ -1,77 +0,0 @@ -@testitem "Utilities" begin - - # citation bibtex - io_buffer = IOBuffer() - QuantumToolbox.cite(io_buffer) - captured_output = String(take!(io_buffer)) - @test captured_output == - """@article{QuantumToolbox.jl2025,\n""" * - """ title = {Quantum{T}oolbox.jl: {A}n efficient {J}ulia framework for simulating open quantum systems},\n""" * - """ author = {Mercurio, Alberto and Huang, Yi-Te and Cai, Li-Xun and Chen, Yueh-Nan and Savona, Vincenzo and Nori, Franco},\n""" * - """ journal = {{Quantum}},\n""" * - """ issn = {2521-327X},\n""" * - """ publisher = {{Verein zur F{\\"{o}}rderung des Open Access Publizierens in den Quantenwissenschaften}},\n""" * - """ volume = {9},\n""" * - """ pages = {1866},\n""" * - """ month = sep,\n""" * - """ year = {2025},\n""" * - """ doi = {10.22331/q-2025-09-29-1866},\n""" * - """ url = {https://doi.org/10.22331/q-2025-09-29-1866}\n""" * - """}\n""" - - @testset "n_thermal" begin - ω1 = rand(Float64) - ω2 = rand(Float64) - @test n_thermal(0, ω2) == 0.0 - @test n_thermal(ω1, 0) == 0.0 - @test n_thermal(ω1, -ω2) == 0.0 - @test n_thermal(ω1, ω2) == 1 / (exp(ω1 / ω2) - 1) - @test typeof(n_thermal(Int32(2), Int32(3))) == Float32 - @test typeof(n_thermal(Float32(2), Float32(3))) == Float32 - @test typeof(n_thermal(Int64(2), Int32(3))) == Float64 - @test typeof(n_thermal(Int32(2), Int64(3))) == Float64 - @test typeof(n_thermal(Float64(2), Float32(3))) == Float64 - @test typeof(n_thermal(Float32(2), Float64(3))) == Float64 - end - - @testset "CODATA Physical Constants" begin - c = PhysicalConstants.c - h = PhysicalConstants.h - ħ = PhysicalConstants.ħ - μ0 = PhysicalConstants.μ0 - ϵ0 = PhysicalConstants.ϵ0 - - @test h / ħ ≈ 2 * π - @test μ0 / (4.0e-7 * π) ≈ 1.0 - @test c^2 * μ0 * ϵ0 ≈ 1.0 - end - - @testset "convert unit" begin - V = 100 * rand(Float64) - _unit_list = [:J, :eV, :meV, :MHz, :GHz, :K, :mK] - for origin in _unit_list - for middle in _unit_list - for target in _unit_list - V_middle = convert_unit(V, origin, middle) - V_target = convert_unit(V_middle, middle, target) - V_origin = convert_unit(V_target, target, origin) - @test V ≈ V_origin - end - end - end - @test_throws ArgumentError convert_unit(V, :bad_unit, :J) - @test_throws ArgumentError convert_unit(V, :J, :bad_unit) - end - - @testset "Type Inference" begin - v1 = rand(Float64) - @inferred n_thermal(v1, Int32(123)) - - _unit_list = [:J, :eV, :meV, :GHz, :mK] - for u1 in _unit_list - for u2 in _unit_list - @inferred convert_unit(v1, u1, u2) - end - end - end -end From 3132a756dfce828f45f61c4878633da1f3af609a Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Fri, 10 Apr 2026 09:27:40 +0900 Subject: [PATCH 02/41] fix CI for `julia < 1.11` --- .github/workflows/CI.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 791b4e47f..94bd66250 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -87,6 +87,20 @@ jobs: arch: ${{ matrix.node.arch }} - uses: julia-actions/cache@v3 - uses: julia-actions/julia-buildpkg@v1 + - name: Dev local libs for Julia < 1.11 + shell: bash + run: | + julia --project=. -e ' + using Pkg + if VERSION < v"1.11" + for lib in readdir("lib"; join=true) + isdir(lib) || continue + isfile(joinpath(lib, "Project.toml")) || continue + Pkg.develop(path=lib) + end + end + Pkg.instantiate() + ' - uses: julia-actions/julia-runtest@v1 env: GROUP: ${{ matrix.group }} From 70d9fbaf388d36436f3f74aeebd9b95c4adac5de Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Fri, 10 Apr 2026 12:53:37 +0900 Subject: [PATCH 03/41] fix CI --- .github/workflows/CI.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 94bd66250..46071d8f4 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -86,7 +86,6 @@ jobs: version: ${{ matrix.version }} arch: ${{ matrix.node.arch }} - uses: julia-actions/cache@v3 - - uses: julia-actions/julia-buildpkg@v1 - name: Dev local libs for Julia < 1.11 shell: bash run: | @@ -101,6 +100,7 @@ jobs: end Pkg.instantiate() ' + - uses: julia-actions/julia-buildpkg@v1 - uses: julia-actions/julia-runtest@v1 env: GROUP: ${{ matrix.group }} From e9c94d4727a445c72239c6b73c3c6776a42e8195 Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Fri, 10 Apr 2026 13:55:01 +0900 Subject: [PATCH 04/41] format files --- lib/QuantumToolboxUtils/src/PhysicalConstants.jl | 2 +- lib/QuantumToolboxUtils/src/QuantumToolboxUtils.jl | 2 +- lib/QuantumToolboxUtils/src/misc.jl | 2 +- src/QuantumToolbox.jl | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/QuantumToolboxUtils/src/PhysicalConstants.jl b/lib/QuantumToolboxUtils/src/PhysicalConstants.jl index c6fd8f366..f6730e229 100644 --- a/lib/QuantumToolboxUtils/src/PhysicalConstants.jl +++ b/lib/QuantumToolboxUtils/src/PhysicalConstants.jl @@ -77,4 +77,4 @@ function convert_unit(value::T, unit1::Symbol, unit2::Symbol) where {T <: Real} !haskey(_energy_units, unit1) && throw(ArgumentError("Invalid unit :$(unit1)")) !haskey(_energy_units, unit2) && throw(ArgumentError("Invalid unit :$(unit2)")) return _float_type(T)(value * (_energy_units[unit1] / _energy_units[unit2])) -end \ No newline at end of file +end diff --git a/lib/QuantumToolboxUtils/src/QuantumToolboxUtils.jl b/lib/QuantumToolboxUtils/src/QuantumToolboxUtils.jl index 0c8d8415f..18dd7bd5d 100644 --- a/lib/QuantumToolboxUtils/src/QuantumToolboxUtils.jl +++ b/lib/QuantumToolboxUtils/src/QuantumToolboxUtils.jl @@ -10,4 +10,4 @@ include("type_handle.jl") include("PhysicalConstants.jl") include("misc.jl") -end \ No newline at end of file +end diff --git a/lib/QuantumToolboxUtils/src/misc.jl b/lib/QuantumToolboxUtils/src/misc.jl index 38dc9139b..2a7c26b33 100644 --- a/lib/QuantumToolboxUtils/src/misc.jl +++ b/lib/QuantumToolboxUtils/src/misc.jl @@ -45,4 +45,4 @@ end _Ginibre_ensemble(rng::AbstractRNG, ::Type{T}, n::Int, rank::Int = n) where {T <: Complex} = randn(rng, T, n, rank) / sqrt(T(n)) -_Boltzmann_weight(β::T, E::Int) where {T <: Real} = (E != 0 || isfinite(β)) ? exp(-β * E) : one(T) \ No newline at end of file +_Boltzmann_weight(β::T, E::Int) where {T <: Real} = (E != 0 || isfinite(β)) ? exp(-β * E) : one(T) diff --git a/src/QuantumToolbox.jl b/src/QuantumToolbox.jl index e0be157a4..708d7ccf2 100644 --- a/src/QuantumToolbox.jl +++ b/src/QuantumToolbox.jl @@ -16,7 +16,7 @@ import Reexport: @reexport @reexport using QuantumToolboxUtils ## internal functions of QuantumToolbox libraries -import QuantumToolboxUtils: +import QuantumToolboxUtils: FloatOrComplex, getVal, makeVal, From bc727f581b295cc5265fe3d0148946479eec7bfa Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Fri, 10 Apr 2026 17:35:51 +0900 Subject: [PATCH 05/41] update bump version CI --- .github/workflows/bump-version.yml | 51 ++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/.github/workflows/bump-version.yml b/.github/workflows/bump-version.yml index 9b292ba4e..3ee6078ec 100644 --- a/.github/workflows/bump-version.yml +++ b/.github/workflows/bump-version.yml @@ -3,6 +3,14 @@ name: Bump Version on: workflow_dispatch: inputs: + package: + description: 'Package to bump' + required: true + default: 'QuantumToolbox' + type: choice + options: + - QuantumToolbox + - QuantumToolboxUtils bump_type: description: 'Version bump type' required: true @@ -37,12 +45,20 @@ jobs: julia -e ' using Pkg; Pkg.add("Changelog") using TOML, Dates, Changelog - project_file = "Project.toml" + package = ENV["PACKAGE"] + project_file = package == "QuantumToolbox" ? "Project.toml" : "lib/$(package)/Project.toml" changelog_file = "CHANGELOG.md" # --- PART 1: Calculate new version number --- + # the current version of QuantumToolbox + p_QT = TOML.parsefile("Project.toml") + v_QT = VersionNumber(p_QT["version"]) + + # the current version of selected package p = TOML.parsefile(project_file) v = VersionNumber(p["version"]) + + # the version bump type (major, minor, patch) type = ENV["BUMP_TYPE"] new_v = if type == "major" VersionNumber(v.major + 1, 0, 0) @@ -53,9 +69,10 @@ jobs: end # --- PART 2: Output version number to GitHub Actions variables --- - println("Bump version from v$v to v$new_v") + println("Bump $package version from v$v to v$new_v") open(ENV["GITHUB_OUTPUT"], "a") do io println(io, "new_version=$new_v") + println(io, "project_file=$project_file") end # --- PART 3: Update Project.toml (using Regex to preserve formatting) --- @@ -66,35 +83,43 @@ jobs: # --- PART 4: Update CHANGELOG.md --- content = read(changelog_file, String) - marker = "## [Unreleased](https://github.com/qutip/QuantumToolbox.jl/tree/main)" - insertion = "$marker\n\n\n\n## [v$new_v]\nRelease date: $(Dates.format(now(), "yyyy-mm-dd"))" - new_content = replace(content, marker => insertion) + + marker1 = "\n\n## [v$v_QT]" + insertion1 = "\nBump $package version to v$new_v\n$marker1" + new_content = replace(content, marker1 => insertion1) + + if package == "QuantumToolbox" + marker2 = "## [Unreleased](https://github.com/qutip/QuantumToolbox.jl/tree/main)" + insertion2 = "$marker2\n\n\n\n## [v$new_v]\nRelease date: $(Dates.format(now(), "yyyy-mm-dd"))" + new_content = replace(new_content, marker2 => insertion2) + end + write(changelog_file, new_content) Changelog.generate(Changelog.CommonMark(), changelog_file; repo = "qutip/QuantumToolbox.jl") println("Updated $changelog_file") ' env: + PACKAGE: ${{ inputs.package }} BUMP_TYPE: ${{ inputs.bump_type }} - name: Create Branch run: | git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" - - BRANCH_NAME="bump-to-${{ steps.updates.outputs.new_version }}" + + BRANCH_NAME="bump-${{ inputs.package }}-version-to-v${{ steps.updates.outputs.new_version }}" git checkout -b $BRANCH_NAME - git add Project.toml CHANGELOG.md - git commit -m "[no ci] Bump version to v${{ steps.updates.outputs.new_version }}" + git add "${{ steps.updates.outputs.project_file }}" CHANGELOG.md + git commit -m "[no ci] Bump ${{ inputs.package }}.jl version to v${{ steps.updates.outputs.new_version }}" git push origin $BRANCH_NAME - name: Create Pull Request env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - BRANCH_NAME="bump-to-${{ steps.updates.outputs.new_version }}" + BRANCH_NAME="bump-${{ inputs.package }}-version-to-v${{ steps.updates.outputs.new_version }}" gh pr create \ --base main \ --head $BRANCH_NAME \ - --title "Bump version to v${{ steps.updates.outputs.new_version }}" \ - --body "This PR bumps the package version to v${{ steps.updates.outputs.new_version }} and updates CHANGELOG.md." \ - --label "Skip ChangeLog" + --title "Bump ${{ inputs.package }} version to v${{ steps.updates.outputs.new_version }}" \ + --body "This PR bumps ${{ inputs.package }} version to v${{ steps.updates.outputs.new_version }} and updates CHANGELOG.md." From 2b53dbae883750fcf317c4862f132ea86b0de697 Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Fri, 10 Apr 2026 17:36:07 +0900 Subject: [PATCH 06/41] update bump version CI --- .github/workflows/bump-version.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/bump-version.yml b/.github/workflows/bump-version.yml index 3ee6078ec..e7116c077 100644 --- a/.github/workflows/bump-version.yml +++ b/.github/workflows/bump-version.yml @@ -85,7 +85,7 @@ jobs: content = read(changelog_file, String) marker1 = "\n\n## [v$v_QT]" - insertion1 = "\nBump $package version to v$new_v\n$marker1" + insertion1 = "\n- Bump $package version to v$new_v\n$marker1" new_content = replace(content, marker1 => insertion1) if package == "QuantumToolbox" From 80a5b3a9bc02d6f71f5282a5a5ac0cfa4a7fed45 Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Thu, 16 Apr 2026 15:06:16 +0900 Subject: [PATCH 07/41] fix CI pipelines --- .buildkite/CUDA_Ext.yml | 28 +++++++++++++++++ .buildkite/pipeline.yml | 1 + .github/workflows/Benchmarks.yml | 2 ++ .github/workflows/CI-Julia-nightly.yml | 2 ++ .github/workflows/CI.yml | 10 +++--- .github/workflows/Code-Quality.yml | 18 ++++++++++- .github/workflows/bump-version.yml | 42 ++++++++++++++++++++++++-- .github/workflows/documentation.yml | 1 + 8 files changed, 96 insertions(+), 8 deletions(-) diff --git a/.buildkite/CUDA_Ext.yml b/.buildkite/CUDA_Ext.yml index 40a80d6e5..840638bb3 100644 --- a/.buildkite/CUDA_Ext.yml +++ b/.buildkite/CUDA_Ext.yml @@ -1,4 +1,31 @@ steps: + # Julia 1.10 doesn't support [sources] in Project.toml, + # so we need to manually dev workspace packages before instantiating. + - label: "Dev local libs for Julia < 1.11" + plugins: + - JuliaCI/julia#v1: + version: "1.10" + - JuliaCI/julia-coverage#v1: + dirs: + - src + - lib + - ext + agents: + queue: "juliagpu" + cuda: "*" + commands: | + julia --project=. -e ' + using Pkg + if VERSION < v"1.11" + for lib in readdir("lib"; join=true) + isdir(lib) || continue + isfile(joinpath(lib, "Project.toml")) || continue + Pkg.develop(path=lib) + end + end + Pkg.instantiate() + ' + - label: "CUDA Julia {{matrix.version}}" matrix: setup: @@ -14,6 +41,7 @@ steps: codecov: true dirs: - src + - lib - ext agents: queue: "juliagpu" diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 36199fd77..b4e69a8dd 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -18,6 +18,7 @@ steps: - ".buildkite/pipeline.yml" - ".buildkite/CUDA_Ext.yml" - "src/**" + - "lib/**" - "ext/QuantumToolboxCUDAExt.jl" - "test/runtests.jl" - "test/ext-test/gpu/**" diff --git a/.github/workflows/Benchmarks.yml b/.github/workflows/Benchmarks.yml index 5592d8c27..d73c8b337 100644 --- a/.github/workflows/Benchmarks.yml +++ b/.github/workflows/Benchmarks.yml @@ -6,6 +6,7 @@ on: paths: - '.github/workflows/Benchmarks.yml' - 'src/**' + - 'lib/**' - 'ext/**' - 'benchmarks/**' - 'Project.toml' @@ -15,6 +16,7 @@ on: paths: - '.github/workflows/Benchmarks.yml' - 'src/**' + - 'lib/**' - 'ext/**' - 'benchmarks/**' - 'Project.toml' diff --git a/.github/workflows/CI-Julia-nightly.yml b/.github/workflows/CI-Julia-nightly.yml index dede3beb5..1baf9f69c 100644 --- a/.github/workflows/CI-Julia-nightly.yml +++ b/.github/workflows/CI-Julia-nightly.yml @@ -7,6 +7,7 @@ on: paths: - '.github/workflows/CI-Julia-nightly.yml' - 'src/**' + - 'lib/**' - 'ext/**' - 'test/runtests.jl' - 'test/core-test/**' @@ -17,6 +18,7 @@ on: paths: - '.github/workflows/CI-Julia-nightly.yml' - 'src/**' + - 'lib/**' - 'ext/**' - 'test/runtests.jl' - 'test/core-test/**' diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 46071d8f4..cbc09b442 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -7,6 +7,7 @@ on: paths: - '.github/workflows/CI.yml' - 'src/**' + - 'lib/**' - 'ext/**' - 'test/runtests.jl' - 'test/core-test/**' @@ -18,6 +19,7 @@ on: paths: - '.github/workflows/CI.yml' - 'src/**' + - 'lib/**' - 'ext/**' - 'test/runtests.jl' - 'test/core-test/**' @@ -92,10 +94,10 @@ jobs: julia --project=. -e ' using Pkg if VERSION < v"1.11" - for lib in readdir("lib"; join=true) - isdir(lib) || continue - isfile(joinpath(lib, "Project.toml")) || continue - Pkg.develop(path=lib) + for lib in readdir("lib"; join=true) + isdir(lib) || continue + isfile(joinpath(lib, "Project.toml")) || continue + Pkg.develop(path=lib) end end Pkg.instantiate() diff --git a/.github/workflows/Code-Quality.yml b/.github/workflows/Code-Quality.yml index f6a4aba9a..aed7a1d9a 100644 --- a/.github/workflows/Code-Quality.yml +++ b/.github/workflows/Code-Quality.yml @@ -7,6 +7,7 @@ on: paths: - '.github/workflows/Code-Quality.yml' - 'src/**' + - 'lib/**' - 'ext/**' - 'test/runtests.jl' - 'test/core-test/**' @@ -17,6 +18,7 @@ on: paths: - '.github/workflows/Code-Quality.yml' - 'src/**' + - 'lib/**' - 'ext/**' - 'test/runtests.jl' - 'test/core-test/**' @@ -39,7 +41,7 @@ jobs: fail-fast: false matrix: version: - - 'lts' + - '1.10' # oldest - '1' os: - 'ubuntu-latest' @@ -55,6 +57,20 @@ jobs: version: ${{ matrix.version }} arch: ${{ matrix.arch }} - uses: julia-actions/cache@v3 + - name: Dev local libs for Julia < 1.11 + shell: bash + run: | + julia --project=. -e ' + using Pkg + if VERSION < v"1.11" + for lib in readdir("lib"; join=true) + isdir(lib) || continue + isfile(joinpath(lib, "Project.toml")) || continue + Pkg.develop(path=lib) + end + end + Pkg.instantiate() + ' - uses: julia-actions/julia-buildpkg@v1 - uses: julia-actions/julia-runtest@v1 env: diff --git a/.github/workflows/bump-version.yml b/.github/workflows/bump-version.yml index e7116c077..09669637f 100644 --- a/.github/workflows/bump-version.yml +++ b/.github/workflows/bump-version.yml @@ -85,7 +85,7 @@ jobs: content = read(changelog_file, String) marker1 = "\n\n## [v$v_QT]" - insertion1 = "\n- Bump $package version to v$new_v\n$marker1" + insertion1 = "\n- Bump $package version to `v$new_v`.\n$marker1" new_content = replace(content, marker1 => insertion1) if package == "QuantumToolbox" @@ -114,12 +114,48 @@ jobs: git push origin $BRANCH_NAME - name: Create Pull Request + id: create_pr env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | BRANCH_NAME="bump-${{ inputs.package }}-version-to-v${{ steps.updates.outputs.new_version }}" - gh pr create \ + PR_URL=$(gh pr create \ --base main \ --head $BRANCH_NAME \ --title "Bump ${{ inputs.package }} version to v${{ steps.updates.outputs.new_version }}" \ - --body "This PR bumps ${{ inputs.package }} version to v${{ steps.updates.outputs.new_version }} and updates CHANGELOG.md." + --body "This PR bumps ${{ inputs.package }} version to v${{ steps.updates.outputs.new_version }} and updates CHANGELOG.md.") + + PR_NUMBER="${PR_URL##*/}" + + echo "Created PR: $PR_URL" + { + echo "pr_url=$PR_URL" + echo "pr_number=$PR_NUMBER" + } >> "$GITHUB_OUTPUT" + + - name: Update CHANGELOG with PR number + run: | + julia -e ' + using Pkg; Pkg.add("Changelog") + using Changelog + + package = ENV["PACKAGE"] + new_v = ENV["NEW_VERSION"] + pr_number = ENV["PR_NUMBER"] + changelog_file = "CHANGELOG.md" + + content = read(changelog_file, String) + old_entry = "- Bump $package version to `v$new_v`." + new_entry = "$old_entry ([#$pr_number])" + + write(changelog_file, replace(content, old_entry => new_entry)) + Changelog.generate(Changelog.CommonMark(), changelog_file; repo = "qutip/QuantumToolbox.jl") + ' + + git add CHANGELOG.md + git commit -m "[no ci] Add PR reference to CHANGELOG" + git push origin "bump-${{ inputs.package }}-version-to-v${{ steps.updates.outputs.new_version }}" + env: + PACKAGE: ${{ inputs.package }} + NEW_VERSION: ${{ steps.updates.outputs.new_version }} + PR_NUMBER: ${{ steps.create_pr.outputs.pr_number }} diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index 44b46e391..141240a6f 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -12,6 +12,7 @@ on: paths: - '.github/workflows/documentation.yml' - 'src/**' + - 'lib/**' - 'ext/**' - 'docs/**' - 'Project.toml' From 698727220d130d0be3f076e97a922887119107f5 Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Thu, 16 Apr 2026 15:47:09 +0900 Subject: [PATCH 08/41] fix CUDA CI pipeline --- .buildkite/CUDA_Ext.yml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/.buildkite/CUDA_Ext.yml b/.buildkite/CUDA_Ext.yml index 840638bb3..ebc2d0a4a 100644 --- a/.buildkite/CUDA_Ext.yml +++ b/.buildkite/CUDA_Ext.yml @@ -1,11 +1,12 @@ steps: # Julia 1.10 doesn't support [sources] in Project.toml, # so we need to manually dev workspace packages before instantiating. - - label: "Dev local libs for Julia < 1.11" + - label: "CUDA Julia 1.10" plugins: - JuliaCI/julia#v1: version: "1.10" - JuliaCI/julia-coverage#v1: + codecov: true dirs: - src - lib @@ -23,14 +24,18 @@ steps: Pkg.develop(path=lib) end end - Pkg.instantiate() + Pkg.test(; test_args=["--quickfail"]) ' + env: + GROUP: "CUDA_Ext" + SECRET_CODECOV_TOKEN: "ZfhQu/IcRLqNyZ//ZNs5sjBPaV76IHfU5gui52Qn+Rp8tOurukqgScuyDt+3HQ4R0hJYBw1/Nqg6jmBsvWSc9NEUx8kGsUJFHfN3no0+b+PFxA8oJkWc9EpyIsjht5ZIjlsFWR3f0DpPqMEle/QyWOPcal63CChXR8oAoR+Fz1Bh8GkokLlnC8F9Ugp9xBlu401GCbyZhvLTZnNIgK5yy9q8HBJnBg1cPOhI81J6JvYpEmcIofEzFV/qkfpTUPclu43WNoFX2DZPzbxilf3fsAd5/+nRkRfkNML8KiN4mnmjHxPPbuY8F5zC/PS5ybXtDpfvaMQc01WApXCkZk0ZAQ==;U2FsdGVkX1+eDT7dqCME5+Ox5i8GvWRTQbwiP/VYjapThDbxXFDeSSIC6Opmon+M8go22Bun3bat6Fzie65ang==" + timeout_in_minutes: 60 - label: "CUDA Julia {{matrix.version}}" matrix: setup: version: - - "1.10" # oldest + - "1.11" # oldest - "1" # latest plugins: - JuliaCI/julia#v1: From 93e042d0f843ed7b4c0ceae6574aad3f1a1a0ff4 Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Thu, 16 Apr 2026 15:47:27 +0900 Subject: [PATCH 09/41] add code quality test for lib --- lib/QuantumToolboxUtils/test/code_quality.jl | 9 +++++++++ test/core-test/code-quality/code_quality.jl | 2 +- test/runtests.jl | 8 ++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 lib/QuantumToolboxUtils/test/code_quality.jl diff --git a/lib/QuantumToolboxUtils/test/code_quality.jl b/lib/QuantumToolboxUtils/test/code_quality.jl new file mode 100644 index 000000000..c31a5cb8f --- /dev/null +++ b/lib/QuantumToolboxUtils/test/code_quality.jl @@ -0,0 +1,9 @@ +@testset "Code quality (QuantumToolboxUtils)" verbose = true begin + @testset "Aqua.jl" begin + Aqua.test_all(QuantumToolboxUtils; ambiguities = false, unbound_args = false) + end + + @testset "JET.jl" begin + JET.test_package(QuantumToolboxUtils; target_modules = (QuantumToolboxUtils,), ignore_missing_comparison = true) + end +end diff --git a/test/core-test/code-quality/code_quality.jl b/test/core-test/code-quality/code_quality.jl index 5effb97d1..5dde51b6e 100644 --- a/test/core-test/code-quality/code_quality.jl +++ b/test/core-test/code-quality/code_quality.jl @@ -1,4 +1,4 @@ -@testset "Code quality" verbose = true begin +@testset "Code quality (QuantumToolbox)" verbose = true begin @testset "Aqua.jl" begin Aqua.test_all(QuantumToolbox; ambiguities = false, unbound_args = false) end diff --git a/test/runtests.jl b/test/runtests.jl index 3cad44db2..573534502 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -4,6 +4,11 @@ using Pkg const testdir = dirname(@__FILE__) +# Define the paths to the library +const LIBRARY_PATHS = Dict( + "QuantumToolboxUtils" => joinpath(testdir, "..", "lib", "QuantumToolboxUtils"), +) + # Define the paths to the extension tests const EXTENSION_PATHS = Dict( "AutoDiff_Ext" => joinpath(testdir, "ext-test", "cpu", "autodiff"), @@ -57,6 +62,9 @@ if (GROUP == "All") || (GROUP == "Code-Quality") (GROUP == "Code-Quality") && QuantumToolbox.about() # print version info. for code quality CI in GitHub + for (lib_name, lib_path) in LIBRARY_PATHS + include(joinpath(lib_path, "test", "code_quality.jl")) + end include(joinpath(path, "code_quality.jl")) end From fccffd865c827c750ee0e78a2093166569d8ecc4 Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Thu, 16 Apr 2026 16:21:10 +0900 Subject: [PATCH 10/41] fix docs --- Makefile | 3 +-- docs/Project.toml | 5 +++++ docs/make.jl | 12 +++++------- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 7e59b10a7..553b69ad8 100644 --- a/Makefile +++ b/Makefile @@ -16,8 +16,7 @@ test: ${JULIA} --project -e 'using Pkg; Pkg.update(); Pkg.test()' docs: - ${JULIA} --project=docs -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.update()' - ${JULIA} --project=docs docs/make.jl + ${JULIA} --project=docs -e 'using Pkg; Pkg.update(); include("docs/make.jl")' vitepress: npm --prefix docs run docs:dev diff --git a/docs/Project.toml b/docs/Project.toml index 57a8c133b..6af8c6a5c 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -8,7 +8,12 @@ DocumenterVitepress = "4710194d-e776-4893-9690-8d956a29c365" ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" Mooncake = "da2b9cff-9c12-43a0-ae48-6db2b0edb7d6" QuantumToolbox = "6c2fb7c5-b903-41d2-bc5e-5a7c320b9fab" +QuantumToolboxUtils = "02afad9e-e2b8-4f9a-965f-b5dca5b538ca" SciMLSensitivity = "1ed8b502-d754-442c-8d5d-10ac956f44a1" +[sources] +QuantumToolbox = {path = ".."} +QuantumToolboxUtils = {path = "../lib/QuantumToolboxUtils"} + [compat] DocumenterVitepress = "0.3" diff --git a/docs/make.jl b/docs/make.jl index 6f8a0f930..08be90710 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -7,17 +7,15 @@ using Changelog # Load of packages required to compile the extension documentation using CairoMakie -doctest_setup = quote - using LinearAlgebra - using SparseArrays - using QuantumToolbox -end -DocMeta.setdocmeta!(QuantumToolbox, :DocTestSetup, doctest_setup; recursive = true) - # some options for `makedocs` const DRAFT = get(ENV, "DRAFT", false) == "true" # `DRAFT = true` disables cell evaluation const DOCTEST = get(ENV, "DOCTEST", true) == true # `DOCTEST = false` skips doc tests +if DOCTEST + DocMeta.setdocmeta!(QuantumToolboxUtils, :DocTestSetup, :(using QuantumToolboxUtils); recursive = true) + DocMeta.setdocmeta!(QuantumToolbox, :DocTestSetup, :(using QuantumToolbox, LinearAlgebra, SparseArrays); recursive = true) +end + # generate bibliography bib = CitationBibliography( joinpath(@__DIR__, "src", "resources", "bibliography.bib"), From e2b1cb25fbd7e56a5d5735707d98f8cc65d9020f Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Thu, 16 Apr 2026 17:26:46 +0900 Subject: [PATCH 11/41] fix code quality tests --- .github/workflows/Code-Quality.yml | 4 +--- test/core-test/code-quality/Project.toml | 4 ++++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/Code-Quality.yml b/.github/workflows/Code-Quality.yml index aed7a1d9a..be790d80f 100644 --- a/.github/workflows/Code-Quality.yml +++ b/.github/workflows/Code-Quality.yml @@ -47,8 +47,6 @@ jobs: - 'ubuntu-latest' arch: - 'x64' - group: - - 'Code-Quality' steps: - uses: actions/checkout@v6 @@ -74,4 +72,4 @@ jobs: - uses: julia-actions/julia-buildpkg@v1 - uses: julia-actions/julia-runtest@v1 env: - GROUP: ${{ matrix.group }} + GROUP: 'Code-Quality' diff --git a/test/core-test/code-quality/Project.toml b/test/core-test/code-quality/Project.toml index d71385453..e0b7dfea8 100644 --- a/test/core-test/code-quality/Project.toml +++ b/test/core-test/code-quality/Project.toml @@ -2,8 +2,12 @@ Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595" JET = "c3a54625-cd67-489e-a8e7-0a5a0ff4e31b" QuantumToolbox = "6c2fb7c5-b903-41d2-bc5e-5a7c320b9fab" +QuantumToolboxUtils = "02afad9e-e2b8-4f9a-965f-b5dca5b538ca" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" +[sources] +QuantumToolboxUtils = {path = "../../../lib/QuantumToolboxUtils"} + [compat] Aqua = "0.8" JET = "0.9, 0.10, 0.11" From 31328c09563baba72541cb74174c8ca9e8a61876 Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Thu, 16 Apr 2026 18:14:34 +0900 Subject: [PATCH 12/41] fix code quality CI --- .github/workflows/Code-Quality.yml | 14 -------------- test/runtests.jl | 9 +++++++-- 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/.github/workflows/Code-Quality.yml b/.github/workflows/Code-Quality.yml index be790d80f..fca13b529 100644 --- a/.github/workflows/Code-Quality.yml +++ b/.github/workflows/Code-Quality.yml @@ -55,20 +55,6 @@ jobs: version: ${{ matrix.version }} arch: ${{ matrix.arch }} - uses: julia-actions/cache@v3 - - name: Dev local libs for Julia < 1.11 - shell: bash - run: | - julia --project=. -e ' - using Pkg - if VERSION < v"1.11" - for lib in readdir("lib"; join=true) - isdir(lib) || continue - isfile(joinpath(lib, "Project.toml")) || continue - Pkg.develop(path=lib) - end - end - Pkg.instantiate() - ' - uses: julia-actions/julia-buildpkg@v1 - uses: julia-actions/julia-runtest@v1 env: diff --git a/test/runtests.jl b/test/runtests.jl index 573534502..18b760bbd 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -5,8 +5,8 @@ using Pkg const testdir = dirname(@__FILE__) # Define the paths to the library -const LIBRARY_PATHS = Dict( - "QuantumToolboxUtils" => joinpath(testdir, "..", "lib", "QuantumToolboxUtils"), +const LIBRARY_PATHS = ( + joinpath(testdir, "..", "lib", "QuantumToolboxUtils"), ) # Define the paths to the extension tests @@ -31,6 +31,11 @@ const GROUP_LIST = String[ # function to set up the environment for subtests function setup_subtest_env(path::String) Pkg.activate(path) + if VERSION < v"1.11" + for lib in LIBRARY_PATHS + Pkg.develop(path=lib) + end + end Pkg.develop(PackageSpec(path = dirname(@__DIR__))) Pkg.update() return nothing From 9140aa4bf71b131936dd1927a3784e1879909746 Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Fri, 17 Apr 2026 11:38:57 +0900 Subject: [PATCH 13/41] fix code quality test --- test/runtests.jl | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index 18b760bbd..8f71c8fd0 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -32,8 +32,8 @@ const GROUP_LIST = String[ function setup_subtest_env(path::String) Pkg.activate(path) if VERSION < v"1.11" - for lib in LIBRARY_PATHS - Pkg.develop(path=lib) + for lib_path in LIBRARY_PATHS + Pkg.develop(path=lib_path) end end Pkg.develop(PackageSpec(path = dirname(@__DIR__))) @@ -67,7 +67,8 @@ if (GROUP == "All") || (GROUP == "Code-Quality") (GROUP == "Code-Quality") && QuantumToolbox.about() # print version info. for code quality CI in GitHub - for (lib_name, lib_path) in LIBRARY_PATHS + # run code quality tests for all libraries and the main package + for lib_path in LIBRARY_PATHS include(joinpath(lib_path, "test", "code_quality.jl")) end include(joinpath(path, "code_quality.jl")) From 196d16d4b91f25623b992bf2a1e36cf61d1de5a9 Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Fri, 17 Apr 2026 13:51:10 +0900 Subject: [PATCH 14/41] fix code quality test --- .github/workflows/Code-Quality.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.github/workflows/Code-Quality.yml b/.github/workflows/Code-Quality.yml index fca13b529..be790d80f 100644 --- a/.github/workflows/Code-Quality.yml +++ b/.github/workflows/Code-Quality.yml @@ -55,6 +55,20 @@ jobs: version: ${{ matrix.version }} arch: ${{ matrix.arch }} - uses: julia-actions/cache@v3 + - name: Dev local libs for Julia < 1.11 + shell: bash + run: | + julia --project=. -e ' + using Pkg + if VERSION < v"1.11" + for lib in readdir("lib"; join=true) + isdir(lib) || continue + isfile(joinpath(lib, "Project.toml")) || continue + Pkg.develop(path=lib) + end + end + Pkg.instantiate() + ' - uses: julia-actions/julia-buildpkg@v1 - uses: julia-actions/julia-runtest@v1 env: From 07cc9b430b3ed88f5aeeb46b0878aebef406cfb9 Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Wed, 22 Apr 2026 10:39:31 +0900 Subject: [PATCH 15/41] format files --- test/runtests.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/runtests.jl b/test/runtests.jl index 8f71c8fd0..65174638c 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -33,7 +33,7 @@ function setup_subtest_env(path::String) Pkg.activate(path) if VERSION < v"1.11" for lib_path in LIBRARY_PATHS - Pkg.develop(path=lib_path) + Pkg.develop(path = lib_path) end end Pkg.develop(PackageSpec(path = dirname(@__DIR__))) From 96dc4965108bb673961ef5081ae55a5316e9b0c2 Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Wed, 22 Apr 2026 20:44:03 +0900 Subject: [PATCH 16/41] fix bump version ci --- .github/workflows/bump-version.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/bump-version.yml b/.github/workflows/bump-version.yml index 09669637f..e215effa1 100644 --- a/.github/workflows/bump-version.yml +++ b/.github/workflows/bump-version.yml @@ -85,7 +85,7 @@ jobs: content = read(changelog_file, String) marker1 = "\n\n## [v$v_QT]" - insertion1 = "\n- Bump $package version to `v$new_v`.\n$marker1" + insertion1 = "\n- [lib] Bump `$package` version to `v$new_v`.\n$marker1" new_content = replace(content, marker1 => insertion1) if package == "QuantumToolbox" @@ -145,7 +145,7 @@ jobs: changelog_file = "CHANGELOG.md" content = read(changelog_file, String) - old_entry = "- Bump $package version to `v$new_v`." + old_entry = "- [lib] Bump `$package` version to `v$new_v`." new_entry = "$old_entry ([#$pr_number])" write(changelog_file, replace(content, old_entry => new_entry)) From 4b6ec24a45fcaa95b5b0b1a3f393140286c5e619 Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Wed, 22 Apr 2026 21:23:00 +0900 Subject: [PATCH 17/41] add versioninfo and cite --- lib/QuantumToolboxUtils/Project.toml | 2 + .../src/QuantumToolboxUtils.jl | 7 + .../QuantumToolboxUtils/src}/versioninfo.jl | 123 +++++++++++------- src/QuantumToolbox.jl | 10 +- src/utils.jl | 29 +++++ 5 files changed, 123 insertions(+), 48 deletions(-) rename {src => lib/QuantumToolboxUtils/src}/versioninfo.jl (56%) create mode 100644 src/utils.jl diff --git a/lib/QuantumToolboxUtils/Project.toml b/lib/QuantumToolboxUtils/Project.toml index ba231cd15..69b9116e7 100644 --- a/lib/QuantumToolboxUtils/Project.toml +++ b/lib/QuantumToolboxUtils/Project.toml @@ -4,12 +4,14 @@ authors = ["Alberto Mercurio", "Yi-Te Huang"] version = "0.1.0" [deps] +LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" SciMLOperators = "c0aeaf25-5076-4817-a8d5-81caf7dfa961" SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" [compat] +LinearAlgebra = "1" Random = "1" SciMLOperators = "1.12" SparseArrays = "1" diff --git a/lib/QuantumToolboxUtils/src/QuantumToolboxUtils.jl b/lib/QuantumToolboxUtils/src/QuantumToolboxUtils.jl index 18dd7bd5d..0dcdcd12d 100644 --- a/lib/QuantumToolboxUtils/src/QuantumToolboxUtils.jl +++ b/lib/QuantumToolboxUtils/src/QuantumToolboxUtils.jl @@ -1,13 +1,20 @@ module QuantumToolboxUtils +using LinearAlgebra using SparseArrays import StaticArraysCore: SVector, MVector import Random: AbstractRNG import SciMLOperators: AbstractSciMLOperator +include("versioninfo.jl") include("type_handle.jl") include("PhysicalConstants.jl") include("misc.jl") +function __init__() + _register_qt_library!(QuantumToolboxUtils) + return nothing +end + end diff --git a/src/versioninfo.jl b/lib/QuantumToolboxUtils/src/versioninfo.jl similarity index 56% rename from src/versioninfo.jl rename to lib/QuantumToolboxUtils/src/versioninfo.jl index 4a99ddc26..66fb87e5a 100644 --- a/src/versioninfo.jl +++ b/lib/QuantumToolboxUtils/src/versioninfo.jl @@ -1,78 +1,69 @@ #= -Command line output of information on QuantumToolbox, dependencies, and system information +Reusable version information helpers for QuantumToolbox libraries. =# -@doc raw""" - QuantumToolbox.versioninfo(io::IO=stdout) +# Registry of all loaded QuantumToolbox libraries, populated via __init__ in each library. +const _QT_LIBRARIES = Module[] -Command line output of information on QuantumToolbox, dependencies, and system information, same as [`QuantumToolbox.about`](@ref). +raw""" + _register_qt_library!(m::Module) + +Register a QuantumToolbox library module into the global registry. Each library should call this in its `__init__` function. """ -function versioninfo(io::IO = stdout) - # print introduction - println( - io, - "\n", - " QuantumToolbox.jl: Quantum Toolbox in Julia\n", - "≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡\n", - "Copyright © QuTiP team 2022 and later.\n", - "Current admin team:\n", - " Alberto Mercurio and Yi-Te Huang\n", - ) +function _register_qt_library!(m::Module) + (m ∉ _QT_LIBRARIES) && pushfirst!(_QT_LIBRARIES, m) # use pushfirst! so that main API libraries are at the front of the registry (for better display order in versioninfo) + return nothing +end - # print package information - pkg_tuple = ( - QuantumToolbox, - QuantumToolboxUtils, - SciMLOperators, - LinearSolve, - OrdinaryDiffEqCore, - ) - pkginfo(io; pkgs = pkg_tuple) +raw""" + _add_library_deps!(lib::Val, DEPpkgs::Vector{Module}) - # print System information - sysinfo(io) +Add new dependencies to `DEPpkgs` for the specified library. Extend this function in each QuantumToolbox library to declare its external (non-QuantumToolbox) dependencies. +""" +_add_library_deps!(lib::Val{T}, DEPpkgs::Vector{Module}) where {T} = throw(ArgumentError("Unknown QuantumToolbox library : $T")) +_add_library_deps!(lib::Val{:QuantumToolboxUtils}, DEPpkgs::Vector{Module}) = nothing # currently no external dependencies for QuantumToolboxUtils - # print citation information - println( - io, - "+---------------------------------------------------+\n", - "| Please cite QuantumToolbox.jl in your publication |\n", - "+---------------------------------------------------+\n", - "For your convenience, a bibtex reference can be easily generated using `QuantumToolbox.cite()`.\n", - ) +# add pkgs2 into pkgs1 but ensure the uniqueness +function _add_pkgs!(pkgs1::Vector{Module}, pkgs2::Vector{Module}) + for pkg in unique(pkgs2) + (pkg ∉ pkgs1) && push!(pkgs1, pkg) + end return nothing end -@doc raw""" - QuantumToolbox.pkginfo(io::IO=stdout; pkgs::NTuple{N, Module} = (QuantumToolbox,)) +raw""" + QuantumToolboxUtils.pkginfo(io::IO=stdout; pkgs::Vector{Module} = Module[]) -Command line output of version numbers for given tuple of packages: `pkgs`. Default to `(QuantumToolbox,)`. +Command line output of version numbers for given vector of packages: `pkgs`. """ -function pkginfo(io::IO = stdout; pkgs::NTuple{N, Module} = (QuantumToolbox,)) where {N} +function pkginfo(io::IO = stdout; pkgs::Vector{Module} = Module[], split_after::Union{Nothing, Int} = nothing) pkg_ver_list = map(pkgversion, pkgs) maxLen = max(5, maximum(length ∘ string, pkgs)) # maximum string length of package names (5 refer to "Julia") + separation_line = "------------------------------------" print( io, "Package information:\n", "====================================\n", ) println(io, rpad("Julia", maxLen, " "), " Ver. ", VERSION) # print Julia version first - for (pkg, pkg_ver) in zip(pkgs, pkg_ver_list) + println(io, separation_line) + for (idx, (pkg, pkg_ver)) in enumerate(zip(pkgs, pkg_ver_list)) println(io, rpad(pkg, maxLen, " "), " Ver. ", pkg_ver) + !isnothing(split_after) && (idx == split_after) && (idx < length(pkgs)) && println(io, separation_line) end print(io, "\n") return nothing end -@doc raw""" - QuantumToolbox.sysinfo(io::IO=stdout) +raw""" + QuantumToolboxUtils.sysinfo(io::IO=stdout) Command line output of system information. """ function sysinfo(io::IO = stdout) cpu = Sys.cpu_info() - BLAS_info = BLAS.get_config().loaded_libs[1] + BLAS_info = LinearAlgebra.BLAS.get_config().loaded_libs[1] Sys.iswindows() ? OS_name = "Windows" : Sys.isapple() ? OS_name = "macOS" : OS_name = Sys.KERNEL println( @@ -91,15 +82,55 @@ function sysinfo(io::IO = stdout) return nothing end -@doc raw""" - QuantumToolbox.about(io::IO=stdout) +function _print_versioninfo(io::IO = stdout) + println( + io, + "\n", + " QuantumToolbox.jl: Quantum Toolbox in Julia\n", + "≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡\n", + "Copyright © QuTiP team 2022 and later.\n", + "Current admin team:\n", + " Alberto Mercurio and Yi-Te Huang\n", + ) + + DEPpkgs = _gen_dep_pkg_list() + pkginfo(io; pkgs = vcat(_QT_LIBRARIES, DEPpkgs), split_after = length(_QT_LIBRARIES)) + sysinfo(io) + + println( + io, + "+---------------------------------------------------+\n", + "| Please cite QuantumToolbox.jl in your publication |\n", + "+---------------------------------------------------+\n", + "For your convenience, a bibtex reference can be easily generated using `QuantumToolbox.cite()`.\n", + ) + return nothing +end + +function _gen_dep_pkg_list() + DEPpkgs = Module[] + for lib in _QT_LIBRARIES + _add_library_deps!(Val(nameof(lib)), DEPpkgs) + end + return DEPpkgs +end + +raw""" + QuantumToolboxUtils.versioninfo(io::IO=stdout) + +Command line output of information on QuantumToolbox, dependencies, and system information, same as [`QuantumToolbox.about`](@ref). +""" +versioninfo(io::IO = stdout) = _print_versioninfo(io) + +raw""" + QuantumToolboxUtils.about(io::IO=stdout) Command line output of information on QuantumToolbox, dependencies, and system information, same as [`QuantumToolbox.versioninfo`](@ref). """ about(io::IO = stdout) = versioninfo(io) -@doc raw""" - QuantumToolbox.cite(io::IO = stdout) +raw""" + QuantumToolboxUtils.cite(io::IO = stdout) Command line output of citation information and bibtex generator for `QuantumToolbox.jl`. """ diff --git a/src/QuantumToolbox.jl b/src/QuantumToolbox.jl index 708d7ccf2..45a1fce86 100644 --- a/src/QuantumToolbox.jl +++ b/src/QuantumToolbox.jl @@ -33,6 +33,7 @@ import QuantumToolboxUtils: ## SciML packages (for QobjEvo, OrdinaryDiffEq, and LinearSolve) import SciMLBase: + SciMLBase, solve, solve!, init, @@ -107,9 +108,9 @@ export cache_operator, iscached, isconstant # Source files -## Utility +## Some overloading with QuantumToolboxUtils library include("settings.jl") -include("versioninfo.jl") +include("utils.jl") include("linear_maps.jl") ## Quantum Object @@ -166,4 +167,9 @@ include("visualization/wigner.jl") ## deprecated functions include("deprecated.jl") +function __init__() + QuantumToolboxUtils._register_qt_library!(QuantumToolbox) + return nothing +end + end diff --git a/src/utils.jl b/src/utils.jl new file mode 100644 index 000000000..2bd4ac86f --- /dev/null +++ b/src/utils.jl @@ -0,0 +1,29 @@ +#= +Overloading functions from QuantumToolboxUtils +=# + +function QuantumToolboxUtils._add_library_deps!(lib::Val{:QuantumToolbox}, DEPpkgs::Vector{Module}) + QuantumToolboxUtils._add_pkgs!(DEPpkgs, Module[SciMLBase, SciMLOperators, OrdinaryDiffEqCore, LinearSolve]) + return nothing +end + +@doc raw""" + QuantumToolbox.versioninfo(io::IO=stdout) + +Command line output of information on QuantumToolbox, dependencies, and system information, same as [`QuantumToolbox.about`](@ref). +""" +versioninfo(io::IO = stdout) = QuantumToolboxUtils._print_versioninfo(io) + +@doc raw""" + QuantumToolbox.about(io::IO=stdout) + +Command line output of information on QuantumToolbox, dependencies, and system information, same as [`QuantumToolbox.versioninfo`](@ref). +""" +about(io::IO = stdout) = versioninfo(io) + +@doc raw""" + QuantumToolbox.cite(io::IO = stdout) + +Command line output of citation information and bibtex generator for `QuantumToolbox.jl`. +""" +cite(io::IO = stdout) = QuantumToolboxUtils.cite(io) From 22a069319b431ef2e37325367f9d43e4518722c1 Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Thu, 23 Apr 2026 10:32:48 +0900 Subject: [PATCH 18/41] fix versioninfo --- lib/QuantumToolboxUtils/src/QuantumToolboxUtils.jl | 2 +- lib/QuantumToolboxUtils/src/versioninfo.jl | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/QuantumToolboxUtils/src/QuantumToolboxUtils.jl b/lib/QuantumToolboxUtils/src/QuantumToolboxUtils.jl index 0dcdcd12d..110ccfa1d 100644 --- a/lib/QuantumToolboxUtils/src/QuantumToolboxUtils.jl +++ b/lib/QuantumToolboxUtils/src/QuantumToolboxUtils.jl @@ -5,7 +5,7 @@ using SparseArrays import StaticArraysCore: SVector, MVector import Random: AbstractRNG -import SciMLOperators: AbstractSciMLOperator +import SciMLOperators: SciMLOperators, AbstractSciMLOperator include("versioninfo.jl") include("type_handle.jl") diff --git a/lib/QuantumToolboxUtils/src/versioninfo.jl b/lib/QuantumToolboxUtils/src/versioninfo.jl index 66fb87e5a..b3783adb9 100644 --- a/lib/QuantumToolboxUtils/src/versioninfo.jl +++ b/lib/QuantumToolboxUtils/src/versioninfo.jl @@ -21,7 +21,10 @@ raw""" Add new dependencies to `DEPpkgs` for the specified library. Extend this function in each QuantumToolbox library to declare its external (non-QuantumToolbox) dependencies. """ _add_library_deps!(lib::Val{T}, DEPpkgs::Vector{Module}) where {T} = throw(ArgumentError("Unknown QuantumToolbox library : $T")) -_add_library_deps!(lib::Val{:QuantumToolboxUtils}, DEPpkgs::Vector{Module}) = nothing # currently no external dependencies for QuantumToolboxUtils +function _add_library_deps!(lib::Val{:QuantumToolboxUtils}, DEPpkgs::Vector{Module}) + _add_pkgs!(DEPpkgs, Module[SciMLOperators]) + return nothing +end # add pkgs2 into pkgs1 but ensure the uniqueness function _add_pkgs!(pkgs1::Vector{Module}, pkgs2::Vector{Module}) From 614081d220772d83850d291e207ee76a93f6aaf8 Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Thu, 23 Apr 2026 10:57:17 +0900 Subject: [PATCH 19/41] move `cite` test to utils --- {test/core-test => lib/QuantumToolboxUtils/test}/cite.jl | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {test/core-test => lib/QuantumToolboxUtils/test}/cite.jl (100%) diff --git a/test/core-test/cite.jl b/lib/QuantumToolboxUtils/test/cite.jl similarity index 100% rename from test/core-test/cite.jl rename to lib/QuantumToolboxUtils/test/cite.jl From e2257e65edad0040ce38276d633d42437a93c3d7 Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Thu, 23 Apr 2026 10:57:45 +0900 Subject: [PATCH 20/41] move settings and fix versioninfo --- .../src/QuantumToolboxUtils.jl | 1 + .../QuantumToolboxUtils/src}/settings.jl | 2 +- lib/QuantumToolboxUtils/src/versioninfo.jl | 12 ++++----- src/QuantumToolbox.jl | 1 - src/utils.jl | 26 ++++--------------- 5 files changed, 13 insertions(+), 29 deletions(-) rename {src => lib/QuantumToolboxUtils/src}/settings.jl (94%) diff --git a/lib/QuantumToolboxUtils/src/QuantumToolboxUtils.jl b/lib/QuantumToolboxUtils/src/QuantumToolboxUtils.jl index 110ccfa1d..76861e33e 100644 --- a/lib/QuantumToolboxUtils/src/QuantumToolboxUtils.jl +++ b/lib/QuantumToolboxUtils/src/QuantumToolboxUtils.jl @@ -7,6 +7,7 @@ import Random: AbstractRNG import SciMLOperators: SciMLOperators, AbstractSciMLOperator +include("settings.jl") include("versioninfo.jl") include("type_handle.jl") include("PhysicalConstants.jl") diff --git a/src/settings.jl b/lib/QuantumToolboxUtils/src/settings.jl similarity index 94% rename from src/settings.jl rename to lib/QuantumToolboxUtils/src/settings.jl index e4daa9c85..e5a59538f 100644 --- a/src/settings.jl +++ b/lib/QuantumToolboxUtils/src/settings.jl @@ -17,7 +17,7 @@ end @doc raw""" QuantumToolbox.settings -Contains all the default global settings of QuantumToolbox.jl. +Contains all the default global settings of QuantumToolbox.jl and all related libraries. # List of settings diff --git a/lib/QuantumToolboxUtils/src/versioninfo.jl b/lib/QuantumToolboxUtils/src/versioninfo.jl index b3783adb9..e1c8bdb79 100644 --- a/lib/QuantumToolboxUtils/src/versioninfo.jl +++ b/lib/QuantumToolboxUtils/src/versioninfo.jl @@ -118,22 +118,22 @@ function _gen_dep_pkg_list() return DEPpkgs end -raw""" - QuantumToolboxUtils.versioninfo(io::IO=stdout) +@doc raw""" + QuantumToolbox.versioninfo(io::IO=stdout) Command line output of information on QuantumToolbox, dependencies, and system information, same as [`QuantumToolbox.about`](@ref). """ versioninfo(io::IO = stdout) = _print_versioninfo(io) -raw""" - QuantumToolboxUtils.about(io::IO=stdout) +@doc raw""" + QuantumToolbox.about(io::IO=stdout) Command line output of information on QuantumToolbox, dependencies, and system information, same as [`QuantumToolbox.versioninfo`](@ref). """ about(io::IO = stdout) = versioninfo(io) -raw""" - QuantumToolboxUtils.cite(io::IO = stdout) +@doc raw""" + QuantumToolbox.cite(io::IO = stdout) Command line output of citation information and bibtex generator for `QuantumToolbox.jl`. """ diff --git a/src/QuantumToolbox.jl b/src/QuantumToolbox.jl index 45a1fce86..01ee4b659 100644 --- a/src/QuantumToolbox.jl +++ b/src/QuantumToolbox.jl @@ -109,7 +109,6 @@ export cache_operator, iscached, isconstant # Source files ## Some overloading with QuantumToolboxUtils library -include("settings.jl") include("utils.jl") include("linear_maps.jl") diff --git a/src/utils.jl b/src/utils.jl index 2bd4ac86f..a9236d4fc 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -1,5 +1,5 @@ #= -Overloading functions from QuantumToolboxUtils +Some alias and overloading functions from QuantumToolboxUtils =# function QuantumToolboxUtils._add_library_deps!(lib::Val{:QuantumToolbox}, DEPpkgs::Vector{Module}) @@ -7,23 +7,7 @@ function QuantumToolboxUtils._add_library_deps!(lib::Val{:QuantumToolbox}, DEPpk return nothing end -@doc raw""" - QuantumToolbox.versioninfo(io::IO=stdout) - -Command line output of information on QuantumToolbox, dependencies, and system information, same as [`QuantumToolbox.about`](@ref). -""" -versioninfo(io::IO = stdout) = QuantumToolboxUtils._print_versioninfo(io) - -@doc raw""" - QuantumToolbox.about(io::IO=stdout) - -Command line output of information on QuantumToolbox, dependencies, and system information, same as [`QuantumToolbox.versioninfo`](@ref). -""" -about(io::IO = stdout) = versioninfo(io) - -@doc raw""" - QuantumToolbox.cite(io::IO = stdout) - -Command line output of citation information and bibtex generator for `QuantumToolbox.jl`. -""" -cite(io::IO = stdout) = QuantumToolboxUtils.cite(io) +const settings = QuantumToolboxUtils.settings +const versioninfo = QuantumToolboxUtils.versioninfo +const about = QuantumToolboxUtils.about +const cite = QuantumToolboxUtils.cite From e3a95c9afa0a6fdf143acc13988f25d2d580828f Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Thu, 23 Apr 2026 11:09:31 +0900 Subject: [PATCH 21/41] move `linear_maps` to utils --- {src => lib/QuantumToolboxUtils/src}/linear_maps.jl | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {src => lib/QuantumToolboxUtils/src}/linear_maps.jl (100%) diff --git a/src/linear_maps.jl b/lib/QuantumToolboxUtils/src/linear_maps.jl similarity index 100% rename from src/linear_maps.jl rename to lib/QuantumToolboxUtils/src/linear_maps.jl From 3e46ce26016de0af79fad80a499211e731443438 Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Thu, 23 Apr 2026 11:09:43 +0900 Subject: [PATCH 22/41] fix typo --- src/QuantumToolbox.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/src/QuantumToolbox.jl b/src/QuantumToolbox.jl index 01ee4b659..31816244c 100644 --- a/src/QuantumToolbox.jl +++ b/src/QuantumToolbox.jl @@ -110,7 +110,6 @@ export cache_operator, iscached, isconstant ## Some overloading with QuantumToolboxUtils library include("utils.jl") -include("linear_maps.jl") ## Quantum Object include("qobj/dimensions.jl") From 6d0cbc0972beb31313340e007db3287a95e059ee Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Thu, 23 Apr 2026 11:10:13 +0900 Subject: [PATCH 23/41] split misc in utils into linalg and physics_func --- .../src/QuantumToolboxUtils.jl | 5 ++++- lib/QuantumToolboxUtils/src/linalg.jl | 20 +++++++++++++++++++ .../src/{misc.jl => physics_func.jl} | 20 ------------------- 3 files changed, 24 insertions(+), 21 deletions(-) create mode 100644 lib/QuantumToolboxUtils/src/linalg.jl rename lib/QuantumToolboxUtils/src/{misc.jl => physics_func.jl} (64%) diff --git a/lib/QuantumToolboxUtils/src/QuantumToolboxUtils.jl b/lib/QuantumToolboxUtils/src/QuantumToolboxUtils.jl index 76861e33e..237e83d77 100644 --- a/lib/QuantumToolboxUtils/src/QuantumToolboxUtils.jl +++ b/lib/QuantumToolboxUtils/src/QuantumToolboxUtils.jl @@ -9,9 +9,12 @@ import SciMLOperators: SciMLOperators, AbstractSciMLOperator include("settings.jl") include("versioninfo.jl") + include("type_handle.jl") +include("linalg.jl") +include("linear_maps.jl") include("PhysicalConstants.jl") -include("misc.jl") +include("physics_func.jl") function __init__() _register_qt_library!(QuantumToolboxUtils) diff --git a/lib/QuantumToolboxUtils/src/linalg.jl b/lib/QuantumToolboxUtils/src/linalg.jl new file mode 100644 index 000000000..d9ded6385 --- /dev/null +++ b/lib/QuantumToolboxUtils/src/linalg.jl @@ -0,0 +1,20 @@ +export row_major_reshape, meshgrid + +@doc raw""" + row_major_reshape(Q::AbstractArray, shapes...) + +Reshapes `Q` in the row-major order, as numpy. +""" +row_major_reshape(Q::AbstractArray{T}, shapes...) where {T} = + PermutedDimsArray(reshape(Q, reverse(shapes)...), (length(shapes):-1:1)) + +@doc raw""" + meshgrid(x::AbstractVector, y::AbstractVector) + +Equivalent to [numpy meshgrid](https://numpy.org/doc/stable/reference/generated/numpy.meshgrid.html). +""" +function meshgrid(x::AbstractVector{T}, y::AbstractVector{T}) where {T} + X = reshape(repeat(x, inner = length(y)), length(y), length(x)) + Y = repeat(y, outer = (1, length(x))) + return X, Y +end \ No newline at end of file diff --git a/lib/QuantumToolboxUtils/src/misc.jl b/lib/QuantumToolboxUtils/src/physics_func.jl similarity index 64% rename from lib/QuantumToolboxUtils/src/misc.jl rename to lib/QuantumToolboxUtils/src/physics_func.jl index 2a7c26b33..7a37736de 100644 --- a/lib/QuantumToolboxUtils/src/misc.jl +++ b/lib/QuantumToolboxUtils/src/physics_func.jl @@ -1,24 +1,4 @@ export gaussian, n_thermal -export row_major_reshape, meshgrid - -@doc raw""" - row_major_reshape(Q::AbstractArray, shapes...) - -Reshapes `Q` in the row-major order, as numpy. -""" -row_major_reshape(Q::AbstractArray{T}, shapes...) where {T} = - PermutedDimsArray(reshape(Q, reverse(shapes)...), (length(shapes):-1:1)) - -@doc raw""" - meshgrid(x::AbstractVector, y::AbstractVector) - -Equivalent to [numpy meshgrid](https://numpy.org/doc/stable/reference/generated/numpy.meshgrid.html). -""" -function meshgrid(x::AbstractVector{T}, y::AbstractVector{T}) where {T} - X = reshape(repeat(x, inner = length(y)), length(y), length(x)) - Y = repeat(y, outer = (1, length(x))) - return X, Y -end @doc raw""" gaussian(x::Number, μ::Number, σ::Number) From 81850b842979afb2f457fad4bef7d6960bc99cc1 Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Thu, 23 Apr 2026 11:10:26 +0900 Subject: [PATCH 24/41] format files --- lib/QuantumToolboxUtils/src/linalg.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/QuantumToolboxUtils/src/linalg.jl b/lib/QuantumToolboxUtils/src/linalg.jl index d9ded6385..4de0285dc 100644 --- a/lib/QuantumToolboxUtils/src/linalg.jl +++ b/lib/QuantumToolboxUtils/src/linalg.jl @@ -17,4 +17,4 @@ function meshgrid(x::AbstractVector{T}, y::AbstractVector{T}) where {T} X = reshape(repeat(x, inner = length(y)), length(y), length(x)) Y = repeat(y, outer = (1, length(x))) return X, Y -end \ No newline at end of file +end From a5d22a7adb0050f48754e54e22dd311505bf9d06 Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Thu, 23 Apr 2026 11:24:02 +0900 Subject: [PATCH 25/41] rename test group `Core` to `Basic` --- .github/copilot-instructions.md | 4 ++-- .github/workflows/CI-Julia-nightly.yml | 2 +- .github/workflows/CI.yml | 4 ++-- Makefile | 2 +- docs/src/resources/contributing.md | 8 ++++---- test/runtests.jl | 12 ++++++------ 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index b18214474..6e62f5108 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -82,11 +82,11 @@ QuantumToolbox.settings.ProgressMeterKWARGS = (showspeed=true, printed=true) ### Running Tests ```bash make test # Run all core tests -GROUP=Core make test # Run core tests only +GROUP=Basic make test # Run Basic tests only GROUP=CUDA_Ext make test # Run CUDA extension tests only ``` -Test groups (set `GROUP` env var): "All", "Core", "Code-Quality", "AutoDiff_Ext", "Makie_Ext", "CUDA_Ext", "Arbitrary-Precision" +Test groups (set `GROUP` env var): "All", "Basic", "Code-Quality", "AutoDiff_Ext", "Makie_Ext", "CUDA_Ext", "Arbitrary-Precision" ### Code Quality & Formatting ```bash diff --git a/.github/workflows/CI-Julia-nightly.yml b/.github/workflows/CI-Julia-nightly.yml index 1baf9f69c..277c94396 100644 --- a/.github/workflows/CI-Julia-nightly.yml +++ b/.github/workflows/CI-Julia-nightly.yml @@ -47,7 +47,7 @@ jobs: arch: - 'x64' group: - - 'Core' + - 'Basic' steps: - uses: actions/checkout@v6 diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index cbc09b442..82c7f0187 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -54,7 +54,7 @@ jobs: - os: 'macOS-latest' arch: 'arm64' group: - - 'Core' + - 'Basic' include: # for core tests (intermediate versions) @@ -62,7 +62,7 @@ jobs: node: os: 'ubuntu-latest' arch: 'x64' - group: 'Core' + group: 'Basic' # for extension tests - version: '1' diff --git a/Makefile b/Makefile index 553b69ad8..0ef7cc53e 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ changelog: ${JULIA} -e 'using Changelog; Changelog.generate(Changelog.CommonMark(), "CHANGELOG.md"; repo = "qutip/QuantumToolbox.jl")' test: - ${JULIA} --project -e 'using Pkg; Pkg.update(); Pkg.test()' + ${JULIA} -t 4 --project -e 'using Pkg; Pkg.update(); Pkg.test()' docs: ${JULIA} --project=docs -e 'using Pkg; Pkg.update(); include("docs/make.jl")' diff --git a/docs/src/resources/contributing.md b/docs/src/resources/contributing.md index 494a19523..dad9b934e 100644 --- a/docs/src/resources/contributing.md +++ b/docs/src/resources/contributing.md @@ -62,15 +62,15 @@ make test This command will automatically rebuild `Julia` and run the script located in `test/runtests.jl` (should cover both the original tests and the new test(s) you add). -The tests are divided into several test groups, where the group names are defined in the file `test/runtests.jl` with a variable `GROUP`. One can also run the test scripts just for a certain test group by adding an argument `GROUP=` to the `make test` command. For example, to run the tests for group `Core`, one can use the following command: +The tests are divided into several test groups, where the group names are defined in the file `test/runtests.jl` with a variable `GROUP`. One can also run the test scripts just for a certain test group by adding an argument `GROUP=` to the `make test` command. For example, to run the tests for group `Basic`, one can use the following command: ```shell -make GROUP=Core test +make GROUP=Basic test ``` -#### [Test Item Framework for Core tests](@id doc-Contribute:Test-Item-Framework-for-Core-tests) +#### [Test Item Framework for Basic tests](@id doc-Contribute:Test-Item-Framework-for-Basic-tests) -The tests in `GROUP=Core` are provided using the [Test Item Framework](https://www.julia-vscode.org/docs/stable/userguide/testitems/), which structures the test codes into `@testitems` and makes it easier to run individually. +The tests in `GROUP=Basic` are provided using the [Test Item Framework](https://www.julia-vscode.org/docs/stable/userguide/testitems/), which structures the test codes into `@testitems` and makes it easier to run individually. The [VS Code](https://code.visualstudio.com/) and its [Julia extension](https://www.julia-vscode.org/) provides us with options to run individual `@testitems`. It is much easier to find the specific core test that failed since the [Julia extension](https://www.julia-vscode.org/) in [VS Code](https://code.visualstudio.com/) will collect all core test failures and then display them in a structured way, directly at the place in the code where a specific core test failed. See [here](https://www.julia-vscode.org/docs/stable/userguide/testitems/) for more details. diff --git a/test/runtests.jl b/test/runtests.jl index 65174638c..f6a6465f0 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -22,7 +22,7 @@ const EXTENSION_LIST = collect(keys(EXTENSION_PATHS)) const GROUP = get(ENV, "GROUP", "All") const GROUP_LIST = String[ "All", - "Core", + "Basic", "Code-Quality", EXTENSION_LIST..., ] @@ -41,15 +41,15 @@ function setup_subtest_env(path::String) return nothing end -###################################### -# Core tests (use TestItemRunner.jl) # -###################################### -if (GROUP == "All") || (GROUP == "Core") +####################################### +# Basic tests (use TestItemRunner.jl) # +####################################### +if (GROUP == "All") || (GROUP == "Basic") import QuantumToolbox QuantumToolbox.about() - println("\nStart running Core tests...\n") + println("\nStart running Basic tests...\n") @run_package_tests verbose = true end From 124ff239af3d2448668e3f145f3905a23f77d3fd Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Thu, 23 Apr 2026 14:47:08 +0900 Subject: [PATCH 26/41] add deprecated to utils --- .../src/QuantumToolboxUtils.jl | 3 +++ lib/QuantumToolboxUtils/src/deprecated.jl | 23 +++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 lib/QuantumToolboxUtils/src/deprecated.jl diff --git a/lib/QuantumToolboxUtils/src/QuantumToolboxUtils.jl b/lib/QuantumToolboxUtils/src/QuantumToolboxUtils.jl index 237e83d77..a9ff0db25 100644 --- a/lib/QuantumToolboxUtils/src/QuantumToolboxUtils.jl +++ b/lib/QuantumToolboxUtils/src/QuantumToolboxUtils.jl @@ -16,6 +16,9 @@ include("linear_maps.jl") include("PhysicalConstants.jl") include("physics_func.jl") +## deprecated functions +include("deprecated.jl") + function __init__() _register_qt_library!(QuantumToolboxUtils) return nothing diff --git a/lib/QuantumToolboxUtils/src/deprecated.jl b/lib/QuantumToolboxUtils/src/deprecated.jl new file mode 100644 index 000000000..13af5ae49 --- /dev/null +++ b/lib/QuantumToolboxUtils/src/deprecated.jl @@ -0,0 +1,23 @@ +#= +This file gathers all the deprecated names (structures, functions, or variables) which will be removed in the future major release. + +- Before the major release, the deprecated names will show warnings or just throw errors when they are called. +- If the deprecated names were once exported, we will still export them here until next major release. +- If we decide to push a major release, cleanup this file. + +Example 1 [throw errors if the deprecation is fundamental, and there is no replacement for it]: +``` +export deprecated_foo +deprecated_foo(args...; kwargs...) = error("`deprecated_foo` is deprecated and will be removed in next major release.") +``` + +Example 2 ["force" show warning and tell the users that there is a replacement for the deprecated function]: + +``` +export deprecated_foo +function deprecated_foo(args...; kwargs...) + Base.depwarn("`deprecated_foo` is deprecated and will be removed in next major release, use `new_foo` instead.", :deprecated_foo, force = true) + new_foo(args...; kwargs...) +end +``` +=# From 8e4508859b2764a1e531018a0e9e3d6e16dafe9c Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Thu, 23 Apr 2026 15:01:37 +0900 Subject: [PATCH 27/41] move arnoldi to utils --- lib/QuantumToolboxUtils/src/QuantumToolboxUtils.jl | 11 ++++++++--- .../QuantumToolboxUtils/src/linalg}/arnoldi.jl | 0 lib/QuantumToolboxUtils/src/{ => linalg}/linalg.jl | 0 .../src/{ => linalg}/linear_maps.jl | 0 src/QuantumToolbox.jl | 1 - 5 files changed, 8 insertions(+), 4 deletions(-) rename {src => lib/QuantumToolboxUtils/src/linalg}/arnoldi.jl (100%) rename lib/QuantumToolboxUtils/src/{ => linalg}/linalg.jl (100%) rename lib/QuantumToolboxUtils/src/{ => linalg}/linear_maps.jl (100%) diff --git a/lib/QuantumToolboxUtils/src/QuantumToolboxUtils.jl b/lib/QuantumToolboxUtils/src/QuantumToolboxUtils.jl index a9ff0db25..45de9f7dc 100644 --- a/lib/QuantumToolboxUtils/src/QuantumToolboxUtils.jl +++ b/lib/QuantumToolboxUtils/src/QuantumToolboxUtils.jl @@ -7,12 +7,17 @@ import Random: AbstractRNG import SciMLOperators: SciMLOperators, AbstractSciMLOperator +## Basic utilities for QuantumToolbox libraries include("settings.jl") include("versioninfo.jl") - include("type_handle.jl") -include("linalg.jl") -include("linear_maps.jl") + +## Linear Algebra +include("linalg/linalg.jl") +include("linalg/arnoldi.jl") +include("linalg/linear_maps.jl") + +## Other physical related utilities include("PhysicalConstants.jl") include("physics_func.jl") diff --git a/src/arnoldi.jl b/lib/QuantumToolboxUtils/src/linalg/arnoldi.jl similarity index 100% rename from src/arnoldi.jl rename to lib/QuantumToolboxUtils/src/linalg/arnoldi.jl diff --git a/lib/QuantumToolboxUtils/src/linalg.jl b/lib/QuantumToolboxUtils/src/linalg/linalg.jl similarity index 100% rename from lib/QuantumToolboxUtils/src/linalg.jl rename to lib/QuantumToolboxUtils/src/linalg/linalg.jl diff --git a/lib/QuantumToolboxUtils/src/linear_maps.jl b/lib/QuantumToolboxUtils/src/linalg/linear_maps.jl similarity index 100% rename from lib/QuantumToolboxUtils/src/linear_maps.jl rename to lib/QuantumToolboxUtils/src/linalg/linear_maps.jl diff --git a/src/QuantumToolbox.jl b/src/QuantumToolbox.jl index 31816244c..1019e2676 100644 --- a/src/QuantumToolbox.jl +++ b/src/QuantumToolbox.jl @@ -149,7 +149,6 @@ include("time_evolution/time_evolution_dynamical.jl") include("correlations.jl") include("wigner.jl") include("spin_lattice.jl") -include("arnoldi.jl") include("entropy.jl") include("metrics.jl") include("negativity.jl") From 961397febf4fa4ea53e57691db613a9502e66fa7 Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Thu, 23 Apr 2026 15:04:23 +0900 Subject: [PATCH 28/41] move code-quality test folder --- .github/workflows/Code-Quality.yml | 2 +- test/{core-test => }/code-quality/Project.toml | 2 +- test/{core-test => }/code-quality/code_quality.jl | 0 test/runtests.jl | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) rename test/{core-test => }/code-quality/Project.toml (82%) rename test/{core-test => }/code-quality/code_quality.jl (100%) diff --git a/.github/workflows/Code-Quality.yml b/.github/workflows/Code-Quality.yml index be790d80f..d6a293144 100644 --- a/.github/workflows/Code-Quality.yml +++ b/.github/workflows/Code-Quality.yml @@ -21,7 +21,7 @@ on: - 'lib/**' - 'ext/**' - 'test/runtests.jl' - - 'test/core-test/**' + - 'test/code-quality/**' - 'Project.toml' types: - opened diff --git a/test/core-test/code-quality/Project.toml b/test/code-quality/Project.toml similarity index 82% rename from test/core-test/code-quality/Project.toml rename to test/code-quality/Project.toml index e0b7dfea8..5a4113b71 100644 --- a/test/core-test/code-quality/Project.toml +++ b/test/code-quality/Project.toml @@ -6,7 +6,7 @@ QuantumToolboxUtils = "02afad9e-e2b8-4f9a-965f-b5dca5b538ca" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [sources] -QuantumToolboxUtils = {path = "../../../lib/QuantumToolboxUtils"} +QuantumToolboxUtils = {path = "../../lib/QuantumToolboxUtils"} [compat] Aqua = "0.8" diff --git a/test/core-test/code-quality/code_quality.jl b/test/code-quality/code_quality.jl similarity index 100% rename from test/core-test/code-quality/code_quality.jl rename to test/code-quality/code_quality.jl diff --git a/test/runtests.jl b/test/runtests.jl index f6a6465f0..5eb3b4a89 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -59,7 +59,7 @@ end # Code Quality tests if (GROUP == "All") || (GROUP == "Code-Quality") - path = joinpath(testdir, "core-test", "code-quality") + path = joinpath(testdir, "code-quality") setup_subtest_env(path) using QuantumToolbox From 8e026248d20ba610adacaa1674ff9f5d08635104 Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Thu, 23 Apr 2026 17:56:43 +0900 Subject: [PATCH 29/41] divide Basic tests by libraries --- test/runtests.jl | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index 5eb3b4a89..86a354f3a 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -5,8 +5,8 @@ using Pkg const testdir = dirname(@__FILE__) # Define the paths to the library -const LIBRARY_PATHS = ( - joinpath(testdir, "..", "lib", "QuantumToolboxUtils"), +const LIBRARY_PATHS = Dict( + "QuantumToolboxUtils" => joinpath(testdir, "..", "lib", "QuantumToolboxUtils"), ) # Define the paths to the extension tests @@ -32,7 +32,7 @@ const GROUP_LIST = String[ function setup_subtest_env(path::String) Pkg.activate(path) if VERSION < v"1.11" - for lib_path in LIBRARY_PATHS + for (_, lib_path) in LIBRARY_PATHS Pkg.develop(path = lib_path) end end @@ -49,8 +49,20 @@ if (GROUP == "All") || (GROUP == "Basic") QuantumToolbox.about() - println("\nStart running Basic tests...\n") - @run_package_tests verbose = true + println("\nStart running Basic tests...") + + # tests in lib folder for each library + # PATH: lib/LIBRARY_NAME/test/ + for (lib_name, _) in LIBRARY_PATHS + println("\n[$lib_name]") + @run_package_tests filter = ti -> occursin(joinpath("lib", lib_name, "test"), ti.filename) verbose = true + end + + # main package tests (all tests except those in the lib folder) + println("\n[QuantumToolbox]") + @run_package_tests filter = ti -> !occursin("lib", ti.filename) verbose = true + + println("\n===============> Basic tests completed <===============\n") end ######################################################################## @@ -68,7 +80,7 @@ if (GROUP == "All") || (GROUP == "Code-Quality") (GROUP == "Code-Quality") && QuantumToolbox.about() # print version info. for code quality CI in GitHub # run code quality tests for all libraries and the main package - for lib_path in LIBRARY_PATHS + for (_, lib_path) in LIBRARY_PATHS include(joinpath(lib_path, "test", "code_quality.jl")) end include(joinpath(path, "code_quality.jl")) From d65d2182ba592fa3f43bb958c825848b7f366832 Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Thu, 23 Apr 2026 17:58:23 +0900 Subject: [PATCH 30/41] update changelog --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index de9f3d161..9c1cd656f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased](https://github.com/qutip/QuantumToolbox.jl/tree/main) - +- [lib] Introduce QuantumToolboxUtils library. ([#686]) ## [v0.45.0] Release date: 2026-04-19 @@ -484,6 +484,7 @@ Release date: 2024-11-13 [#681]: https://github.com/qutip/QuantumToolbox.jl/issues/681 [#682]: https://github.com/qutip/QuantumToolbox.jl/issues/682 [#683]: https://github.com/qutip/QuantumToolbox.jl/issues/683 +[#686]: https://github.com/qutip/QuantumToolbox.jl/issues/686 [#688]: https://github.com/qutip/QuantumToolbox.jl/issues/688 [#689]: https://github.com/qutip/QuantumToolbox.jl/issues/689 [#690]: https://github.com/qutip/QuantumToolbox.jl/issues/690 From 52c579a4928503fa05c97aa99d65e837a0a6c745 Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Fri, 24 Apr 2026 11:25:40 +0900 Subject: [PATCH 31/41] fix docs --- docs/make.jl | 1 - docs/src/.vitepress/config.mts | 4 + docs/src/index.md | 2 +- docs/src/resources/api.md | 106 ++++++++++-------- docs/src/users_guide/settings.md | 4 +- .../src/linalg/linear_maps.jl | 4 +- lib/QuantumToolboxUtils/src/settings.jl | 4 +- lib/QuantumToolboxUtils/src/versioninfo.jl | 4 +- 8 files changed, 70 insertions(+), 59 deletions(-) diff --git a/docs/make.jl b/docs/make.jl index 08be90710..0d0f07040 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -34,7 +34,6 @@ const PAGES = [ "Home" => "index.md", "Getting Started" => [ "Brief Example" => "getting_started/brief_example.md", - # "Key differences from QuTiP" => "getting_started/qutip_differences.md", "The Importance of Type-Stability" => "getting_started/type_stability.md", "Example: Create QuantumToolbox.jl Logo" => "getting_started/logo.md", "Cite QuantumToolbox.jl" => "getting_started/cite.md", diff --git a/docs/src/.vitepress/config.mts b/docs/src/.vitepress/config.mts index 91a00ca79..1365173be 100644 --- a/docs/src/.vitepress/config.mts +++ b/docs/src/.vitepress/config.mts @@ -54,6 +54,10 @@ export default defineConfig({ light: "github-light", dark: "github-dark" }, + + // options for @mdit-vue/plugin-toc + // https://github.com/mdit-vue/mdit-vue/tree/main/packages/plugin-toc#options + toc: { level: [2, 3, 4] }, // for API page, triggered by: [[toc]] }, vite: { plugins: [ diff --git a/docs/src/index.md b/docs/src/index.md index 154d27418..e0736c5a8 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -75,7 +75,7 @@ Alternatively, this can also be done in `Julia`'s [Pkg REPL](https://julialang.g ``` More information about `Julia`'s package manager can be found at [`Pkg.jl`](https://julialang.github.io/Pkg.jl/v1/). -To load the package and check the version information, use either [`QuantumToolbox.versioninfo()`](@ref) or [`QuantumToolbox.about()`](@ref), namely +To load the package and check the version information, use either [`QuantumToolbox.versioninfo()`](@ref QuantumToolboxUtils.versioninfo) or [`QuantumToolbox.about()`](@ref QuantumToolboxUtils.about), namely ```julia using QuantumToolbox QuantumToolbox.versioninfo() diff --git a/docs/src/resources/api.md b/docs/src/resources/api.md index 435dbf91d..0b5e50ca1 100644 --- a/docs/src/resources/api.md +++ b/docs/src/resources/api.md @@ -1,3 +1,35 @@ +# [API](@id doc-API) + +**Table of contents** + +[[toc]] + +## [QuantumToolboxUtils](@id doc-API:QuantumToolboxUtils) + +```@meta +CurrentModule = QuantumToolboxUtils + +DocTestSetup = quote + using QuantumToolboxUtils +end +``` + +```@docs +settings +versioninfo +about +cite +row_major_reshape +meshgrid +AbstractLinearMap +gaussian +n_thermal +PhysicalConstants +convert_unit +``` + +## [QuantumToolbox](@id doc-API:QuantumToolbox) + ```@meta CurrentModule = QuantumToolbox @@ -8,22 +40,23 @@ DocTestSetup = quote end ``` -# [API](@id doc-API) - -**Table of contents** - -[[toc]] - -## [Quantum object (Qobj) and type](@id doc-API:Quantum-object-and-type) +### [Dimensions](@id doc-API:Dimensions) ```@docs Dimensions +get_size AbstractSpace AbstractSuperSpace Space TensorSpace LiouvilleSpace EnrSpace +enr_state_dictionaries +``` + +### [Quantum object (Qobj) and type](@id doc-API:Quantum-object-and-type) + +```@docs AbstractQuantumObject Bra Ket @@ -39,7 +72,7 @@ Base.length SciMLOperators.cache_operator ``` -## [Qobj boolean functions](@id doc-API:Qobj-boolean-functions) +### [Qobj boolean functions](@id doc-API:Qobj-boolean-functions) ```@docs isbra @@ -57,7 +90,7 @@ SciMLOperators.iscached SciMLOperators.isconstant ``` -## [Qobj arithmetic and attributes](@id doc-API:Qobj-arithmetic-and-attributes) +### [Qobj arithmetic and attributes](@id doc-API:Qobj-arithmetic-and-attributes) ```@docs Base.zero @@ -89,7 +122,7 @@ get_coherence partial_transpose ``` -## [Qobj eigenvalues and eigenvectors](@id doc-API:Qobj-eigenvalues-and-eigenvectors) +### [Qobj eigenvalues and eigenvectors](@id doc-API:Qobj-eigenvalues-and-eigenvectors) ```@docs EigsolveResult @@ -101,7 +134,7 @@ eigsolve eigsolve_al ``` -## [Qobj manipulation](@id doc-API:Qobj-manipulation) +### [Qobj manipulation](@id doc-API:Qobj-manipulation) ```@docs ket2dm @@ -114,7 +147,7 @@ vec2mat mat2vec ``` -## [Generate states and operators](@id doc-API:Generate-states-and-operators) +### [Generate states and operators](@id doc-API:Generate-states-and-operators) ```@docs zero_ket @@ -172,7 +205,7 @@ sprepost lindblad_dissipator ``` -## [Synonyms of functions for Qobj](@id doc-API:Synonyms-of-functions-for-Qobj) +### [Synonyms of functions for Qobj](@id doc-API:Synonyms-of-functions-for-Qobj) ```@docs Qobj QobjEvo @@ -196,7 +229,7 @@ qeye_like qzero_like ``` -## [Time evolution](@id doc-API:Time-evolution) +### [Time evolution](@id doc-API:Time-evolution) ```@docs TimeEvolutionProblem @@ -229,7 +262,7 @@ brterm brmesolve ``` -### [Steady State Solvers](@id doc-API:Steady-State-Solvers) +#### [Steady State Solvers](@id doc-API:Steady-State-Solvers) ```@docs steadystate @@ -241,14 +274,14 @@ SteadyStateODESolver SSFloquetEffectiveLiouvillian ``` -### [Dynamical Shifted Fock method](@id doc-API:Dynamical-Shifted-Fock-method) +#### [Dynamical Shifted Fock method](@id doc-API:Dynamical-Shifted-Fock-method) ```@docs dsf_mesolve dsf_mcsolve ``` -### [Low-rank time evolution](@id doc-API:Low-rank-time-evolution) +#### [Low-rank time evolution](@id doc-API:Low-rank-time-evolution) ```@docs TimeEvolutionLRSol @@ -256,7 +289,7 @@ lr_mesolveProblem lr_mesolve ``` -## [Correlations and Spectrum](@id doc-API:Correlations-and-Spectrum) +### [Correlations and Spectrum](@id doc-API:Correlations-and-Spectrum) ```@docs correlation_3op_2t @@ -270,7 +303,7 @@ PseudoInverse Lanczos ``` -## [Entropy and Metrics](@id doc-API:Entropy-and-Metrics) +### [Entropy and Metrics](@id doc-API:Entropy-and-Metrics) ```@docs entropy_vn @@ -289,7 +322,7 @@ bures_dist bures_angle ``` -## [Spin Lattice](@id doc-API:Spin-Lattice) +### [Spin Lattice](@id doc-API:Spin-Lattice) ```@docs Lattice @@ -297,45 +330,20 @@ multisite_operator DissipativeIsing ``` -## [Symmetries and Block Diagonalization](@id doc-API:Symmetries-and-Block-Diagonalization) +### [Symmetries and Block Diagonalization](@id doc-API:Symmetries-and-Block-Diagonalization) ```@docs block_diagonal_form BlockDiagonalForm ``` -## [Miscellaneous](@id doc-API:Miscellaneous) +### [Miscellaneous](@id doc-API:Miscellaneous) ```@docs wigner ``` -## [Linear Maps](@id doc-API:Linear-Maps) - -```@docs -AbstractLinearMap -``` - -## [Utility functions](@id doc-API:Utility-functions) - -```@docs -QuantumToolbox.settings -QuantumToolbox.versioninfo -QuantumToolbox.about -QuantumToolbox.pkginfo -QuantumToolbox.sysinfo -QuantumToolbox.cite -gaussian -n_thermal -PhysicalConstants -convert_unit -row_major_reshape -get_size -meshgrid -enr_state_dictionaries -``` - -## [Visualization](@id doc-API:Visualization) +### [Visualization](@id doc-API:Visualization) ```@docs plot_wigner @@ -344,7 +352,7 @@ matrix_heatmap matrix_histogram ``` -### [Bloch Sphere](@id doc-API:Bloch-Sphere) +#### [Bloch Sphere](@id doc-API:Bloch-Sphere) ```@docs Bloch diff --git a/docs/src/users_guide/settings.md b/docs/src/users_guide/settings.md index 53e9f59c9..78b01a25e 100644 --- a/docs/src/users_guide/settings.md +++ b/docs/src/users_guide/settings.md @@ -2,7 +2,7 @@ In this section, we introduce the default global settings used throughout the package and show how to modify them. -All settings are stored in [`QuantumToolbox.settings`](@ref). +All settings are stored in [`QuantumToolbox.settings`](@ref QuantumToolboxUtils.settings). !!! warning "Differences from QuTiP" Due to the differences in programming languages, solving algorithms, and many other reasons, these global settings (including their default values and usage) may be very different from those in `Python QuTiP`. @@ -20,7 +20,7 @@ Here, we list out each setting along with the specific functions that will use i ## Change default settings -First, we can check the current [`QuantumToolbox.settings`](@ref): +First, we can check the current [`QuantumToolbox.settings`](@ref QuantumToolboxUtils.settings): ```@example settings using QuantumToolbox diff --git a/lib/QuantumToolboxUtils/src/linalg/linear_maps.jl b/lib/QuantumToolboxUtils/src/linalg/linear_maps.jl index 93f550788..e5184165d 100644 --- a/lib/QuantumToolboxUtils/src/linalg/linear_maps.jl +++ b/lib/QuantumToolboxUtils/src/linalg/linear_maps.jl @@ -28,7 +28,7 @@ It is typically represented as a matrix with dimensions given by `size`, and thi ## Example -As an example, we now define the linear map used in the [`eigsolve_al`](@ref) function for Arnoldi-Lindblad eigenvalue solver: +As an example, we now define the linear map used in the [`eigsolve_al`](@ref QuantumToolbox.eigsolve_al) function for Arnoldi-Lindblad eigenvalue solver: ```julia struct ArnoldiLindbladIntegratorMap{T,TS,TI} <: AbstractLinearMap{T,TS} @@ -44,7 +44,7 @@ function LinearAlgebra.mul!(y::AbstractVector, A::ArnoldiLindbladIntegratorMap, end ``` -where `integrator` is the ODE integrator for the time-evolution. In this way, we can diagonalize this linear map using the [`eigsolve`](@ref) function. +where `integrator` is the ODE integrator for the time-evolution. In this way, we can diagonalize this linear map using the [`eigsolve`](@ref QuantumToolbox.eigsolve) function. """ abstract type AbstractLinearMap{T, TS} end diff --git a/lib/QuantumToolboxUtils/src/settings.jl b/lib/QuantumToolboxUtils/src/settings.jl index e5a59538f..e439d326b 100644 --- a/lib/QuantumToolboxUtils/src/settings.jl +++ b/lib/QuantumToolboxUtils/src/settings.jl @@ -21,8 +21,8 @@ Contains all the default global settings of QuantumToolbox.jl and all related li # List of settings -- `tidyup_tol::Float64 = 1.0e-14` : tolerance for [`tidyup`](@ref), [`tidyup!`](@ref) and [`to_sparse`](@ref). -- `auto_tidyup::Bool = true` : Automatically tidyup. +- `tidyup_tol::Float64 = 1.0e-14` : tolerance for [`tidyup`](@ref QuantumToolbox.tidyup), [`tidyup!`](@ref QuantumToolbox.tidyup!) and [`to_sparse`](@ref QuantumToolbox.to_sparse). +- `auto_tidyup::Bool = true` : Automatically `tidyup`. - `ProgressMeterKWARGS::NamedTuple = (showspeed = true, printed = true)` : Default keyword arguments for progress bar in [`ProgressMeter.jl`](https://github.com/timholy/ProgressMeter.jl). This allows the customization of progress bar. For detailed explanation of each settings, see our documentation [here](https://qutip.org/QuantumToolbox.jl/stable/users_guide/settings). diff --git a/lib/QuantumToolboxUtils/src/versioninfo.jl b/lib/QuantumToolboxUtils/src/versioninfo.jl index e1c8bdb79..82388420e 100644 --- a/lib/QuantumToolboxUtils/src/versioninfo.jl +++ b/lib/QuantumToolboxUtils/src/versioninfo.jl @@ -121,14 +121,14 @@ end @doc raw""" QuantumToolbox.versioninfo(io::IO=stdout) -Command line output of information on QuantumToolbox, dependencies, and system information, same as [`QuantumToolbox.about`](@ref). +Command line output of information on QuantumToolbox, dependencies, and system information, same as [`QuantumToolbox.about`](@ref QuantumToolboxUtils.about). """ versioninfo(io::IO = stdout) = _print_versioninfo(io) @doc raw""" QuantumToolbox.about(io::IO=stdout) -Command line output of information on QuantumToolbox, dependencies, and system information, same as [`QuantumToolbox.versioninfo`](@ref). +Command line output of information on QuantumToolbox, dependencies, and system information, same as [`QuantumToolbox.versioninfo`](@ref QuantumToolboxUtils.versioninfo). """ about(io::IO = stdout) = versioninfo(io) From 74a0a8252b3592823d644298a45d1152c3ae161c Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Fri, 24 Apr 2026 12:44:21 +0900 Subject: [PATCH 32/41] add more tests for utils --- lib/QuantumToolboxUtils/test/cite.jl | 4 +- lib/QuantumToolboxUtils/test/linalg.jl | 43 +++++++++++++++++++ .../test/{n_thermal.jl => physics_func.jl} | 14 ++++++ .../test/versioninfo_and_settings.jl | 33 ++++++++++++++ 4 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 lib/QuantumToolboxUtils/test/linalg.jl rename lib/QuantumToolboxUtils/test/{n_thermal.jl => physics_func.jl} (71%) create mode 100644 lib/QuantumToolboxUtils/test/versioninfo_and_settings.jl diff --git a/lib/QuantumToolboxUtils/test/cite.jl b/lib/QuantumToolboxUtils/test/cite.jl index d1dc6dc83..82a7873b8 100644 --- a/lib/QuantumToolboxUtils/test/cite.jl +++ b/lib/QuantumToolboxUtils/test/cite.jl @@ -1,8 +1,8 @@ -@testitem "Cite" begin +@testitem "cite" begin # citation bibtex io_buffer = IOBuffer() - QuantumToolbox.cite(io_buffer) + QuantumToolboxUtils.cite(io_buffer) captured_output = String(take!(io_buffer)) @test captured_output == """@article{QuantumToolbox.jl2025,\n""" * diff --git a/lib/QuantumToolboxUtils/test/linalg.jl b/lib/QuantumToolboxUtils/test/linalg.jl new file mode 100644 index 000000000..4f0da7479 --- /dev/null +++ b/lib/QuantumToolboxUtils/test/linalg.jl @@ -0,0 +1,43 @@ +@testitem "linalg helpers" begin + # row_major_reshape + q = collect(1:12) + q_row_major = row_major_reshape(q, 3, 4) + @test Array(q_row_major) == [1 2 3 4; 5 6 7 8; 9 10 11 12] + + # meshgrid + x = [1, 2, 3] + y = [10, 20] + X, Y = meshgrid(x, y) + @test X == [1 2 3; 1 2 3] + @test Y == [10 10 10; 20 20 20] +end + +@testitem "Arnoldi and expv" begin + import LinearAlgebra: norm + + # Use n = 3 and m = 2 to avoid exact Arnoldi breakdown (and NaN in AS). + A = 0.01 * [1.0 2.0 0.0; 0.0 3.0 4.0; 5.0 0.0 6.0] + b = [1.0, 2.0, 3.0] + m = 2 + + AS = arnoldi(A, b, m) + @test AS.m == m + @test size(AS.V) == (3, 3) + @test size(AS.H) == (3, 2) + @test norm(AS.V[:, 1]) ≈ 1.0 + + x = expv(A, 0.2, b; m = m) + @test x ≈ exp(0.2 * A) * b atol = 1.0e-4 + + x2 = zeros(3) + expv!(x2, AS, 0.2, b) + @test x2 ≈ exp(0.2 * A) * b atol = 1.0e-4 + + # test dimension mismatch + A_bad = [1.0 0.0; 0.0 1.0] + b_bad = [1.0, 0.0] + AS_bad_V = ArnoldiSpace(zeros(3, 3), zeros(3, 2), zeros(3, 2), 2) + AS_bad_b = ArnoldiSpace(zeros(2, 3), zeros(3, 2), zeros(3, 2), 2) + @test_throws DimensionMismatch arnoldi!(AS_bad_V, A_bad, b_bad) + @test_throws DimensionMismatch arnoldi!(AS_bad_b, A_bad, [1.0, 0.0, 0.0]) +end diff --git a/lib/QuantumToolboxUtils/test/n_thermal.jl b/lib/QuantumToolboxUtils/test/physics_func.jl similarity index 71% rename from lib/QuantumToolboxUtils/test/n_thermal.jl rename to lib/QuantumToolboxUtils/test/physics_func.jl index 0dfd4f36a..6a8fb879e 100644 --- a/lib/QuantumToolboxUtils/test/n_thermal.jl +++ b/lib/QuantumToolboxUtils/test/physics_func.jl @@ -1,4 +1,18 @@ +@testitem "gaussian" begin + mu = 0.7 + sigma = 1.2 + delta = 0.4 + + @test gaussian(mu, mu, sigma) == 1.0 + @test gaussian(mu + delta, mu, sigma) ≈ gaussian(mu - delta, mu, sigma) + + @testset "Type Inference" begin + @inferred gaussian(0.1, 0.2, 0.3) + end +end + @testitem "n_thermal" begin + ω1 = rand(Float64) ω2 = rand(Float64) @test n_thermal(0, ω2) == 0.0 diff --git a/lib/QuantumToolboxUtils/test/versioninfo_and_settings.jl b/lib/QuantumToolboxUtils/test/versioninfo_and_settings.jl new file mode 100644 index 000000000..36578cbcb --- /dev/null +++ b/lib/QuantumToolboxUtils/test/versioninfo_and_settings.jl @@ -0,0 +1,33 @@ +@testitem "versioninfo and about" begin + # test error handling + io_wrong = IOBuffer() + push!(QuantumToolboxUtils._QT_LIBRARIES, Base) + @test_throws ArgumentError QuantumToolboxUtils.versioninfo(io_wrong) + deleteat!(QuantumToolboxUtils._QT_LIBRARIES, findall(x -> x == Base, QuantumToolboxUtils._QT_LIBRARIES)) + + # versioninfo + io_version = IOBuffer() + QuantumToolboxUtils.versioninfo(io_version) + version_output = String(take!(io_version)) + @test occursin("QuantumToolbox.jl: Quantum Toolbox in Julia", version_output) + @test occursin("Package information:", version_output) + @test occursin("QuantumToolboxUtils", version_output) + @test occursin("System information:", version_output) + @test occursin("Please cite QuantumToolbox.jl in your publication", version_output) + + # about + io_about = IOBuffer() + QuantumToolboxUtils.about(io_about) + about_output = String(take!(io_about)) + @test version_output == about_output +end + +@testitem "Settings" begin + io = IOBuffer() + show(io, QuantumToolboxUtils.settings) + out = String(take!(io)) + @test occursin("QuantumToolbox.jl Settings", out) + @test occursin("tidyup_tol", out) + @test occursin("auto_tidyup", out) + @test occursin("ProgressMeterKWARGS", out) +end From 71cc36101b344990cac3b582a8f28aad677de3aa Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Fri, 24 Apr 2026 14:26:49 +0900 Subject: [PATCH 33/41] change test group name from `Basic` to `Main` --- .github/copilot-instructions.md | 4 ++-- .github/workflows/CI-Julia-nightly.yml | 2 +- .github/workflows/CI.yml | 4 ++-- docs/src/resources/contributing.md | 8 ++++---- test/runtests.jl | 10 +++++----- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 6e62f5108..2434a7b09 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -82,11 +82,11 @@ QuantumToolbox.settings.ProgressMeterKWARGS = (showspeed=true, printed=true) ### Running Tests ```bash make test # Run all core tests -GROUP=Basic make test # Run Basic tests only +GROUP=Main make test # Run Main tests only GROUP=CUDA_Ext make test # Run CUDA extension tests only ``` -Test groups (set `GROUP` env var): "All", "Basic", "Code-Quality", "AutoDiff_Ext", "Makie_Ext", "CUDA_Ext", "Arbitrary-Precision" +Test groups (set `GROUP` env var): "All", "Main", "Code-Quality", "AutoDiff_Ext", "Makie_Ext", "CUDA_Ext", "Arbitrary-Precision" ### Code Quality & Formatting ```bash diff --git a/.github/workflows/CI-Julia-nightly.yml b/.github/workflows/CI-Julia-nightly.yml index 277c94396..03c87188b 100644 --- a/.github/workflows/CI-Julia-nightly.yml +++ b/.github/workflows/CI-Julia-nightly.yml @@ -47,7 +47,7 @@ jobs: arch: - 'x64' group: - - 'Basic' + - 'Main' steps: - uses: actions/checkout@v6 diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 82c7f0187..413afb69c 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -54,7 +54,7 @@ jobs: - os: 'macOS-latest' arch: 'arm64' group: - - 'Basic' + - 'Main' include: # for core tests (intermediate versions) @@ -62,7 +62,7 @@ jobs: node: os: 'ubuntu-latest' arch: 'x64' - group: 'Basic' + group: 'Main' # for extension tests - version: '1' diff --git a/docs/src/resources/contributing.md b/docs/src/resources/contributing.md index dad9b934e..b255c3409 100644 --- a/docs/src/resources/contributing.md +++ b/docs/src/resources/contributing.md @@ -62,15 +62,15 @@ make test This command will automatically rebuild `Julia` and run the script located in `test/runtests.jl` (should cover both the original tests and the new test(s) you add). -The tests are divided into several test groups, where the group names are defined in the file `test/runtests.jl` with a variable `GROUP`. One can also run the test scripts just for a certain test group by adding an argument `GROUP=` to the `make test` command. For example, to run the tests for group `Basic`, one can use the following command: +The tests are divided into several test groups, where the group names are defined in the file `test/runtests.jl` with a variable `GROUP`. One can also run the test scripts just for a certain test group by adding an argument `GROUP=` to the `make test` command. For example, to run the tests for group `Main`, one can use the following command: ```shell -make GROUP=Basic test +make test GROUP=Main ``` -#### [Test Item Framework for Basic tests](@id doc-Contribute:Test-Item-Framework-for-Basic-tests) +#### [Test Item Framework for Main tests](@id doc-Contribute:Test-Item-Framework-for-Main-tests) -The tests in `GROUP=Basic` are provided using the [Test Item Framework](https://www.julia-vscode.org/docs/stable/userguide/testitems/), which structures the test codes into `@testitems` and makes it easier to run individually. +The tests in `GROUP=Main` are provided using the [Test Item Framework](https://www.julia-vscode.org/docs/stable/userguide/testitems/), which structures the test codes into `@testitems` and makes it easier to run individually. The [VS Code](https://code.visualstudio.com/) and its [Julia extension](https://www.julia-vscode.org/) provides us with options to run individual `@testitems`. It is much easier to find the specific core test that failed since the [Julia extension](https://www.julia-vscode.org/) in [VS Code](https://code.visualstudio.com/) will collect all core test failures and then display them in a structured way, directly at the place in the code where a specific core test failed. See [here](https://www.julia-vscode.org/docs/stable/userguide/testitems/) for more details. diff --git a/test/runtests.jl b/test/runtests.jl index 86a354f3a..8dfbc9f20 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -22,7 +22,7 @@ const EXTENSION_LIST = collect(keys(EXTENSION_PATHS)) const GROUP = get(ENV, "GROUP", "All") const GROUP_LIST = String[ "All", - "Basic", + "Main", "Code-Quality", EXTENSION_LIST..., ] @@ -42,14 +42,14 @@ function setup_subtest_env(path::String) end ####################################### -# Basic tests (use TestItemRunner.jl) # +# Main tests (use TestItemRunner.jl) # ####################################### -if (GROUP == "All") || (GROUP == "Basic") +if (GROUP == "All") || (GROUP == "Main") import QuantumToolbox QuantumToolbox.about() - println("\nStart running Basic tests...") + println("\nStart running Main tests...") # tests in lib folder for each library # PATH: lib/LIBRARY_NAME/test/ @@ -62,7 +62,7 @@ if (GROUP == "All") || (GROUP == "Basic") println("\n[QuantumToolbox]") @run_package_tests filter = ti -> !occursin("lib", ti.filename) verbose = true - println("\n===============> Basic tests completed <===============\n") + println("\n===============> Main tests completed <===============\n") end ######################################################################## From 6ff0a24439058f7ced1a73adbaf23631fb4dc32e Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Tue, 28 Apr 2026 15:13:46 +0800 Subject: [PATCH 34/41] remove `row_major_reshape` --- docs/src/resources/api.md | 1 - lib/QuantumToolboxUtils/src/linalg/linalg.jl | 10 +--------- lib/QuantumToolboxUtils/test/linalg.jl | 5 ----- 3 files changed, 1 insertion(+), 15 deletions(-) diff --git a/docs/src/resources/api.md b/docs/src/resources/api.md index 0b5e50ca1..915d1660c 100644 --- a/docs/src/resources/api.md +++ b/docs/src/resources/api.md @@ -19,7 +19,6 @@ settings versioninfo about cite -row_major_reshape meshgrid AbstractLinearMap gaussian diff --git a/lib/QuantumToolboxUtils/src/linalg/linalg.jl b/lib/QuantumToolboxUtils/src/linalg/linalg.jl index 4de0285dc..320fd72eb 100644 --- a/lib/QuantumToolboxUtils/src/linalg/linalg.jl +++ b/lib/QuantumToolboxUtils/src/linalg/linalg.jl @@ -1,12 +1,4 @@ -export row_major_reshape, meshgrid - -@doc raw""" - row_major_reshape(Q::AbstractArray, shapes...) - -Reshapes `Q` in the row-major order, as numpy. -""" -row_major_reshape(Q::AbstractArray{T}, shapes...) where {T} = - PermutedDimsArray(reshape(Q, reverse(shapes)...), (length(shapes):-1:1)) +export meshgrid @doc raw""" meshgrid(x::AbstractVector, y::AbstractVector) diff --git a/lib/QuantumToolboxUtils/test/linalg.jl b/lib/QuantumToolboxUtils/test/linalg.jl index 4f0da7479..31f412628 100644 --- a/lib/QuantumToolboxUtils/test/linalg.jl +++ b/lib/QuantumToolboxUtils/test/linalg.jl @@ -1,9 +1,4 @@ @testitem "linalg helpers" begin - # row_major_reshape - q = collect(1:12) - q_row_major = row_major_reshape(q, 3, 4) - @test Array(q_row_major) == [1 2 3 4; 5 6 7 8; 9 10 11 12] - # meshgrid x = [1, 2, 3] y = [10, 20] From c68d51d5093ead1ad962abed4ffc95e13ea521e2 Mon Sep 17 00:00:00 2001 From: Yi-Te Huang <44385685+ytdHuang@users.noreply.github.com> Date: Fri, 1 May 2026 12:00:34 +0800 Subject: [PATCH 35/41] minor change for tests --- .buildkite/CUDA_Ext.yml | 4 +-- .github/copilot-instructions.md | 4 +-- .github/workflows/CI.yml | 4 +-- test/runtests.jl | 44 ++++++++++++++++++++++----------- 4 files changed, 36 insertions(+), 20 deletions(-) diff --git a/.buildkite/CUDA_Ext.yml b/.buildkite/CUDA_Ext.yml index ebc2d0a4a..6db9c208b 100644 --- a/.buildkite/CUDA_Ext.yml +++ b/.buildkite/CUDA_Ext.yml @@ -27,7 +27,7 @@ steps: Pkg.test(; test_args=["--quickfail"]) ' env: - GROUP: "CUDA_Ext" + GROUP: "CUDA-Ext" SECRET_CODECOV_TOKEN: "ZfhQu/IcRLqNyZ//ZNs5sjBPaV76IHfU5gui52Qn+Rp8tOurukqgScuyDt+3HQ4R0hJYBw1/Nqg6jmBsvWSc9NEUx8kGsUJFHfN3no0+b+PFxA8oJkWc9EpyIsjht5ZIjlsFWR3f0DpPqMEle/QyWOPcal63CChXR8oAoR+Fz1Bh8GkokLlnC8F9Ugp9xBlu401GCbyZhvLTZnNIgK5yy9q8HBJnBg1cPOhI81J6JvYpEmcIofEzFV/qkfpTUPclu43WNoFX2DZPzbxilf3fsAd5/+nRkRfkNML8KiN4mnmjHxPPbuY8F5zC/PS5ybXtDpfvaMQc01WApXCkZk0ZAQ==;U2FsdGVkX1+eDT7dqCME5+Ox5i8GvWRTQbwiP/VYjapThDbxXFDeSSIC6Opmon+M8go22Bun3bat6Fzie65ang==" timeout_in_minutes: 60 @@ -52,6 +52,6 @@ steps: queue: "juliagpu" cuda: "*" env: - GROUP: "CUDA_Ext" + GROUP: "CUDA-Ext" SECRET_CODECOV_TOKEN: "ZfhQu/IcRLqNyZ//ZNs5sjBPaV76IHfU5gui52Qn+Rp8tOurukqgScuyDt+3HQ4R0hJYBw1/Nqg6jmBsvWSc9NEUx8kGsUJFHfN3no0+b+PFxA8oJkWc9EpyIsjht5ZIjlsFWR3f0DpPqMEle/QyWOPcal63CChXR8oAoR+Fz1Bh8GkokLlnC8F9Ugp9xBlu401GCbyZhvLTZnNIgK5yy9q8HBJnBg1cPOhI81J6JvYpEmcIofEzFV/qkfpTUPclu43WNoFX2DZPzbxilf3fsAd5/+nRkRfkNML8KiN4mnmjHxPPbuY8F5zC/PS5ybXtDpfvaMQc01WApXCkZk0ZAQ==;U2FsdGVkX1+eDT7dqCME5+Ox5i8GvWRTQbwiP/VYjapThDbxXFDeSSIC6Opmon+M8go22Bun3bat6Fzie65ang==" timeout_in_minutes: 60 diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 2434a7b09..4a7028bb4 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -83,10 +83,10 @@ QuantumToolbox.settings.ProgressMeterKWARGS = (showspeed=true, printed=true) ```bash make test # Run all core tests GROUP=Main make test # Run Main tests only -GROUP=CUDA_Ext make test # Run CUDA extension tests only +GROUP=CUDA-Ext make test # Run CUDA extension tests only ``` -Test groups (set `GROUP` env var): "All", "Main", "Code-Quality", "AutoDiff_Ext", "Makie_Ext", "CUDA_Ext", "Arbitrary-Precision" +Test groups (set `GROUP` env var): "All", "Main", "Code-Quality", "AutoDiff-Ext", "Makie-Ext", "CUDA-Ext", "Arbitrary-Precision" ### Code Quality & Formatting ```bash diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 413afb69c..9e840ea8c 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -69,12 +69,12 @@ jobs: node: os: 'ubuntu-latest' arch: 'x64' - group: 'Makie_Ext' + group: 'Makie-Ext' - version: '1.12' node: os: 'ubuntu-latest' arch: 'x64' - group: 'AutoDiff_Ext' + group: 'AutoDiff-Ext' - version: '1' node: os: 'ubuntu-latest' diff --git a/test/runtests.jl b/test/runtests.jl index 8dfbc9f20..dd3795ea6 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -5,18 +5,19 @@ using Pkg const testdir = dirname(@__FILE__) # Define the paths to the library -const LIBRARY_PATHS = Dict( - "QuantumToolboxUtils" => joinpath(testdir, "..", "lib", "QuantumToolboxUtils"), +const LIBRARY_NAME_AND_PATH = Dict( + "Utils" => ("QuantumToolboxUtils", joinpath(testdir, "..", "lib", "QuantumToolboxUtils")), ) +const LIBRARY_LIST = collect(keys(LIBRARY_NAME_AND_PATH)) # Define the paths to the extension tests -const EXTENSION_PATHS = Dict( - "AutoDiff_Ext" => joinpath(testdir, "ext-test", "cpu", "autodiff"), - "Makie_Ext" => joinpath(testdir, "ext-test", "cpu", "makie"), - "CUDA_Ext" => joinpath(testdir, "ext-test", "gpu"), +const EXTENSION_PATH = Dict( + "AutoDiff-Ext" => joinpath(testdir, "ext-test", "cpu", "autodiff"), + "Makie-Ext" => joinpath(testdir, "ext-test", "cpu", "makie"), + "CUDA-Ext" => joinpath(testdir, "ext-test", "gpu"), "Arbitrary-Precision" => joinpath(testdir, "ext-test", "cpu", "arbitrary_precision"), ) -const EXTENSION_LIST = collect(keys(EXTENSION_PATHS)) +const EXTENSION_LIST = collect(keys(EXTENSION_PATH)) # Handle the GROUP environment variable to determine which tests to run const GROUP = get(ENV, "GROUP", "All") @@ -24,6 +25,7 @@ const GROUP_LIST = String[ "All", "Main", "Code-Quality", + LIBRARY_LIST..., EXTENSION_LIST..., ] (GROUP in GROUP_LIST) || throw(ArgumentError("Unknown GROUP = $GROUP\nThe allowed groups are: $GROUP_LIST\n")) @@ -32,7 +34,8 @@ const GROUP_LIST = String[ function setup_subtest_env(path::String) Pkg.activate(path) if VERSION < v"1.11" - for (_, lib_path) in LIBRARY_PATHS + for lib in LIBRARY_LIST + _, lib_path = LIBRARY_NAME_AND_PATH[lib] Pkg.develop(path = lib_path) end end @@ -53,7 +56,8 @@ if (GROUP == "All") || (GROUP == "Main") # tests in lib folder for each library # PATH: lib/LIBRARY_NAME/test/ - for (lib_name, _) in LIBRARY_PATHS + for lib in LIBRARY_LIST + lib_name, _ = LIBRARY_NAME_AND_PATH[lib] println("\n[$lib_name]") @run_package_tests filter = ti -> occursin(joinpath("lib", lib_name, "test"), ti.filename) verbose = true end @@ -65,6 +69,17 @@ if (GROUP == "All") || (GROUP == "Main") println("\n===============> Main tests completed <===============\n") end +# only run tests for a specific library +if GROUP ∈ LIBRARY_LIST + import QuantumToolbox + + QuantumToolbox.about() + + lib_name, _ = LIBRARY_NAME_AND_PATH[GROUP] + println("\n[$lib_name]") + @run_package_tests filter = ti -> occursin(joinpath("lib", lib_name, "test"), ti.filename) verbose = true +end + ######################################################################## # Use traditional Test.jl instead of TestItemRunner.jl for other tests # ######################################################################## @@ -80,7 +95,8 @@ if (GROUP == "All") || (GROUP == "Code-Quality") (GROUP == "Code-Quality") && QuantumToolbox.about() # print version info. for code quality CI in GitHub # run code quality tests for all libraries and the main package - for (_, lib_path) in LIBRARY_PATHS + for lib in LIBRARY_LIST + _, lib_path = LIBRARY_NAME_AND_PATH[lib] include(joinpath(lib_path, "test", "code_quality.jl")) end include(joinpath(path, "code_quality.jl")) @@ -88,15 +104,15 @@ end # Extension tests if GROUP ∈ EXTENSION_LIST - path = EXTENSION_PATHS[GROUP] + path = EXTENSION_PATH[GROUP] setup_subtest_env(path) - if GROUP == "AutoDiff_Ext" + if GROUP == "AutoDiff-Ext" println(Pkg.status()) include(joinpath(path, "autodiff.jl")) - elseif GROUP == "Makie_Ext" + elseif GROUP == "Makie-Ext" include(joinpath(path, "makie_ext.jl")) - elseif GROUP == "CUDA_Ext" + elseif GROUP == "CUDA-Ext" include(joinpath(path, "cuda_ext.jl")) elseif GROUP == "Arbitrary-Precision" include(joinpath(path, "arbitrary_precision.jl")) From 64d64906ccdbc53949e6a5ce9ed6a0541bb017ff Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Tue, 28 Jul 2026 11:37:50 +0200 Subject: [PATCH 36/41] change library name from `Utils` to `Core` --- .github/workflows/bump-version.yml | 2 +- CHANGELOG.md | 2 +- Project.toml | 6 +++--- docs/Project.toml | 4 ++-- docs/make.jl | 4 ++-- docs/src/index.md | 2 +- docs/src/resources/api.md | 6 +++--- docs/src/users_guide/settings.md | 4 ++-- .../LICENSE | 0 .../Project.toml | 4 ++-- .../src/PhysicalConstants.jl | 0 .../src/QuantumToolboxCore.jl} | 4 ++-- .../src/deprecated.jl | 0 .../src/linalg/arnoldi.jl | 0 .../src/linalg/linalg.jl | 0 .../src/linalg/linear_maps.jl | 0 .../src/physics_func.jl | 0 .../src/settings.jl | 0 .../src/type_handle.jl | 0 .../src/versioninfo.jl | 10 +++++----- .../test/PhysicalConstants.jl | 0 .../test/cite.jl | 2 +- lib/QuantumToolboxCore/test/code_quality.jl | 9 +++++++++ .../test/linalg.jl | 0 .../test/physics_func.jl | 0 .../test/versioninfo_and_settings.jl | 14 +++++++------- lib/QuantumToolboxUtils/test/code_quality.jl | 9 --------- src/QuantumToolbox.jl | 10 +++++----- src/core_overload.jl | 13 +++++++++++++ src/utils.jl | 13 ------------- test/code-quality/Project.toml | 4 ++-- test/runtests.jl | 2 +- 32 files changed, 62 insertions(+), 62 deletions(-) rename lib/{QuantumToolboxUtils => QuantumToolboxCore}/LICENSE (100%) rename lib/{QuantumToolboxUtils => QuantumToolboxCore}/Project.toml (86%) rename lib/{QuantumToolboxUtils => QuantumToolboxCore}/src/PhysicalConstants.jl (100%) rename lib/{QuantumToolboxUtils/src/QuantumToolboxUtils.jl => QuantumToolboxCore/src/QuantumToolboxCore.jl} (89%) rename lib/{QuantumToolboxUtils => QuantumToolboxCore}/src/deprecated.jl (100%) rename lib/{QuantumToolboxUtils => QuantumToolboxCore}/src/linalg/arnoldi.jl (100%) rename lib/{QuantumToolboxUtils => QuantumToolboxCore}/src/linalg/linalg.jl (100%) rename lib/{QuantumToolboxUtils => QuantumToolboxCore}/src/linalg/linear_maps.jl (100%) rename lib/{QuantumToolboxUtils => QuantumToolboxCore}/src/physics_func.jl (100%) rename lib/{QuantumToolboxUtils => QuantumToolboxCore}/src/settings.jl (100%) rename lib/{QuantumToolboxUtils => QuantumToolboxCore}/src/type_handle.jl (100%) rename lib/{QuantumToolboxUtils => QuantumToolboxCore}/src/versioninfo.jl (95%) rename lib/{QuantumToolboxUtils => QuantumToolboxCore}/test/PhysicalConstants.jl (100%) rename lib/{QuantumToolboxUtils => QuantumToolboxCore}/test/cite.jl (95%) create mode 100644 lib/QuantumToolboxCore/test/code_quality.jl rename lib/{QuantumToolboxUtils => QuantumToolboxCore}/test/linalg.jl (100%) rename lib/{QuantumToolboxUtils => QuantumToolboxCore}/test/physics_func.jl (100%) rename lib/{QuantumToolboxUtils => QuantumToolboxCore}/test/versioninfo_and_settings.jl (67%) delete mode 100644 lib/QuantumToolboxUtils/test/code_quality.jl create mode 100644 src/core_overload.jl delete mode 100644 src/utils.jl diff --git a/.github/workflows/bump-version.yml b/.github/workflows/bump-version.yml index 2ef51be19..ad28ef157 100644 --- a/.github/workflows/bump-version.yml +++ b/.github/workflows/bump-version.yml @@ -10,7 +10,7 @@ on: type: choice options: - QuantumToolbox - - QuantumToolboxUtils + - QuantumToolboxCore bump_type: description: 'Version bump type' required: true diff --git a/CHANGELOG.md b/CHANGELOG.md index 7fde5d334..32bd6cee4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased](https://github.com/qutip/QuantumToolbox.jl/tree/main) -- [lib] Introduce QuantumToolboxUtils library. ([#686]) +- [lib] Introduce `QuantumToolboxCore` library. ([#686]) - Add documentation about arbitrary precision computations. ([#745]) - Fix `e_ops` expectation values being always stored as `ComplexF64` in `sesolve`, `mesolve`, `mcsolve`, `ssesolve`, and `smesolve`. They now follow the element type of the problem, so that arbitrary precision solutions return `sol.expect` with the requested precision instead of silently narrowing it to double precision. ([#745]) - Fix `sesolve_map` and `mesolve_map` sharing mutable e_ops-saving callback state across trajectories when a custom `prob_func` is supplied, which could throw a `BoundsError` or produce incorrect results. Both now accept a `safetycopy` keyword (smart-defaulting to `true` for a custom `prob_func`, `false` otherwise) mirroring `SciMLBase.EnsembleProblem`. ([#645], [#747]) diff --git a/Project.toml b/Project.toml index d056ebd11..ed4b60af0 100644 --- a/Project.toml +++ b/Project.toml @@ -20,7 +20,7 @@ OrdinaryDiffEqLowOrderRK = "1344f307-1e59-4825-a18e-ace9aa3fa4c6" OrdinaryDiffEqVerner = "79d7bb75-1356-48c1-b8c0-6832512096c2" Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" ProgressMeter = "92933f4c-e287-5a05-a399-4b506db050ca" -QuantumToolboxUtils = "02afad9e-e2b8-4f9a-965f-b5dca5b538ca" +QuantumToolboxCore = "7fbe806f-1706-4992-b132-86e53e431434" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" Reexport = "189a3867-3050-52da-a836-e630ba90ab69" SciMLBase = "0bca4576-84f4-4d90-8ffe-ffa030f20462" @@ -40,7 +40,7 @@ KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c" Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" [sources] -QuantumToolboxUtils = {path = "lib/QuantumToolboxUtils"} +QuantumToolboxCore = {path = "lib/QuantumToolboxCore"} [extensions] QuantumToolboxCUDAExt = ["CUDACore", "cuSPARSE"] @@ -71,7 +71,7 @@ OrdinaryDiffEqLowOrderRK = "2" OrdinaryDiffEqVerner = "2" Pkg = "1" ProgressMeter = "1.11.0" -QuantumToolboxUtils = "0.1" +QuantumToolboxCore = "0.1" Random = "1" Reexport = "1" SciMLBase = "3" diff --git a/docs/Project.toml b/docs/Project.toml index f88419128..3835f71c0 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -10,12 +10,12 @@ ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" GenericSchur = "c145ed77-6b09-5dd9-b285-bf645a82121e" Mooncake = "da2b9cff-9c12-43a0-ae48-6db2b0edb7d6" QuantumToolbox = "6c2fb7c5-b903-41d2-bc5e-5a7c320b9fab" -QuantumToolboxUtils = "02afad9e-e2b8-4f9a-965f-b5dca5b538ca" +QuantumToolboxCore = "7fbe806f-1706-4992-b132-86e53e431434" SciMLSensitivity = "1ed8b502-d754-442c-8d5d-10ac956f44a1" [sources] QuantumToolbox = {path = ".."} -QuantumToolboxUtils = {path = "../lib/QuantumToolboxUtils"} +QuantumToolboxCore = {path = "../lib/QuantumToolboxCore"} [compat] DocumenterVitepress = "0.3" diff --git a/docs/make.jl b/docs/make.jl index e047fd863..38f347afc 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -12,7 +12,7 @@ const DRAFT = get(ENV, "DRAFT", false) == "true" # `DRAFT = true` disables c const DOCTEST = get(ENV, "DOCTEST", true) == true # `DOCTEST = false` skips doc tests if DOCTEST - DocMeta.setdocmeta!(QuantumToolboxUtils, :DocTestSetup, :(using QuantumToolboxUtils); recursive = true) + DocMeta.setdocmeta!(QuantumToolboxCore, :DocTestSetup, :(using QuantumToolboxCore); recursive = true) DocMeta.setdocmeta!(QuantumToolbox, :DocTestSetup, :(using QuantumToolbox, LinearAlgebra, SparseArrays); recursive = true) end @@ -81,7 +81,7 @@ const PAGES = [ makedocs(; modules = [ - QuantumToolboxUtils, + QuantumToolboxCore, QuantumToolbox, Base.get_extension(QuantumToolbox, :QuantumToolboxMakieExt), ], diff --git a/docs/src/index.md b/docs/src/index.md index 8a06738e0..00fddc719 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -86,7 +86,7 @@ Alternatively, this can also be done in `Julia`'s [Pkg REPL](https://julialang.g ``` More information about `Julia`'s package manager can be found at [`Pkg.jl`](https://julialang.github.io/Pkg.jl/v1/). -To load the package and check the version information, use either [`QuantumToolbox.versioninfo()`](@ref QuantumToolboxUtils.versioninfo) or [`QuantumToolbox.about()`](@ref QuantumToolboxUtils.about), namely +To load the package and check the version information, use either [`QuantumToolbox.versioninfo()`](@ref QuantumToolboxCore.versioninfo) or [`QuantumToolbox.about()`](@ref QuantumToolboxCore.about), namely ```julia using QuantumToolbox QuantumToolbox.versioninfo() diff --git a/docs/src/resources/api.md b/docs/src/resources/api.md index b56e0ceaf..dee1f5992 100644 --- a/docs/src/resources/api.md +++ b/docs/src/resources/api.md @@ -4,13 +4,13 @@ [[toc]] -## [QuantumToolboxUtils](@id doc-API:QuantumToolboxUtils) +## [QuantumToolboxCore](@id doc-API:QuantumToolboxCore) ```@meta -CurrentModule = QuantumToolboxUtils +CurrentModule = QuantumToolboxCore DocTestSetup = quote - using QuantumToolboxUtils + using QuantumToolboxCore end ``` diff --git a/docs/src/users_guide/settings.md b/docs/src/users_guide/settings.md index 78b01a25e..a3b64d601 100644 --- a/docs/src/users_guide/settings.md +++ b/docs/src/users_guide/settings.md @@ -2,7 +2,7 @@ In this section, we introduce the default global settings used throughout the package and show how to modify them. -All settings are stored in [`QuantumToolbox.settings`](@ref QuantumToolboxUtils.settings). +All settings are stored in [`QuantumToolbox.settings`](@ref QuantumToolboxCore.settings). !!! warning "Differences from QuTiP" Due to the differences in programming languages, solving algorithms, and many other reasons, these global settings (including their default values and usage) may be very different from those in `Python QuTiP`. @@ -20,7 +20,7 @@ Here, we list out each setting along with the specific functions that will use i ## Change default settings -First, we can check the current [`QuantumToolbox.settings`](@ref QuantumToolboxUtils.settings): +First, we can check the current [`QuantumToolbox.settings`](@ref QuantumToolboxCore.settings): ```@example settings using QuantumToolbox diff --git a/lib/QuantumToolboxUtils/LICENSE b/lib/QuantumToolboxCore/LICENSE similarity index 100% rename from lib/QuantumToolboxUtils/LICENSE rename to lib/QuantumToolboxCore/LICENSE diff --git a/lib/QuantumToolboxUtils/Project.toml b/lib/QuantumToolboxCore/Project.toml similarity index 86% rename from lib/QuantumToolboxUtils/Project.toml rename to lib/QuantumToolboxCore/Project.toml index 69b9116e7..ad1c05ed0 100644 --- a/lib/QuantumToolboxUtils/Project.toml +++ b/lib/QuantumToolboxCore/Project.toml @@ -1,5 +1,5 @@ -name = "QuantumToolboxUtils" -uuid = "02afad9e-e2b8-4f9a-965f-b5dca5b538ca" +name = "QuantumToolboxCore" +uuid = "7fbe806f-1706-4992-b132-86e53e431434" authors = ["Alberto Mercurio", "Yi-Te Huang"] version = "0.1.0" diff --git a/lib/QuantumToolboxUtils/src/PhysicalConstants.jl b/lib/QuantumToolboxCore/src/PhysicalConstants.jl similarity index 100% rename from lib/QuantumToolboxUtils/src/PhysicalConstants.jl rename to lib/QuantumToolboxCore/src/PhysicalConstants.jl diff --git a/lib/QuantumToolboxUtils/src/QuantumToolboxUtils.jl b/lib/QuantumToolboxCore/src/QuantumToolboxCore.jl similarity index 89% rename from lib/QuantumToolboxUtils/src/QuantumToolboxUtils.jl rename to lib/QuantumToolboxCore/src/QuantumToolboxCore.jl index 45de9f7dc..e414cb189 100644 --- a/lib/QuantumToolboxUtils/src/QuantumToolboxUtils.jl +++ b/lib/QuantumToolboxCore/src/QuantumToolboxCore.jl @@ -1,4 +1,4 @@ -module QuantumToolboxUtils +module QuantumToolboxCore using LinearAlgebra using SparseArrays @@ -25,7 +25,7 @@ include("physics_func.jl") include("deprecated.jl") function __init__() - _register_qt_library!(QuantumToolboxUtils) + _register_qt_library!(QuantumToolboxCore) return nothing end diff --git a/lib/QuantumToolboxUtils/src/deprecated.jl b/lib/QuantumToolboxCore/src/deprecated.jl similarity index 100% rename from lib/QuantumToolboxUtils/src/deprecated.jl rename to lib/QuantumToolboxCore/src/deprecated.jl diff --git a/lib/QuantumToolboxUtils/src/linalg/arnoldi.jl b/lib/QuantumToolboxCore/src/linalg/arnoldi.jl similarity index 100% rename from lib/QuantumToolboxUtils/src/linalg/arnoldi.jl rename to lib/QuantumToolboxCore/src/linalg/arnoldi.jl diff --git a/lib/QuantumToolboxUtils/src/linalg/linalg.jl b/lib/QuantumToolboxCore/src/linalg/linalg.jl similarity index 100% rename from lib/QuantumToolboxUtils/src/linalg/linalg.jl rename to lib/QuantumToolboxCore/src/linalg/linalg.jl diff --git a/lib/QuantumToolboxUtils/src/linalg/linear_maps.jl b/lib/QuantumToolboxCore/src/linalg/linear_maps.jl similarity index 100% rename from lib/QuantumToolboxUtils/src/linalg/linear_maps.jl rename to lib/QuantumToolboxCore/src/linalg/linear_maps.jl diff --git a/lib/QuantumToolboxUtils/src/physics_func.jl b/lib/QuantumToolboxCore/src/physics_func.jl similarity index 100% rename from lib/QuantumToolboxUtils/src/physics_func.jl rename to lib/QuantumToolboxCore/src/physics_func.jl diff --git a/lib/QuantumToolboxUtils/src/settings.jl b/lib/QuantumToolboxCore/src/settings.jl similarity index 100% rename from lib/QuantumToolboxUtils/src/settings.jl rename to lib/QuantumToolboxCore/src/settings.jl diff --git a/lib/QuantumToolboxUtils/src/type_handle.jl b/lib/QuantumToolboxCore/src/type_handle.jl similarity index 100% rename from lib/QuantumToolboxUtils/src/type_handle.jl rename to lib/QuantumToolboxCore/src/type_handle.jl diff --git a/lib/QuantumToolboxUtils/src/versioninfo.jl b/lib/QuantumToolboxCore/src/versioninfo.jl similarity index 95% rename from lib/QuantumToolboxUtils/src/versioninfo.jl rename to lib/QuantumToolboxCore/src/versioninfo.jl index 82388420e..0699234e4 100644 --- a/lib/QuantumToolboxUtils/src/versioninfo.jl +++ b/lib/QuantumToolboxCore/src/versioninfo.jl @@ -21,7 +21,7 @@ raw""" Add new dependencies to `DEPpkgs` for the specified library. Extend this function in each QuantumToolbox library to declare its external (non-QuantumToolbox) dependencies. """ _add_library_deps!(lib::Val{T}, DEPpkgs::Vector{Module}) where {T} = throw(ArgumentError("Unknown QuantumToolbox library : $T")) -function _add_library_deps!(lib::Val{:QuantumToolboxUtils}, DEPpkgs::Vector{Module}) +function _add_library_deps!(lib::Val{:QuantumToolboxCore}, DEPpkgs::Vector{Module}) _add_pkgs!(DEPpkgs, Module[SciMLOperators]) return nothing end @@ -35,7 +35,7 @@ function _add_pkgs!(pkgs1::Vector{Module}, pkgs2::Vector{Module}) end raw""" - QuantumToolboxUtils.pkginfo(io::IO=stdout; pkgs::Vector{Module} = Module[]) + QuantumToolboxCore.pkginfo(io::IO=stdout; pkgs::Vector{Module} = Module[]) Command line output of version numbers for given vector of packages: `pkgs`. """ @@ -60,7 +60,7 @@ function pkginfo(io::IO = stdout; pkgs::Vector{Module} = Module[], split_after:: end raw""" - QuantumToolboxUtils.sysinfo(io::IO=stdout) + QuantumToolboxCore.sysinfo(io::IO=stdout) Command line output of system information. """ @@ -121,14 +121,14 @@ end @doc raw""" QuantumToolbox.versioninfo(io::IO=stdout) -Command line output of information on QuantumToolbox, dependencies, and system information, same as [`QuantumToolbox.about`](@ref QuantumToolboxUtils.about). +Command line output of information on QuantumToolbox, dependencies, and system information, same as [`QuantumToolbox.about`](@ref QuantumToolboxCore.about). """ versioninfo(io::IO = stdout) = _print_versioninfo(io) @doc raw""" QuantumToolbox.about(io::IO=stdout) -Command line output of information on QuantumToolbox, dependencies, and system information, same as [`QuantumToolbox.versioninfo`](@ref QuantumToolboxUtils.versioninfo). +Command line output of information on QuantumToolbox, dependencies, and system information, same as [`QuantumToolbox.versioninfo`](@ref QuantumToolboxCore.versioninfo). """ about(io::IO = stdout) = versioninfo(io) diff --git a/lib/QuantumToolboxUtils/test/PhysicalConstants.jl b/lib/QuantumToolboxCore/test/PhysicalConstants.jl similarity index 100% rename from lib/QuantumToolboxUtils/test/PhysicalConstants.jl rename to lib/QuantumToolboxCore/test/PhysicalConstants.jl diff --git a/lib/QuantumToolboxUtils/test/cite.jl b/lib/QuantumToolboxCore/test/cite.jl similarity index 95% rename from lib/QuantumToolboxUtils/test/cite.jl rename to lib/QuantumToolboxCore/test/cite.jl index 82a7873b8..35e8ea6c8 100644 --- a/lib/QuantumToolboxUtils/test/cite.jl +++ b/lib/QuantumToolboxCore/test/cite.jl @@ -2,7 +2,7 @@ # citation bibtex io_buffer = IOBuffer() - QuantumToolboxUtils.cite(io_buffer) + QuantumToolboxCore.cite(io_buffer) captured_output = String(take!(io_buffer)) @test captured_output == """@article{QuantumToolbox.jl2025,\n""" * diff --git a/lib/QuantumToolboxCore/test/code_quality.jl b/lib/QuantumToolboxCore/test/code_quality.jl new file mode 100644 index 000000000..b2c305087 --- /dev/null +++ b/lib/QuantumToolboxCore/test/code_quality.jl @@ -0,0 +1,9 @@ +@testset "Code quality (QuantumToolboxCore)" verbose = true begin + @testset "Aqua.jl" begin + Aqua.test_all(QuantumToolboxCore; ambiguities = false, unbound_args = false) + end + + @testset "JET.jl" begin + JET.test_package(QuantumToolboxCore; target_modules = (QuantumToolboxCore,), ignore_missing_comparison = true) + end +end diff --git a/lib/QuantumToolboxUtils/test/linalg.jl b/lib/QuantumToolboxCore/test/linalg.jl similarity index 100% rename from lib/QuantumToolboxUtils/test/linalg.jl rename to lib/QuantumToolboxCore/test/linalg.jl diff --git a/lib/QuantumToolboxUtils/test/physics_func.jl b/lib/QuantumToolboxCore/test/physics_func.jl similarity index 100% rename from lib/QuantumToolboxUtils/test/physics_func.jl rename to lib/QuantumToolboxCore/test/physics_func.jl diff --git a/lib/QuantumToolboxUtils/test/versioninfo_and_settings.jl b/lib/QuantumToolboxCore/test/versioninfo_and_settings.jl similarity index 67% rename from lib/QuantumToolboxUtils/test/versioninfo_and_settings.jl rename to lib/QuantumToolboxCore/test/versioninfo_and_settings.jl index 36578cbcb..957bb03f7 100644 --- a/lib/QuantumToolboxUtils/test/versioninfo_and_settings.jl +++ b/lib/QuantumToolboxCore/test/versioninfo_and_settings.jl @@ -1,30 +1,30 @@ @testitem "versioninfo and about" begin # test error handling io_wrong = IOBuffer() - push!(QuantumToolboxUtils._QT_LIBRARIES, Base) - @test_throws ArgumentError QuantumToolboxUtils.versioninfo(io_wrong) - deleteat!(QuantumToolboxUtils._QT_LIBRARIES, findall(x -> x == Base, QuantumToolboxUtils._QT_LIBRARIES)) + push!(QuantumToolboxCore._QT_LIBRARIES, Base) + @test_throws ArgumentError QuantumToolboxCore.versioninfo(io_wrong) + deleteat!(QuantumToolboxCore._QT_LIBRARIES, findall(x -> x == Base, QuantumToolboxCore._QT_LIBRARIES)) # versioninfo io_version = IOBuffer() - QuantumToolboxUtils.versioninfo(io_version) + QuantumToolboxCore.versioninfo(io_version) version_output = String(take!(io_version)) @test occursin("QuantumToolbox.jl: Quantum Toolbox in Julia", version_output) @test occursin("Package information:", version_output) - @test occursin("QuantumToolboxUtils", version_output) + @test occursin("QuantumToolboxCore", version_output) @test occursin("System information:", version_output) @test occursin("Please cite QuantumToolbox.jl in your publication", version_output) # about io_about = IOBuffer() - QuantumToolboxUtils.about(io_about) + QuantumToolboxCore.about(io_about) about_output = String(take!(io_about)) @test version_output == about_output end @testitem "Settings" begin io = IOBuffer() - show(io, QuantumToolboxUtils.settings) + show(io, QuantumToolboxCore.settings) out = String(take!(io)) @test occursin("QuantumToolbox.jl Settings", out) @test occursin("tidyup_tol", out) diff --git a/lib/QuantumToolboxUtils/test/code_quality.jl b/lib/QuantumToolboxUtils/test/code_quality.jl deleted file mode 100644 index c31a5cb8f..000000000 --- a/lib/QuantumToolboxUtils/test/code_quality.jl +++ /dev/null @@ -1,9 +0,0 @@ -@testset "Code quality (QuantumToolboxUtils)" verbose = true begin - @testset "Aqua.jl" begin - Aqua.test_all(QuantumToolboxUtils; ambiguities = false, unbound_args = false) - end - - @testset "JET.jl" begin - JET.test_package(QuantumToolboxUtils; target_modules = (QuantumToolboxUtils,), ignore_missing_comparison = true) - end -end diff --git a/src/QuantumToolbox.jl b/src/QuantumToolbox.jl index 2ac1254c2..9fc10909b 100644 --- a/src/QuantumToolbox.jl +++ b/src/QuantumToolbox.jl @@ -13,10 +13,10 @@ import Statistics: mean, std ## Re-export of QuantumToolbox libraries import Reexport: @reexport -@reexport using QuantumToolboxUtils +@reexport using QuantumToolboxCore ## internal functions of QuantumToolbox libraries -import QuantumToolboxUtils: +import QuantumToolboxCore: FloatOrComplex, getVal, makeVal, @@ -109,8 +109,8 @@ export cache_operator, iscached, isconstant # Source files -## Some overloading with QuantumToolboxUtils library -include("utils.jl") +## Some overloading with QuantumToolboxCore library +include("core_overload.jl") ## Quantum Object include("qobj/dimensions.jl") @@ -166,7 +166,7 @@ include("visualization/wigner.jl") include("deprecated.jl") function __init__() - QuantumToolboxUtils._register_qt_library!(QuantumToolbox) + QuantumToolboxCore._register_qt_library!(QuantumToolbox) return nothing end diff --git a/src/core_overload.jl b/src/core_overload.jl new file mode 100644 index 000000000..a587a684f --- /dev/null +++ b/src/core_overload.jl @@ -0,0 +1,13 @@ +#= +Some alias and overloading functions from QuantumToolboxCore +=# + +function QuantumToolboxCore._add_library_deps!(lib::Val{:QuantumToolbox}, DEPpkgs::Vector{Module}) + QuantumToolboxCore._add_pkgs!(DEPpkgs, Module[SciMLBase, SciMLOperators, OrdinaryDiffEqCore, LinearSolve]) + return nothing +end + +const settings = QuantumToolboxCore.settings +const versioninfo = QuantumToolboxCore.versioninfo +const about = QuantumToolboxCore.about +const cite = QuantumToolboxCore.cite diff --git a/src/utils.jl b/src/utils.jl deleted file mode 100644 index a9236d4fc..000000000 --- a/src/utils.jl +++ /dev/null @@ -1,13 +0,0 @@ -#= -Some alias and overloading functions from QuantumToolboxUtils -=# - -function QuantumToolboxUtils._add_library_deps!(lib::Val{:QuantumToolbox}, DEPpkgs::Vector{Module}) - QuantumToolboxUtils._add_pkgs!(DEPpkgs, Module[SciMLBase, SciMLOperators, OrdinaryDiffEqCore, LinearSolve]) - return nothing -end - -const settings = QuantumToolboxUtils.settings -const versioninfo = QuantumToolboxUtils.versioninfo -const about = QuantumToolboxUtils.about -const cite = QuantumToolboxUtils.cite diff --git a/test/code-quality/Project.toml b/test/code-quality/Project.toml index 5a4113b71..82c348963 100644 --- a/test/code-quality/Project.toml +++ b/test/code-quality/Project.toml @@ -2,11 +2,11 @@ Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595" JET = "c3a54625-cd67-489e-a8e7-0a5a0ff4e31b" QuantumToolbox = "6c2fb7c5-b903-41d2-bc5e-5a7c320b9fab" -QuantumToolboxUtils = "02afad9e-e2b8-4f9a-965f-b5dca5b538ca" +QuantumToolboxCore = "7fbe806f-1706-4992-b132-86e53e431434" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [sources] -QuantumToolboxUtils = {path = "../../lib/QuantumToolboxUtils"} +QuantumToolboxCore = {path = "../../lib/QuantumToolboxCore"} [compat] Aqua = "0.8" diff --git a/test/runtests.jl b/test/runtests.jl index dd3795ea6..9997c5fda 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -6,7 +6,7 @@ const testdir = dirname(@__FILE__) # Define the paths to the library const LIBRARY_NAME_AND_PATH = Dict( - "Utils" => ("QuantumToolboxUtils", joinpath(testdir, "..", "lib", "QuantumToolboxUtils")), + "Core" => ("QuantumToolboxCore", joinpath(testdir, "..", "lib", "QuantumToolboxCore")), ) const LIBRARY_LIST = collect(keys(LIBRARY_NAME_AND_PATH)) From dc4b0a283eef8ccce584a6673162fb8116267eab Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Tue, 28 Jul 2026 12:17:14 +0200 Subject: [PATCH 37/41] fix CUDA ci pipeline config --- .buildkite/CUDA_Ext.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.buildkite/CUDA_Ext.yml b/.buildkite/CUDA_Ext.yml index df2bb1efa..fa9c5543e 100644 --- a/.buildkite/CUDA_Ext.yml +++ b/.buildkite/CUDA_Ext.yml @@ -12,8 +12,7 @@ steps: - lib - ext agents: - queue: "juliagpu" - cuda: "*" + queue: "cuda" commands: | julia --project=. -e ' using Pkg @@ -35,7 +34,9 @@ steps: matrix: setup: version: - - "1.11" # oldest + # comment this part first since Julia 1.11 security support ended [see https://endoflife.date/julia] + # but this can be re-enabled, for example, when latest version becomes 1.13, we can put 1.12 here + # - "1.11" # oldest - "1" # latest plugins: - JuliaCI/julia#v1: From 89d00f531393e2763f066a13f238cefcaf36f726 Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Wed, 29 Jul 2026 14:51:04 +0200 Subject: [PATCH 38/41] simplify versioninfo --- .../src/QuantumToolboxCore.jl | 9 +++- lib/QuantumToolboxCore/src/versioninfo.jl | 43 ++----------------- src/QuantumToolbox.jl | 10 ++++- src/core_overload.jl | 5 --- 4 files changed, 20 insertions(+), 47 deletions(-) diff --git a/lib/QuantumToolboxCore/src/QuantumToolboxCore.jl b/lib/QuantumToolboxCore/src/QuantumToolboxCore.jl index e414cb189..85a842608 100644 --- a/lib/QuantumToolboxCore/src/QuantumToolboxCore.jl +++ b/lib/QuantumToolboxCore/src/QuantumToolboxCore.jl @@ -25,7 +25,14 @@ include("physics_func.jl") include("deprecated.jl") function __init__() - _register_qt_library!(QuantumToolboxCore) + if (QuantumToolboxCore ∉ QT_LIBRARIES) + pushfirst!(QT_LIBRARIES, QuantumToolboxCore) # use pushfirst! so that main API libraries are at the front of the registry (for better display order in versioninfo) + + m_list = Module[SciMLOperators] + foreach(m_list) do m + (m ∉ DEP_PKGS) && push!(DEP_PKGS, m) + end + end return nothing end diff --git a/lib/QuantumToolboxCore/src/versioninfo.jl b/lib/QuantumToolboxCore/src/versioninfo.jl index 0699234e4..f9b5c4a4e 100644 --- a/lib/QuantumToolboxCore/src/versioninfo.jl +++ b/lib/QuantumToolboxCore/src/versioninfo.jl @@ -3,36 +3,8 @@ Reusable version information helpers for QuantumToolbox libraries. =# # Registry of all loaded QuantumToolbox libraries, populated via __init__ in each library. -const _QT_LIBRARIES = Module[] - -raw""" - _register_qt_library!(m::Module) - -Register a QuantumToolbox library module into the global registry. Each library should call this in its `__init__` function. -""" -function _register_qt_library!(m::Module) - (m ∉ _QT_LIBRARIES) && pushfirst!(_QT_LIBRARIES, m) # use pushfirst! so that main API libraries are at the front of the registry (for better display order in versioninfo) - return nothing -end - -raw""" - _add_library_deps!(lib::Val, DEPpkgs::Vector{Module}) - -Add new dependencies to `DEPpkgs` for the specified library. Extend this function in each QuantumToolbox library to declare its external (non-QuantumToolbox) dependencies. -""" -_add_library_deps!(lib::Val{T}, DEPpkgs::Vector{Module}) where {T} = throw(ArgumentError("Unknown QuantumToolbox library : $T")) -function _add_library_deps!(lib::Val{:QuantumToolboxCore}, DEPpkgs::Vector{Module}) - _add_pkgs!(DEPpkgs, Module[SciMLOperators]) - return nothing -end - -# add pkgs2 into pkgs1 but ensure the uniqueness -function _add_pkgs!(pkgs1::Vector{Module}, pkgs2::Vector{Module}) - for pkg in unique(pkgs2) - (pkg ∉ pkgs1) && push!(pkgs1, pkg) - end - return nothing -end +const QT_LIBRARIES = Module[] +const DEP_PKGS = Module[] raw""" QuantumToolboxCore.pkginfo(io::IO=stdout; pkgs::Vector{Module} = Module[]) @@ -96,8 +68,7 @@ function _print_versioninfo(io::IO = stdout) " Alberto Mercurio and Yi-Te Huang\n", ) - DEPpkgs = _gen_dep_pkg_list() - pkginfo(io; pkgs = vcat(_QT_LIBRARIES, DEPpkgs), split_after = length(_QT_LIBRARIES)) + pkginfo(io; pkgs = vcat(QT_LIBRARIES, DEP_PKGS), split_after = length(QT_LIBRARIES)) sysinfo(io) println( @@ -110,14 +81,6 @@ function _print_versioninfo(io::IO = stdout) return nothing end -function _gen_dep_pkg_list() - DEPpkgs = Module[] - for lib in _QT_LIBRARIES - _add_library_deps!(Val(nameof(lib)), DEPpkgs) - end - return DEPpkgs -end - @doc raw""" QuantumToolbox.versioninfo(io::IO=stdout) diff --git a/src/QuantumToolbox.jl b/src/QuantumToolbox.jl index 9fc10909b..35f04c7b4 100644 --- a/src/QuantumToolbox.jl +++ b/src/QuantumToolbox.jl @@ -166,7 +166,15 @@ include("visualization/wigner.jl") include("deprecated.jl") function __init__() - QuantumToolboxCore._register_qt_library!(QuantumToolbox) + if (QuantumToolbox ∉ QuantumToolboxCore.QT_LIBRARIES) + pushfirst!(QuantumToolboxCore.QT_LIBRARIES, QuantumToolbox) # use pushfirst! so that main API libraries are at the front of the registry (for better display order in versioninfo) + + m_list = Module[SciMLBase, SciMLOperators, OrdinaryDiffEqCore, LinearSolve] + foreach(m_list) do m + (m ∉ QuantumToolboxCore.DEP_PKGS) && push!(QuantumToolboxCore.DEP_PKGS, m) + end + end + return nothing end diff --git a/src/core_overload.jl b/src/core_overload.jl index a587a684f..01a8e248f 100644 --- a/src/core_overload.jl +++ b/src/core_overload.jl @@ -2,11 +2,6 @@ Some alias and overloading functions from QuantumToolboxCore =# -function QuantumToolboxCore._add_library_deps!(lib::Val{:QuantumToolbox}, DEPpkgs::Vector{Module}) - QuantumToolboxCore._add_pkgs!(DEPpkgs, Module[SciMLBase, SciMLOperators, OrdinaryDiffEqCore, LinearSolve]) - return nothing -end - const settings = QuantumToolboxCore.settings const versioninfo = QuantumToolboxCore.versioninfo const about = QuantumToolboxCore.about From ec4de698ab323bf04c3d02e43b884d79ae2372c9 Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Wed, 29 Jul 2026 15:08:31 +0200 Subject: [PATCH 39/41] minor changes --- lib/QuantumToolboxCore/src/QuantumToolboxCore.jl | 5 ++++- src/QuantumToolbox.jl | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/QuantumToolboxCore/src/QuantumToolboxCore.jl b/lib/QuantumToolboxCore/src/QuantumToolboxCore.jl index 85a842608..fec910063 100644 --- a/lib/QuantumToolboxCore/src/QuantumToolboxCore.jl +++ b/lib/QuantumToolboxCore/src/QuantumToolboxCore.jl @@ -25,9 +25,12 @@ include("physics_func.jl") include("deprecated.jl") function __init__() + # register QuantumToolbox library and its dependencies if (QuantumToolboxCore ∉ QT_LIBRARIES) - pushfirst!(QT_LIBRARIES, QuantumToolboxCore) # use pushfirst! so that main API libraries are at the front of the registry (for better display order in versioninfo) + # use pushfirst! so that main API libraries are at the front of the registry (for better display order in versioninfo) + pushfirst!(QT_LIBRARIES, QuantumToolboxCore) + # dependencies m_list = Module[SciMLOperators] foreach(m_list) do m (m ∉ DEP_PKGS) && push!(DEP_PKGS, m) diff --git a/src/QuantumToolbox.jl b/src/QuantumToolbox.jl index 35f04c7b4..327f2861e 100644 --- a/src/QuantumToolbox.jl +++ b/src/QuantumToolbox.jl @@ -166,9 +166,12 @@ include("visualization/wigner.jl") include("deprecated.jl") function __init__() + # register QuantumToolbox library and its dependencies if (QuantumToolbox ∉ QuantumToolboxCore.QT_LIBRARIES) - pushfirst!(QuantumToolboxCore.QT_LIBRARIES, QuantumToolbox) # use pushfirst! so that main API libraries are at the front of the registry (for better display order in versioninfo) + # use pushfirst! so that main API libraries are at the front of the registry (for better display order in versioninfo) + pushfirst!(QuantumToolboxCore.QT_LIBRARIES, QuantumToolbox) + # dependencies m_list = Module[SciMLBase, SciMLOperators, OrdinaryDiffEqCore, LinearSolve] foreach(m_list) do m (m ∉ QuantumToolboxCore.DEP_PKGS) && push!(QuantumToolboxCore.DEP_PKGS, m) From 9d9c6f44d4a77fd9204bb93d7eb1dc66d9ce3d65 Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Thu, 30 Jul 2026 09:09:44 +0200 Subject: [PATCH 40/41] fix versioninfo test --- lib/QuantumToolboxCore/test/versioninfo_and_settings.jl | 6 ------ 1 file changed, 6 deletions(-) diff --git a/lib/QuantumToolboxCore/test/versioninfo_and_settings.jl b/lib/QuantumToolboxCore/test/versioninfo_and_settings.jl index 957bb03f7..808914754 100644 --- a/lib/QuantumToolboxCore/test/versioninfo_and_settings.jl +++ b/lib/QuantumToolboxCore/test/versioninfo_and_settings.jl @@ -1,10 +1,4 @@ @testitem "versioninfo and about" begin - # test error handling - io_wrong = IOBuffer() - push!(QuantumToolboxCore._QT_LIBRARIES, Base) - @test_throws ArgumentError QuantumToolboxCore.versioninfo(io_wrong) - deleteat!(QuantumToolboxCore._QT_LIBRARIES, findall(x -> x == Base, QuantumToolboxCore._QT_LIBRARIES)) - # versioninfo io_version = IOBuffer() QuantumToolboxCore.versioninfo(io_version) From 4affcb34a91c7eab863a0aea5f3ddb05c761daa4 Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Thu, 30 Jul 2026 17:13:19 +0200 Subject: [PATCH 41/41] minor changes from copilot --- .buildkite/CUDA_Ext.yml | 2 +- .github/workflows/Code-Quality.yml | 2 +- .github/workflows/bump-version.yml | 18 +++++++++--------- lib/QuantumToolboxCore/src/versioninfo.jl | 4 +++- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/.buildkite/CUDA_Ext.yml b/.buildkite/CUDA_Ext.yml index fa9c5543e..47a6aa015 100644 --- a/.buildkite/CUDA_Ext.yml +++ b/.buildkite/CUDA_Ext.yml @@ -23,7 +23,7 @@ steps: Pkg.develop(path=lib) end end - Pkg.test(; test_args=["--quickfail"]) + Pkg.test(; coverage=true, test_args=["--quickfail"]) ' env: GROUP: "CUDA-Ext" diff --git a/.github/workflows/Code-Quality.yml b/.github/workflows/Code-Quality.yml index 110235588..71e64eea7 100644 --- a/.github/workflows/Code-Quality.yml +++ b/.github/workflows/Code-Quality.yml @@ -10,7 +10,7 @@ on: - 'lib/**' - 'ext/**' - 'test/runtests.jl' - - 'test/core-test/**' + - 'test/code-quality/**' - 'Project.toml' pull_request: branches: diff --git a/.github/workflows/bump-version.yml b/.github/workflows/bump-version.yml index ad28ef157..d4628d35f 100644 --- a/.github/workflows/bump-version.yml +++ b/.github/workflows/bump-version.yml @@ -83,16 +83,16 @@ jobs: # --- PART 4: Update CHANGELOG.md --- content = read(changelog_file, String) - - marker1 = "\n\n## [v$v_QT]" - insertion1 = "\n- [lib] Bump `$package` version to `v$new_v`.\n$marker1" - new_content = replace(content, marker1 => insertion1) - - if package == "QuantumToolbox" - marker2 = "## [Unreleased](https://github.com/qutip/QuantumToolbox.jl/tree/main)" - insertion2 = "$marker2\n\n\n\n## [v$new_v]\nRelease date: $(Dates.format(now(), "yyyy-mm-dd"))" - new_content = replace(new_content, marker2 => insertion2) + + if package != "QuantumToolbox" + marker = "\n\n## [v$v_QT]" + insertion = "\n- [lib] Bump `$package` version to `v$new_v`.\n$marker" + else + marker = "## [Unreleased](https://github.com/qutip/QuantumToolbox.jl/tree/main)" + insertion = "$marker\n\n\n\n## [v$new_v]\nRelease date: $(Dates.format(now(), "yyyy-mm-dd"))" + new_content = replace(new_content, marker => insertion) end + new_content = replace(content, marker => insertion) write(changelog_file, new_content) Changelog.generate(Changelog.CommonMark(), changelog_file; repo = "qutip/QuantumToolbox.jl") diff --git a/lib/QuantumToolboxCore/src/versioninfo.jl b/lib/QuantumToolboxCore/src/versioninfo.jl index f9b5c4a4e..b3d24f4eb 100644 --- a/lib/QuantumToolboxCore/src/versioninfo.jl +++ b/lib/QuantumToolboxCore/src/versioninfo.jl @@ -13,7 +13,9 @@ Command line output of version numbers for given vector of packages: `pkgs`. """ function pkginfo(io::IO = stdout; pkgs::Vector{Module} = Module[], split_after::Union{Nothing, Int} = nothing) pkg_ver_list = map(pkgversion, pkgs) - maxLen = max(5, maximum(length ∘ string, pkgs)) # maximum string length of package names (5 refer to "Julia") + + # maximum string length of package names (5 refer to "Julia") + maxLen = isempty(pkgs) ? max(5, maximum(length ∘ string, pkgs)) : 5 separation_line = "------------------------------------" print(