Skip to content

Commit 42fc464

Browse files
committed
Doc test
1 parent 8bde5c1 commit 42fc464

File tree

5 files changed

+123
-28
lines changed

5 files changed

+123
-28
lines changed

docs/src/index.MD

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,21 @@
11
# [PerfTest.jl] [![Star on GitHub](https://img.shields.io/github/stars/JuliaPerf/PerfTest.jl.svg)](https://github.com/JuliaPerf/PerfTest.jl/stargazers)
2-
The package `PerfTest` provides ...
2+
The package `PerfTest` provides the user with a performance regression unit testing framework. This framework consists of a collection of macros used to declaratively define a performance test suite. Scripts with said macros can then be transformed into performance suites using the `transform` method. This package is focused on providing an easy and fast way to develop performance suites, with additional features to customise them following the demands of the use case.
33

44
## Dependencies
5-
`PerfTest` relies on [StaticArrays.jl], [Adapt.jl] and the Julia GPU packages [CUDA.jl] and [AMDGPU.jl].
5+
`PerfTest` relies on:
6+
- [MacroTools]
7+
- [JLD2]
8+
- [MPI]
9+
- [STREAMBenchmark]
10+
- [GFlops]
11+
- [UnicodePlots]
12+
- [Test]
13+
- [Suppressor]
614

