Skip to content

Commit 2f5e3f5

Browse files
committed
First draft at FloatTracker → TrackedFloats rename
1 parent 0f76599 commit 2f5e3f5

12 files changed

+126
-45
lines changed

CHANGELOG.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ That said, this is research software, so expect some instability as we aim first
66

77
## 1.0.1
88

9-
Enable Inf injection (issue [#41](https://github.com/utahplt/FloatTracker.jl/issues/41))
9+
Enable Inf injection (issue [#41](https://github.com/utahplt/TrackedFloats.jl/issues/41))
1010

1111
## 1.0.0
1212

@@ -56,7 +56,7 @@ Improved the last-ditch effort to extract the module name from a stack frame. No
5656

5757
### Added
5858

59-
Event limit in logger works: set `maxLogs` to control how many events get logged. FloatTracker stops collecting stack traces after this, so should run much faster once the threshold has been hit. Defaults to `Unbounded()`.
59+
Event limit in logger works: set `maxLogs` to control how many events get logged. TrackedFloats stops collecting stack traces after this, so should run much faster once the threshold has been hit. Defaults to `Unbounded()`.
6060

6161
## 0.2.0
6262

Project.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name = "FloatTracker"
1+
name = "TrackedFloats"
22
uuid = "1722352a-da05-4a89-9ace-0f2f7ef630bb"
33
authors = ["Taylor Allred <[email protected]>", "Ashton Wiersdorf <[email protected]>", "Ben Greenman <[email protected]>"]
44
version = "1.0.1"

README.md

+28-26
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,32 @@
1-
# FloatTracker.jl
1+
# TrackedFloats.jl (formerly FloatTracker.jl)
22

3-
[![CI](https://github.com/utahplt/FloatTracker.jl/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/utahplt/FloatTracker.jl/actions/workflows/CI.yml)
3+
⚠️ **NOTICE** ⚠️ we are in the process of renaming FloatTracker → TrackedFloats to bring this inline with Julia package naming conventions. Please be patient.
4+
5+
[![CI](https://github.com/utahplt/TrackedFloats.jl/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/utahplt/TrackedFloats.jl/actions/workflows/CI.yml)
46

57
Track `NaN` and `Inf` generation and propagation in your code.
68

7-
Available on [JuliaHub](https://juliahub.com/ui/Packages/FloatTracker/dBXig/1.0.0)
9+
Available on [JuliaHub](https://juliahub.com/ui/Packages/TrackedFloats/dBXig/1.0.0)
810

911
# Synopsis
1012

1113
```julia
12-
# Pull in FloatTracker
13-
using FloatTracker
14+
# Pull in TrackedFloats
15+
using TrackedFloats
1416

1517
# Wrap inputs in a TrackedFloat* type
1618
num = TrackedFloat64(-42.0)
1719

1820
# Watch as a NaN gets born
1921
should_be_nan = sqrt(num)
2022

21-
# Flush FloatTracker's logs
23+
# Flush TrackedFloats's logs
2224
ft_flush_logs()
2325
```
2426

2527
# Description
2628

27-
`FloatTracker.jl` is a library that provides three new types: `TrackedFloat16`, `TrackedFloat32`, and `TrackedFloat64`.
29+
`TrackedFloats.jl` is a library that provides three new types: `TrackedFloat16`, `TrackedFloat32`, and `TrackedFloat64`.
2830
These behave just like their `FloatN` counterparts except that they detect and log instances of exceptional floating point values. (E.g. `NaN` or `Inf`)
2931

3032
There are three kinds of events that can happen during the lifetime of an exceptional floating point value:
@@ -41,12 +43,12 @@ JuliaCon 2023 talk by Ashton:
4143

4244
<a href="https://www.youtube.com/live/rMrHCM1Etng?si=fK0Y3WYiFOzJYQ4V&t=10147"><img src="https://github-production-user-asset-6210df.s3.amazonaws.com/1731829/266869983-661b7d36-ca5f-489f-bda4-30591ebb25d7.png" /></a>
4345

44-
<!-- https://github.com/utahplt/FloatTracker.jl/assets/1731829/661b7d36-ca5f-489f-bda4-30591ebb25d7 -->
46+
<!-- https://github.com/utahplt/TrackedFloats.jl/assets/1731829/661b7d36-ca5f-489f-bda4-30591ebb25d7 -->
4547

4648

4749
## Example
4850
```julia
49-
using FloatTracker
51+
using TrackedFloats
5052

5153
config_logger(filename="max")
5254

@@ -81,13 +83,13 @@ One uses the builtin `<` operator and the other uses Julia's `max` function. Whe
8183

8284
Note that the result of this program is *wrong*: instead of the true maximum value of the list (`5.0`) getting returned, the bad version returns `4.0`!
8385

84-
We can see this in the log that produced by FloatTracker when running this file.
86+
We can see this in the log that produced by TrackedFloats when running this file.
8587

8688
```
87-
[NaN] check_error at /Users/ashton/.julia/dev/FloatTracker/src/TrackedFloat.jl:11
88-
< at /Users/ashton/.julia/dev/FloatTracker/src/TrackedFloat.jl:214
89-
maximum at /Users/ashton/Research/FloatTrackerExamples/max_example.jl:0
90-
top-level scope at /Users/ashton/Research/FloatTrackerExamples/max_example.jl:20
89+
[NaN] check_error at /Users/ashton/.julia/dev/TrackedFloats/src/TrackedFloat.jl:11
90+
< at /Users/ashton/.julia/dev/TrackedFloats/src/TrackedFloat.jl:214
91+
maximum at /Users/ashton/Research/TrackedFloatsExamples/max_example.jl:0
92+
top-level scope at /Users/ashton/Research/TrackedFloatsExamples/max_example.jl:20
9193
eval at ./boot.jl:370
9294
include_string at ./loading.jl:1899
9395
_include at ./loading.jl:1959
@@ -103,11 +105,11 @@ This tool may be useful for debugging those sorts of issues.
103105

104106
## Usage
105107

106-
1. Call `using FloatTracker`; you may want to include functions like `enable_nan_injection` or `config_logger` or the like. (See below for more details.)
108+
1. Call `using TrackedFloats`; you may want to include functions like `enable_nan_injection` or `config_logger` or the like. (See below for more details.)
107109
2. Add additional customization to logging and injection.
108110
3. Wrap as many of your inputs in `TrackedFloatN` as you can.
109111

110-
FloatTracker should take care of the rest!
112+
TrackedFloats should take care of the rest!
111113

112114
Digging into step 2, there are two things that you can customize after initialization:
113115

@@ -163,7 +165,7 @@ Keyword arguments for `config_logger`:
163165

164166
### Configuring the injector
165167

166-
FloatTracker can *inject* `NaN`s at random points in your program to help you find places where you might not be handling exceptional values properly: this technique can help you find `NaN` kills before they happen in a production environment.
168+
TrackedFloats can *inject* `NaN`s at random points in your program to help you find places where you might not be handling exceptional values properly: this technique can help you find `NaN` kills before they happen in a production environment.
167169

168170
```julia
169171
# Inject 2 NaNs
@@ -218,7 +220,7 @@ Most of the time comparison operators are what kill a NaN. But `^` can kill NaNs
218220

219221
# Fuzzing and Recording injections
220222

221-
FloatTracker allows you to fuzz code and inject NaNs or Infs wherever a `TrackedFloat` type is used. Moreover, you can record these injections to rerun injections.
223+
TrackedFloats allows you to fuzz code and inject NaNs or Infs wherever a `TrackedFloat` type is used. Moreover, you can record these injections to rerun injections.
222224

223225
**WARNING:** it is critical that inputs to the program be exactly the same for recording and replaying to be consistent. The recordings are sensitive to the number of times a floating point operation is hit.
224226

@@ -235,7 +237,7 @@ The checks in the purple region cost the most time, so we do those as late as po
235237

236238
Sometimes we want to inject NaNs throughout the program. We can create a "recording session" that will before each injection check if that point has been tried before. If it has, we move on and try again at the next injection point.
237239

238-
We can tell FloatTracker what we consider to be identical injection points. **TODO:** how *do* we tell FloatTracker what we consider to be the same and not the same? Function boundaries?
240+
We can tell TrackedFloats what we consider to be identical injection points. **TODO:** how *do* we tell TrackedFloats what we consider to be the same and not the same? Function boundaries?
239241

240242
## Recording internals
241243

@@ -247,13 +249,13 @@ Injection points are saved to a *recording file*, where each line denotes an inj
247249
42, solve.jl, OrdinaryDiffEq::solve OrdinaryDiffEq::do_it Finch::make_it_so
248250
```
249251

250-
The first field `42` is the injection point, or the nth time a floating point operation was intercepted by FloatTracker. The second field `solve.jl` acts as a little sanity check: this is the first non-FloatTracker file off of the stack trace. After that comes a list of module names paired with the function on the call stack.
252+
The first field `42` is the injection point, or the nth time a floating point operation was intercepted by TrackedFloats. The second field `solve.jl` acts as a little sanity check: this is the first non-TrackedFloats file off of the stack trace. After that comes a list of module names paired with the function on the call stack.
251253

252254
# Generating CSTGs
253255

254256
Get the [CSTG](https://github.com/utahplt/cstg) code.
255257

256-
Run a program that uses TrackedFloats (e.g. from the [example repository](https://github.com/utahplt/FloatTrackerExamples)).
258+
Run a program that uses TrackedFloats (e.g. from the [example repository](https://github.com/utahplt/TrackedFloatsExamples)).
257259
By default, a file with `*error_log*` in its name should appear.
258260

259261
Generate a graph using the error log:
@@ -272,13 +274,13 @@ For more about CSTG, please see the original paper:
272274
273275
# Examples
274276

275-
Examples have been moved from this repository to an [example repository](https://github.com/utahplt/FloatTrackerExamples)—this allows us to keep the dependencies in this repository nice and light.
277+
Examples have been moved from this repository to an [example repository](https://github.com/utahplt/TrackedFloatsExamples)—this allows us to keep the dependencies in this repository nice and light.
276278

277279
# Julia and GPU programming
278280

279-
FloatTracker works on the CPU. If a Julia function calls a GPU kernel, then you can track exceptions inside the GPU execution using our companion tool [GPU-FPX](https://github.com/LLNL/GPU-FPX) developed by Xinyi Li for her PhD. This will allow you to (1) see the exception flows inside the kernel, (2) whether the exceptions got killed inside the kernel, and if the exceptions were present in the return result of the Julia GPU call, then (3) FloatTracker will show how that exception further flows through the Julia code. You get this full effect by running your Julia Command under `LD_PRELOAD`.
281+
TrackedFloats works on the CPU. If a Julia function calls a GPU kernel, then you can track exceptions inside the GPU execution using our companion tool [GPU-FPX](https://github.com/LLNL/GPU-FPX) developed by Xinyi Li for her PhD. This will allow you to (1) see the exception flows inside the kernel, (2) whether the exceptions got killed inside the kernel, and if the exceptions were present in the return result of the Julia GPU call, then (3) TrackedFloats will show how that exception further flows through the Julia code. You get this full effect by running your Julia Command under `LD_PRELOAD`.
280282

281-
For details of `LD_PRELOAD` and to obtain and install GPU-FPX, please visit the [GPU-FPX repository](https://github.com/LLNL/GPU-FPX) and ask its authors for assistance if needed. For help on using FloatTracker in conjunction with this tool, talk to us.
283+
For details of `LD_PRELOAD` and to obtain and install GPU-FPX, please visit the [GPU-FPX repository](https://github.com/LLNL/GPU-FPX) and ask its authors for assistance if needed. For help on using TrackedFloats in conjunction with this tool, talk to us.
282284

283285
# Running tests
284286

@@ -293,7 +295,7 @@ or via the Julia shell:
293295
```
294296
julia> ] # enter the package shell
295297
pkg> activate .
296-
(FloatTracker) pkg> test
298+
(TrackedFloats) pkg> test
297299
```
298300

299301
# License
@@ -304,7 +306,7 @@ MIT License
304306

305307
Inspired by [Sherlogs.jl](https://github.com/milankl/Sherlogs.jl).
306308

307-
This repository originally lived in [Taylor Allred's repository](https://github.com/tcallred/FloatTracker.jl).
309+
This repository originally lived in [Taylor Allred's repository](https://github.com/tcallred/TrackedFloats.jl).
308310

309311
# Citation
310312

src/Config.jl

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#
2-
# Unified config for FloatTracker
2+
# Unified config for TrackedFloats
33
# ===============================
44
#
55
# Contents:
@@ -218,7 +218,7 @@ function SessionConfig()
218218
end
219219

220220
"""
221-
FloatTracker config struct
221+
TrackedFloats config struct
222222
223223
## Logger Config
224224
## Injector Config
@@ -240,7 +240,7 @@ ft_config = nothing
240240
"""
241241
ft_init()
242242
243-
Initialize the global FloatTracker configuration. (Automatically called when using function by `__init__`)
243+
Initialize the global TrackedFloats configuration. (Automatically called when using function by `__init__`)
244244
245245
We need to make this a function, otherwise it can cache the value of the
246246
timestamp used for writing unique log files.
@@ -264,7 +264,7 @@ export ft__get_global_ft_config_for_test
264264
config_logger(log::LoggerConfig)
265265
config_logger(; args...)
266266
267-
Set the logger for the global FloatTracker configuration instance.
267+
Set the logger for the global TrackedFloats configuration instance.
268268
269269
Takes either a `LoggerConfig` struct, or the same keyword arguments as the
270270
`LoggerConfig` constructor.
@@ -280,7 +280,7 @@ config_logger(; args...) = patch_config!(ft_config.log; args...)
280280
config_injector(log::InjectorConfig)
281281
config_injector(; args...)
282282
283-
Set the injector for the global FloatTracker configuration instance.
283+
Set the injector for the global TrackedFloats configuration instance.
284284
285285
Takes either a `InjectorConfig` struct, or the same keyword arguments as the
286286
`InjectorConfig` constructor.
@@ -295,7 +295,7 @@ config_injector(; args...) = patch_config!(ft_config.inj; args...)
295295
config_session(log::SessionConfig)
296296
config_session(; args...)
297297
298-
Set the session for the global FloatTracker configuration instance.
298+
Set the session for the global TrackedFloats configuration instance.
299299
300300
Takes either a `SessionConfig` struct, or the same keyword arguments as the
301301
`SessionConfig` constructor.

src/Injector.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ end
9292
end
9393

9494
@inline function drop_ft_frames(frames)
95-
collect(Iterators.dropwhile((frame -> frame_library(frame) === "FloatTracker"), frames))
95+
collect(Iterators.dropwhile((frame -> frame_library(frame) === "TrackedFloats"), frames))
9696
end
9797

9898
"""
@@ -102,7 +102,7 @@ Returns whether or not the current point in the code (indicated by the
102102
StackTrace) is a valid point to inject.
103103
"""
104104
function injectable_region(i::InjectorConfig, raw_frames::StackTraces.StackTrace)::Bool
105-
# Drop FloatTracker frames
105+
# Drop TrackedFloats frames
106106
frames = drop_ft_frames(raw_frames)
107107

108108
# If neither functions nor libraries are specified, inject as long as we're

src/FloatTracker.jl renamed to src/TrackedFloats.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
module FloatTracker
1+
module TrackedFloats
22

33
export FtConfig, ft_init, TrackedFloat16, TrackedFloat32, TrackedFloat64, FunctionRef
44
export LoggerConfig, config_logger, exclude_stacktrace, print_log, ft_flush_logs
55
export InjectorConfig, config_injector, enable_nan_injection, disable_nan_injection, enable_inf_injection, disable_inf_injection, record_injection, replay_injection
66
export SessionConfig, config_session
77

8-
include("SharedStructs.jl") # Structures used in multiple places throughout FloatTracker
8+
include("SharedStructs.jl") # Structures used in multiple places throughout TrackedFloats
99
include("Config.jl") # Primary interface routines: routines to control injection, logging, etc.
1010
include("Event.jl") # Routines for diagnosing exceptional events
1111
include("Logger.jl") # Formatting and writing of error/event logs

src/tf_counter.jl

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
abstract type AbstractTrackedFloat <: AbstractFloat end
2+
3+
for TrackedFloatN in (:TrackedFloat16, :TrackedFloat32, :TrackedFloat64)
4+
# Helper functions for working with complex numbers
5+
println("tf_to_complex")
6+
println("tf_track_complex")
7+
println("tf_untrack_complex")
8+
9+
# Use this where an int got wrapped with a TrackedFloat
10+
println("trunc_if_int")
11+
12+
number_types = (:Number, :Integer, :Float16, :Float32, :Float64)
13+
complex_types = (:ComplexF16, :ComplexF32, :ComplexF64)
14+
15+
for NumType in number_types
16+
println("Base")
17+
end
18+
19+
# Binary operators
20+
for O in (:(+), :(-), :(*), :(/), :(^), :min, :max, :rem)
21+
println("Base")
22+
println("Base")
23+
println("Base")
24+
println("Base")
25+
26+
# Hack to appease type dispatch
27+
for NumType in tuple(:Bool, number_types...)
28+
println("Base")
29+
println("Base")
30+
end
31+
end
32+
33+
# Base.decompose seems to be an internal function. Moreover, it always returns
34+
# a tuple of integers. See function def:
35+
# ~/.asdf/installs/julia/1.8.5/share/julia/base/float.jl
36+
#
37+
# Because of this, we treat any call to decompose with a NaN as a kill event.
38+
39+
println("Base")
40+
41+
# Unary operators
42+
for O in (:(-), :(+),
43+
:sign,
44+
:prevfloat, :nextfloat,
45+
:round, :trunc, :ceil, :floor,
46+
:inv, :abs, :sqrt, :cbrt,
47+
:exp, :expm1, :exp2, :exp10,
48+
:exponent,
49+
:log, :log1p, :log2, :log10,
50+
:rad2deg, :deg2rad, :mod2pi, :rem2pi,
51+
:sin, :cos, :tan, :csc, :sec, :cot,
52+
:asin, :acos, :atan, :acsc, :asec, :acot,
53+
:sinh, :cosh, :tanh, :csch, :sech, :coth,
54+
:asinh, :acosh, :atanh, :acsch, :asech, :acoth,
55+
:sinc, :sinpi, :cospi,
56+
:sind, :cosd, :tand, :cscd, :secd, :cotd,
57+
:asind, :acosd, :atand, :acscd, :asecd, :acotd,
58+
)
59+
println("$O")
60+
end
61+
62+
# Type-based functions
63+
for fn in (:floatmin, :floatmax, :eps)
64+
println("$fn")
65+
end
66+
67+
println("one")
68+
println("Base")
69+
println("Base")
70+
71+
72+
for O in (:isnan, :isinf, :issubnormal)
73+
println("Base")
74+
end
75+
76+
for O in (:(<), :(<=), :(==))
77+
println("Base")
78+
end
79+
end # for TrackedFloatN

test/complex_test.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
using Test
2-
using FloatTracker
2+
using TrackedFloats
33

44
@testset "Constructing tracked complex numbers" begin
55
scotty_tt = 0.0 + 1.0im # Our imaginary friend

test/config_api_tests.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using Test
22

3-
using FloatTracker
3+
using TrackedFloats
44

55
@testset "config_* doesn't override everything" begin
66
global_config = ft__get_global_ft_config_for_test()

test/injector_tests.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using Test
22

3-
using FloatTracker
3+
using TrackedFloats
44

55
@testset "should_inject basic behavior" begin
66
i1 = InjectorConfig(active=true, odds=1, n_inject=2)

test/logger_perf_tests.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Run this by entering the Julia REPL and running
22
# include("test/logger_perf_tests.jl")
33

4-
using FloatTracker: TrackedFloat64, ft_flush_logs, exclude_stacktrace, set_logger
4+
using TrackedFloats: TrackedFloat64, ft_flush_logs, exclude_stacktrace, set_logger
55
using FileIO, Profile, FlameGraphs, Plots, ProfileView
66

77
function track(loops)

test/logger_tests.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
using Test
22

3-
using FloatTracker
3+
using TrackedFloats
44

5-
println("FloatTracker loaded")
5+
println("TrackedFloats loaded")
66

77
f5(n) = n-2
88

0 commit comments

Comments
 (0)