From db8d62c47d5df80a64a71d2f6daa4a84b5502c23 Mon Sep 17 00:00:00 2001 From: d-monnet <70266099+d-monnet@users.noreply.github.com> Date: Tue, 17 Oct 2023 11:35:58 -0400 Subject: [PATCH] add csv export option (#95) * add csv export option * Update src/performance_profiles.jl Co-authored-by: tmigot * Update src/performance_profiles.jl Co-authored-by: tmigot * Update src/performance_profiles.jl Co-authored-by: tmigot * Update src/performance_profiles.jl Co-authored-by: tmigot * update signature add header length check * Update documentation * add test for coverage * fix doc --------- Co-authored-by: tmigot --- Project.toml | 4 +++ src/BenchmarkProfiles.jl | 2 +- src/performance_profiles.jl | 56 +++++++++++++++++++++++++++++++++++++ test/runtests.jl | 11 ++++++++ 4 files changed, 72 insertions(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 0cb0465..e5e85da 100644 --- a/Project.toml +++ b/Project.toml @@ -3,16 +3,20 @@ uuid = "ecbce9bc-3e5e-569d-9e29-55181f61f8d0" version = "0.4.3" [deps] +CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b" LaTeXStrings = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" NaNMath = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" Requires = "ae029012-a4dd-5104-9daa-d747884805df" +Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" [compat] +CSV = "0.10" LaTeXStrings = "^1.3" NaNMath = "0.3, 1" Requires = "1" julia = "^1.6" +Tables = "1.11" [extras] PGFPlotsX = "8314cec4-20b6-5062-9cdb-752b83310925" diff --git a/src/BenchmarkProfiles.jl b/src/BenchmarkProfiles.jl index 982f2e6..2668e7d 100644 --- a/src/BenchmarkProfiles.jl +++ b/src/BenchmarkProfiles.jl @@ -5,7 +5,7 @@ import NaNMath using Requires using Printf -export performance_ratios, performance_profile, performance_profile_data +export performance_ratios, performance_profile, performance_profile_data, export_performance_profile export data_ratios, data_profile export bp_backends, PlotsBackend, UnicodePlotsBackend, PGFPlotsXBackend diff --git a/src/performance_profiles.jl b/src/performance_profiles.jl index 9918bd7..a937ab3 100644 --- a/src/performance_profiles.jl +++ b/src/performance_profiles.jl @@ -4,6 +4,8 @@ # # D. Orban, 2015, 2016. +using CSV, Tables + """Compute performance ratios used to produce a performance profile. There is normally no need to call this function directly. @@ -152,3 +154,57 @@ function performance_profile( kwargs..., ) end + +""" +export_performance_profile(T, filename; solver_names = [], header, kwargs...) + +Export a performance profile plot data as .csv file. Profiles data are padded with `NaN` to ensure .csv consistency. + +## Arguments + +* `T :: Matrix{Float64}`: each column of `T` defines the performance data for a solver (smaller is better). + Failures on a given problem are represented by a negative value, an infinite value, or `NaN`. +* `filename :: String` : path to the export file. + +## Keyword Arguments + +* `solver_names :: Vector{S}` : names of the solvers +* `header::Vector{String}`: Contains .csv file column names. Note that `header` value does not change columns order in .csv exported files (see Output). + +Other keyword arguments are passed `performance_profile_data`. + +Output: +File containing profile data in .csv format. Columns are solver1_x, solver1_y, solver2_x, ... +""" +function export_performance_profile( + T::Matrix{Float64}, + filename::String; + solver_names::Vector{S} = String[], + header::Vector{S} = String[], + kwargs... +) where {S <: AbstractString} + nsolvers = size(T)[2] + + x_data, y_data, max_ratio = performance_profile_data(T;kwargs...) + max_elem = maximum(length.(x_data)) + for i in eachindex(x_data) + append!(x_data[i],[NaN for i=1:max_elem-length(x_data[i])]) + append!(y_data[i],[NaN for i=1:max_elem-length(y_data[i])]) + end + x_mat = hcat(x_data...) + y_mat = hcat(y_data...) + + isempty(solver_names) && (solver_names = ["solver_$i" for i = 1:nsolvers]) + + if !isempty(header) + header_l = size(T)[2]*2 + length(header) == header_l || error("Header should contain $(header_l) elements") + header = vcat([[sname*"_x",sname*"_y"] for sname in solver_names]...) + end + data = Matrix{Float64}(undef,max_elem,nsolvers*2) + for i =0:nsolvers-1 + data[:,2*i+1] .= x_mat[:,i+1] + data[:,2*i+2] .= y_mat[:,i+1] + end + CSV.write(filename,Tables.table(data),header=header) +end diff --git a/test/runtests.jl b/test/runtests.jl index 968302a..67d58b1 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -61,4 +61,15 @@ if !Sys.isfreebsd() # GR_jll not available, so Plots won't install profile = data_profile(PGFPlotsXBackend(), H, T, labels) @test isa(profile, Plots.Plot) end + + @testset "csv export" begin + T = 10 * rand(25, 3) + filename = "data.csv" + export_performance_profile(T,filename) + @test isfile(filename) + rm(filename) + export_performance_profile(T,filename,header = ["" for _=1:size(T,2)*2]) + @test isfile(filename) + rm(filename) + end end