715
## Contributors
816
This project has been developed as a Master's thesis by Daniel Sergio Vega Rodriguez.
917
Thus, the contributors to this project have been so far:
1018
- Daniel Sergio Vega Rodriguez ([@Dvegrod](https://github.com/Dvegrod)), Università della Svizzera italiana (USI): developer
11-
- Dr. Samuel Omlin ([@omlins](https://github.com/omlins)), Swiss National Supercomputing Centre (CSCS), ETH Zurich: original idea and Master's thesis superviser
12-
- Prof. Olaf Schenk, Università della Svizzera italiana (USI): Master's thesis superviser
13-
- Dr. Pasadakis Dimosthenis, Università della Svizzera italiana (USI): additional adviser
19+
- Dr. Samuel Omlin ([@omlins](https://github.com/omlins)), Swiss National Supercomputing Centre (CSCS), ETH Zurich: original idea and Master's thesis supervisor
20+
- Prof. Olaf Schenk, Università della Svizzera italiana (USI): Master's thesis supervisor
21+
- Dr. Pasadakis Dimosthenis, Università della Svizzera italiana (USI): additional advisor

src/PerfTest.jl

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ __precompile__(false) # Temporary workaround to avoid error
55
export @perftest, @on_perftest_exec, @on_perftest_ignore, @perftest_config,
66
@define_eff_memory_throughput, @define_metric, @roofline
77

8-
# Possibly redundant
98
using MacroTools
109
include("structs.jl")
1110
include("auxiliar.jl")
@@ -70,6 +69,15 @@ rules = ASTRule[testset_macro_rule,
7069

7170
# Main transform routine
7271

72+
"""
73+
This method builds what is known as a rule set. Which is a function that will evaluate if an expression triggers a rule in a set and if that is the case apply the rule modifier. See the ASTRule documentation for more information.
74+
75+
WARNING: the rule set will apply the FIRST rule that matches with the expression, therefore other matches will be ignored
76+
77+
# Arguments
78+
- `context` the context structure of the tree run, it will be ocassinally used by some rules on the set.
79+
- `rules` the collection of rules that will belong to the resulting set.
80+
"""
7381
function ruleSet(context::Context, rules :: Vector{ASTRule})
7482
function _ruleSet(x)
7583
for rule in rules
@@ -84,13 +92,28 @@ function ruleSet(context::Context, rules :: Vector{ASTRule})
8492
end
8593

8694

87-
function _treeRun(input_expr :: Expr, context :: Context, args...)
95+
"""
96+
This method gets a input julia expression, and a context register and executes a transformation of the input that converts a recipe script (input) into a fully-fledged testing suite (return value).
97+
98+
# Arguments
99+
- `input_expr` the recipe/source expression. (internally, a.k.a source code space)
100+
- `context` a register that will store information useful for the transformation over its run over the AST of the input
101+
102+
"""
103+
function _treeRun(input_expr::Expr, context::Context, args...)
88104

89105
return MacroTools.prewalk(ruleSet(context, rules), input_expr)
90106
end
91107

92108

109+
"""
110+
This method implements the transformation that converts a recipe script into a fully-fledged testing suite.
111+
The function will return a Julia expression with the resulting performance testing suite. This can be then executed or saved in a file for later usage.
112+
113+
# Arguments
114+
- `path` the path of the script to be transformed.
93115
116+
"""
94117
function treeRun(path :: AbstractString)
95118

96119
# Load original
@@ -120,5 +143,7 @@ function treeRun(path :: AbstractString)
120143
return MacroTools.prettify(module_full)
121144
end
122145

146+
transform = treeRun
147+
123148

124149
end # module perftest

src/auxiliar.jl

Lines changed: 54 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,36 @@
11
using MacroTools: ismatch
22

3-
# Function that generates a test name if needed
3+
"""
4+
Function that generates a test name if needed, it is used to name
5+
test targets to distinguish them if several go in the same testset.
6+
"""
47
function genTestName!(state::Context)
58
v = (last(state.depth).depth_test_count += 1)
69
return "Test $v"
710
end
811

12+
13+
"""
14+
Function used to register a new test set in the hierarchy record of the context, where `name` is the name of the test set.
15+
"""
916
function testsetUpdate!(state::Context, name::String)
1017
push!(state.depth, ASTWalkDepthRecord(name))
1118
end
1219

13-
### EXPRESSION LOADER
14-
function loadFileAsExpr(path ::AbstractString)
20+
"""
21+
Utility to get an expression from a Julia file stored at `path`
22+
"""
23+
function loadFileAsExpr(path::AbstractString)
1524
file = open(path, "r")
1625
str = read(file, String)
1726
return Meta.parse("begin $str end")
1827
end
1928

20-
### EXPRESSION PRINTER
29+
"""
30+
Utility to save an expression (`expr`) to a Julia file stored at `path`
31+
32+
Requires a :toplevel symbol to be the head of the expression.
33+
"""
2134
function saveExprAsFile(expr::Expr, path = "out.jl" :: AbstractString)
2235

2336
#Get the module
@@ -31,7 +44,10 @@ function saveExprAsFile(expr::Expr, path = "out.jl" :: AbstractString)
3144

3245
end
3346

34-
## Pops expr block or quote and returns array of nested expressions
47+
"""
48+
Pops `expr` which has a head that is :block or :quote and returns array of nested expressions which are the arguments of such head.
49+
50+
"""
3551
function removeBlock(expr::Expr)::Vector
3652
result = []
3753

@@ -47,7 +63,9 @@ function removeBlock(expr::Expr)::Vector
4763
end
4864

4965

50-
### Useful to move expressions to the toplevel
66+
"""
67+
This function is useful to move expressions to the toplevel when they are enclosed inside a block
68+
"""
5169
function unblockAndConcat(exprs::Vector{Expr})::Expr
5270

5371
result = Expr(:toplevel)
@@ -62,10 +80,11 @@ function unblockAndConcat(exprs::Vector{Expr})::Expr
6280
return result
6381
end
6482

65-
66-
### Useful to correct operations limited by the tree walking
67-
# Will remove quote blocks inside the main block without recursion and push
68-
# their expressions into the main block
83+
"""
84+
Useful to correct operations limited by the tree walking
85+
Will remove quote blocks inside the main block without recursion and push
86+
their expressions into the main block
87+
"""
6988
function popQuoteBlocks(expr::Expr)::Expr
7089
result = []
7190

@@ -87,7 +106,20 @@ function popQuoteBlocks(expr::Expr)::Expr
87106
end
88107
end
89108

109+
"""
110+
This method interpolates the `inside_expr` into `outside_expr` anywhere it finds the token `substitution_token`, which is a symbol. The `outside_expr` has to be a block or a quote block. It has the particularity that it will remove block heads from the `inside_expr` and add the nested elements onto the location where the token it.
111+
112+
# Example:
113+
114+
outside_expr = :(:A; 4)
115+
116+
inside_expr = :(begin 2;3 end)
117+
118+
substitution_token = :A
90119
120+
returns = :(2;3;4)
121+
122+
"""
91123
function flattenedInterpolation(outside_expr::Expr,
92124
inside_expr::Expr,
93125
substitution_token::Symbol)::Expr
@@ -176,7 +208,9 @@ function metaGet(expr_array :: AbstractVector, sym :: Symbol)
176208
return Nothing
177209
end
178210

179-
211+
"""
212+
213+
"""
180214
function metaGetString(expr_array::AbstractVector)
181215

182216
for expr in expr_array
@@ -196,7 +230,9 @@ macro inRange(min, max, value)
196230
return :($min < $value < $max)
197231
end
198232

199-
233+
"""
234+
From a string, it will divide it by lines and retrieve the ones that match the regular expression provided.
235+
"""
200236
function grepOutput(output :: String, regex_or_string :: Union{Regex, String}):: Vector{SubString{String}}
201237
lines = split(output, '\n')
202238

@@ -206,15 +242,19 @@ function grepOutput(output :: String, regex_or_string :: Union{Regex, String})::
206242
return cleaned_lines
207243
end
208244

209-
"""WARNING, SUPPORTS ONLY 1 NUMBER PER LINE"""
245+
"""
246+
From a string (`field`), it will parse the first number it finds as a Float
247+
"""
210248
function getNumber(field :: String)::Float64
211249
clean = replace(field, r"[^0-9.]" => "")
212250

213251

214252
return parse(Float64, clean)
215253
end
216254

217-
## Abbreviation gets from the first match
255+
"""
256+
Given a string `output`, it will retrieve the first number in the first line that contains the string `string`.
257+
"""
218258
function grepOutputXGetNumber(output :: String, string ::String)::Float64
219259

220260
return getNumber(String(grepOutput(output, string)[1]))

src/config.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ using MacroTools
33

44
# CONFIG STRUCTURE DEFINITION
55
# FOR DEFAULTS SEE BELOW COMMENT "DEFAULTCONFIG":
6-
6+
"""
7+
TEST
8+
"""
79
@kwdef mutable struct Struct_Regression
810
enabled::Bool
911

@@ -53,7 +55,7 @@ end
5355

5456
# DEFAULTCONFIG
5557

56-
""" Where the regression tests are saved """
58+
# Where the regression tests are saved
5759
save_folder = ".perftests"
5860

5961
save_test_results = true

src/structs.jl

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,26 @@ using BenchmarkTools
22

33
OPTIONAL_Float = Union{Nothing, Float64}
44

5-
5+
"""
6+
Tolerance interval structure. Used to save intervals around a threshold during test comparisons.
7+
"""
68
@kwdef mutable struct Struct_Tolerance
79
max_percentage::OPTIONAL_Float = nothing
810
min_percentage::OPTIONAL_Float = nothing
911
end
1012

13+
"""
14+
This structure is used to record a test set frame during a AST walk. See `ASTWalkDepthRecord` for more info.
15+
"""
1116
mutable struct DepthRecord
1217
depth_name::String
1318
depth_flag::Bool
1419

1520
DepthRecord(name) = new(name, false)
1621
end
1722

23+
"""
24+
This structure is used to record a test set hierarchy during a AST walk. In any specific point of the walk the array will TODO"""
1825
mutable struct ASTWalkDepthRecord
1926
depth_name::Union{String,Expr}
2027
depth_test_count::Int
@@ -32,7 +39,10 @@ struct FloatRange
3239
end
3340

3441
"""
35-
Saves data needed during one specific execution of the test generation process.
42+
Saves flags needed during the execution of the AST walk. It holds if:
43+
- The walk is on an expression that is a test target
44+
- The walk is on an expression that is inside a config macro
45+
- Several flags that affect the roofline methodology
3646
"""
3747
mutable struct EnvironmentFlags
3848
inside_target::Bool
@@ -46,6 +56,12 @@ mutable struct EnvironmentFlags
4656
end
4757

4858

59+
"""
60+
Saves flags needed during the execution of the AST walk. It holds if:
61+
- The walk is on an expression that is a test target
62+
- The walk is on an expression that is inside a config macro
63+
- Several flags that affect the roofline methodology
64+
"""
4965
@kwdef struct CustomMetric
5066
name::AbstractString
5167
units::AbstractString
@@ -60,7 +76,8 @@ end
6076
end
6177

6278
"""
63-
Saves important state information when going through the AST of an expression.
79+
In order to perform with the test suite generation, the AST walk needs to keep a context register to integrate features that rely on the scope hierarchy.
80+
6481
"""
6582
mutable struct Context
6683
# To register the current testset tree depth
@@ -90,8 +107,11 @@ end
90107

91108

92109
"""
93-
Used by the tree traverser to check for expressions that match "condition",
94-
if they do then "modifier" will be applied to the expression.
110+
Used by the AST walker to check for expressions that match `condition`,
111+
if they do then `modifier` will be applied to the expression.
112+
113+
This is the basic building block of the code transformer, a set of these rules compounds to all the needed manipulations to create the testing suite.
114+
95115
"""
96116
struct ASTRule
97117
condition::Function

0 commit comments

Comments
 (0)