• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

joachimbrand / Rimu.jl / 11740435665

08 Nov 2024 10:29AM UTC coverage: 94.334% (+0.02%) from 94.31%
11740435665

Pull #290

github

joachimbrand
typo in docstring
Pull Request #290: Adaptive Time Step

55 of 56 new or added lines in 6 files covered. (98.21%)

1 existing line in 1 file now uncovered.

6993 of 7413 relevant lines covered (94.33%)

13407004.45 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

87.8
/src/helpers.jl
1
# small functions supporting fciqmc!()
2
# versions without dependence on MPI.jl
3
"""
4
    MultiScalar
5

6
Wrapper over a tuple that supports `+`, `*`, `min`, and `max`. Used with MPI communication
7
because `SVector`s are treated as arrays by `MPI.Allreduce` and `Tuples` do not support
8
scalar operations.
9

10
# Example
11

12
Suppose you want to compute the sum of a vector `dv` and also get the number of positive
13
elements it has in a single pass. You can use `MultiScalar`:
14

15
```julia
16
julia> dv = DVec(:a => 1, :b => -2, :c => 1);
17

18
julia> s, p = mapreduce(+, values(dv)) do v
19
    Rimu.MultiScalar(v, Int(sign(v) == 1))
20
end;
21

22
julia> s, p
23
(0, 2)
24
```
25

26
This will work with `MPIData`.
27

28
Note that only `MultiScalar`s with the same types can be operated on. This is a feature, as it
29
forces type stability.
30
"""
31
struct MultiScalar{T<:Tuple}
32
    tuple::T
101,309,820✔
33
end
34
MultiScalar(args...) = MultiScalar(args)
9,519,419✔
35
MultiScalar(v::SVector) = MultiScalar(Tuple(v))
1✔
36
MultiScalar(m::MultiScalar) = m
382,500✔
37
MultiScalar{T}(m::MultiScalar{T}) where T<:Tuple = m
30,000✔
UNCOV
38
MultiScalar(arg) = MultiScalar((arg,))
×
39

40
Base.getindex(m::MultiScalar, i) = m.tuple[i]
30✔
41

42
const SVecOrTuple = Union{SVector,Tuple}
43

44
for op in (:+, :*, :max, :min)
45
    @eval function Base.$op(a::MultiScalar{T}, b::MultiScalar{T}) where {T}
50,098,156✔
46
        return MultiScalar($op.(a.tuple, b.tuple))
50,098,635✔
47
    end
48
    @eval function Base.$op(a::MultiScalar, b::SVecOrTuple)
41,282,242✔
49
        return $op(a, MultiScalar(b))
41,282,333✔
50
    end
51
    @eval function Base.$op(a::SVecOrTuple, b::MultiScalar)
×
52
        return $op(MultiScalar(a), b)
×
53
    end
54
end
55

56
Base.iterate(m::MultiScalar, args...) = iterate(m.tuple, args...)
8,436,414✔
57
Base.length(m::MultiScalar) = length(m.tuple)
2✔
58

59
# this is run during Rimu initialisation and sets the default
60
"""
61
    smart_logger(args...)
62
Enable terminal progress bar during interactive use (i.e. unless running on CI or HPC).
63
Arguments are passed on to the logger. This is run once during `Rimu` startup. Undo with
64
[`default_logger`](@ref) or by setting `Base.global_logger()`.
65
"""
66
function smart_logger(args...; kwargs...)
8✔
67
    if isdefined(Main, :IJulia) && Main.IJulia.inited # are we running in Jupyter?
4✔
68
        # need for now as TerminalLoggers currently does not play nice with Jupyter
69
        # install a bridge to use ProgressMeter under the hood
70
        # may become unneccessary in the future
71
        ConsoleProgressMonitor.install_logger(; kwargs...) # use ProgressMeter for Jupyter
×
72
    elseif isa(stderr, Base.TTY) && (get(ENV, "CI", nothing) ≠ true) # running in terminal?
4✔
73
        Base.global_logger(TerminalLogger(args...; kwargs...)) # enable progress bar
×
74
    end
75
    return Base.global_logger()
4✔
76
end
77
"""
78
    default_logger(args...)
79
Reset the `global_logger` to `Logging.ConsoleLogger`. Undoes the effect of
80
[`smart_logger`](@ref). Arguments are passed on to `Logging.ConsoleLogger`.
81
"""
82
function default_logger(args...; kwargs...)
4✔
83
    Base.global_logger(ConsoleLogger(args...; kwargs...)) # disable terminal progress bar
2✔
84
    return Base.global_logger()
2✔
85
end
86

87
# small functions for handling keyword arguments
88
"""
89
    replace_keys(nt::NamedTuple, (:old1 => :new1, :old2 => :new2, ...))
90

91
Replace keys in a `NamedTuple` with new keys. This is useful for renaming fields in a
92
`NamedTuple`. Ignores keys that are not present in the `NamedTuple`.
93
"""
94
function replace_keys(nt::NamedTuple, pairs)
32✔
95
    for (old, new) in pairs
32✔
96
        if isdefined(nt, old)
65✔
97
            nt = (; nt..., namedtuple((new,), (nt[old],))...)
4✔
98
            nt = delete(nt, old)
2✔
99
        end
100
    end
97✔
101
    return nt
32✔
102
end
103

104
"""
105
    delete_and_warn_if_present(nt::NamedTuple, keys)
106

107
Delete keys from a `NamedTuple` and issue a warning if they are present. This is useful for
108
removing unused keyword arguments.
109
"""
110
function delete_and_warn_if_present(nt::NamedTuple{names}, keys) where {names}
7✔
111
    unused = names ∩ keys
7✔
112
    if !isempty(unused)
7✔
113
        @warn "The keyword(s) \"$(join(unused, "\", \""))\" are unused and will be ignored."
7✔
114
    end
115
    return delete(nt, keys)
7✔
116
end
117

118
"""
119
    clean_and_warn_if_others_present(nt::NamedTuple{names}, keys) where {names}
120

121
Remove keys from a `NamedTuple` that are not in `keys` and issue a warning if they are
122
present.
123
"""
124
function clean_and_warn_if_others_present(nt::NamedTuple{names}, keys) where {names}
12✔
125
    unused = setdiff(names, keys)
12✔
126
    if !isempty(unused)
12✔
127
        @warn "The keyword(s) \"$(join(unused, "\", \""))\" are unused and will be ignored."
8✔
128
    end
129
    return NamedTuple{filter(x -> x ∈ keys, names)}(nt)
35✔
130
end
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc