From 1d1da0093143327e49a894d3fa360d38eaca36a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Delval?= Date: Thu, 29 Apr 2021 23:41:23 +0200 Subject: [PATCH 1/7] Integration of vfc_ci The vfc_ci tool has been directly added to the repository, since it's not integrated into Verificarlo yet. The vfc_test_h5.cpp file defines a test inspired by test_h5.cpp that reads a list of cycles and dump the vfc_probes for these cycles. --- .gitignore | 2 + Makefile.vfc_ci | 64 ++ ci/__init__.py | 0 ci/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 154 bytes ci/__pycache__/serve.cpython-39.pyc | Bin 0 -> 656 bytes ci/__pycache__/setup.cpython-39.pyc | Bin 0 -> 3296 bytes ci/__pycache__/test.cpython-39.pyc | Bin 0 -> 7108 bytes ci/serve.py | 28 + ci/setup.py | 155 +++++ ci/test.py | 387 ++++++++++++ .../__pycache__/compare_runs.cpython-39.pyc | Bin 0 -> 9285 bytes .../compare_variables.cpython-39.pyc | Bin 0 -> 463 bytes .../__pycache__/helper.cpython-39.pyc | Bin 0 -> 2839 bytes .../__pycache__/inspect_runs.cpython-39.pyc | Bin 0 -> 10125 bytes .../__pycache__/plot.cpython-39.pyc | Bin 0 -> 2455 bytes ci/vfc_ci_report/compare_runs.py | 556 +++++++++++++++++ ci/vfc_ci_report/helper.py | 166 +++++ ci/vfc_ci_report/inspect_runs.py | 588 ++++++++++++++++++ ci/vfc_ci_report/main.py | 217 +++++++ ci/vfc_ci_report/plot.py | 151 +++++ ci/vfc_ci_report/templates/index.html | 480 ++++++++++++++ ci/workflow_templates/ci_README.j2.md | 7 + ci/workflow_templates/gitlab-ci.j2.yml | 42 ++ .../vfc_test_workflow.j2.yml | 57 ++ include/vfc_hashmap.h | 248 ++++++++ include/vfc_probe.h | 254 ++++++++ tests/vfc_test_h5.cpp | 196 ++++++ vfc_ci | 205 ++++++ vfc_ci_cycles.txt | 2 + vfc_tests_config.json | 92 +++ 30 files changed, 3897 insertions(+) create mode 100644 Makefile.vfc_ci create mode 100644 ci/__init__.py create mode 100644 ci/__pycache__/__init__.cpython-39.pyc create mode 100644 ci/__pycache__/serve.cpython-39.pyc create mode 100644 ci/__pycache__/setup.cpython-39.pyc create mode 100644 ci/__pycache__/test.cpython-39.pyc create mode 100755 ci/serve.py create mode 100644 ci/setup.py create mode 100755 ci/test.py create mode 100644 ci/vfc_ci_report/__pycache__/compare_runs.cpython-39.pyc create mode 100644 ci/vfc_ci_report/__pycache__/compare_variables.cpython-39.pyc create mode 100644 ci/vfc_ci_report/__pycache__/helper.cpython-39.pyc create mode 100644 ci/vfc_ci_report/__pycache__/inspect_runs.cpython-39.pyc create mode 100644 ci/vfc_ci_report/__pycache__/plot.cpython-39.pyc create mode 100644 ci/vfc_ci_report/compare_runs.py create mode 100644 ci/vfc_ci_report/helper.py create mode 100644 ci/vfc_ci_report/inspect_runs.py create mode 100644 ci/vfc_ci_report/main.py create mode 100644 ci/vfc_ci_report/plot.py create mode 100644 ci/vfc_ci_report/templates/index.html create mode 100644 ci/workflow_templates/ci_README.j2.md create mode 100644 ci/workflow_templates/gitlab-ci.j2.yml create mode 100644 ci/workflow_templates/vfc_test_workflow.j2.yml create mode 100644 include/vfc_hashmap.h create mode 100644 include/vfc_probe.h create mode 100644 tests/vfc_test_h5.cpp create mode 100755 vfc_ci create mode 100644 vfc_ci_cycles.txt create mode 100644 vfc_tests_config.json diff --git a/.gitignore b/.gitignore index 9980d03..a295ba0 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,5 @@ Slater* Updates* datasets/dataset.* bin/ +*.vfcrun.hd5 +*.vfcraw.hd5 diff --git a/Makefile.vfc_ci b/Makefile.vfc_ci new file mode 100644 index 0000000..8064b40 --- /dev/null +++ b/Makefile.vfc_ci @@ -0,0 +1,64 @@ +## Compiler +CXX = verificarlo-c++ + +## Compiler flags +H5FLAGS = -I/usr/include/hdf5/serial -lhdf5_serial -lhdf5_cpp +# H5FLAGS = -lhdf5 -lhdf5_cpp +CXXFLAGS = -O0 -g $(H5FLAGS) + +INCLUDE = -I $(INC_DIR)/ -I="/usr/include" +DEPS_CXX = $(OBJ_DIR)/SM_MaponiA3.o $(OBJ_DIR)/SM_MaponiA3S.o $(OBJ_DIR)/SM_Standard.o $(OBJ_DIR)/SM_Helpers.o + +SRC_DIR := src +TST_DIR := tests +INC_DIR := include +OBJ_DIR := build +BIN_DIR := bin + +EXEC := $(BIN_DIR)/vfc_test_h5 + +## Build tagets +.PHONY: all clean distclean + +all: $(EXEC) + +clean: + @rm -vrf $(OBJ_DIR) + @rm -vrf $(BIN_DIR) + +distclean: clean + @rm -vrf $(BIN_DIR) \ + Slater* Updates.dat + + +#### COMPILING +$(BIN_DIR) $(OBJ_DIR): + mkdir -p $@ + +### IMPLICIT BUILD RULES +## C++ objects +$(OBJ_DIR)/%.o: $(TST_DIR)/%.cpp $(INC_DIR)/* | $(OBJ_DIR) + $(CXX) $(CXXFLAGS) $(INCLUDE) -c -o $@ $< + +$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp $(INC_DIR)/* | $(OBJ_DIR) + $(CXX) $(CXXFLAGS) -fPIE $(INCLUDE) -c -o $@ $< + +## HDF5/C++ objects +$(OBJ_DIR)/%_h5.o: $(TST_DIR)/%_h5.cpp $(INC_DIR)/* | $(OBJ_DIR) + $(CXX) $(H5CXXFLAGS) $(INCLUDE) -c -o $@ $< + +### EXPLICIT BUILD RULES +## special compiler flag -fPIC otherwise h5c++ builds fail +$(OBJ_DIR)/SM_MaponiA3.o: $(SRC_DIR)/SM_MaponiA3.cpp $(INC_DIR)/* | $(OBJ_DIR) + $(CXX) $(CXXFLAGS) -fPIC $(INCLUDE) -c -o $@ $< + +$(OBJ_DIR)/SM_MaponiA3S.o: $(SRC_DIR)/SM_MaponiA3S.cpp $(INC_DIR)/* | $(OBJ_DIR) + $(CXX) $(CXXFLAGS) -fPIC $(INCLUDE) -c -o $@ $< + +$(OBJ_DIR)/SM_Standard.o: $(SRC_DIR)/SM_Standard.cpp $(INC_DIR)/* | $(OBJ_DIR) + $(CXX) $(CXXFLAGS) -fPIC $(INCLUDE) -c -o $@ $< + + +#### LINKING +$(BIN_DIR)/vfc_test_h5: $(OBJ_DIR)/vfc_test_h5.o $(DEPS_CXX) | $(BIN_DIR) + $(CXX) $(CXXFLAGS) $(INCLUDE) -o $@ $^ $(H5FLAGS) diff --git a/ci/__init__.py b/ci/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/ci/__pycache__/__init__.cpython-39.pyc b/ci/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0135b7144a5614d2edd969d33d163e71293481c8 GIT binary patch literal 154 zcmYe~<>g`kg3HOB2_X70h(HF6K#l_t7qb9~6oz01O-8?!3`HPe1o6vWKO;XkRX?$` zC^aWDHBa9qKe;qFHLs*tKRmxETR)&EKfNe1H#ajcUB4_XIX*d4ABf`PGxIV_;^XxS VDsOSvChpB8660Tn@>mxA!P}<*iA!|xU${rwQ@Hm{))Si zf5|HoGaCy$rzg~Bz32D6@7exhr<_bifJW}VfB8)TetK|jSc7-y`WXfeoV1Vwr#$!u zIpO3ZEZ8q(;JS+Z^k{z11pPg_HW)0Zgp;0fdc@Vo$Py0gK+Sky$#XzV2mFdNOFhP( z*oH&xiibADT5RAexu+(0AjgD9HnCut4RAy@UdGsQVc?$Giw8nbDJqMv4^f)xmE1Wv zOzXzXc%wvRq}tEs`Y`g9t!jN9x3ZQ#`E(=KVl~r3-3r9n?XoJWrch!dmBGR+P0O~G zyL2aRw5-;`q*66?)4!SP*8_dlsA}z(%=IF4RBFdIrCGTcRrF;iTv8OvrWHluBE8o} zbc>N=gWL&9EB=dhv4^M>H$W9`JSZqm=jMr*?%6!RHpe_vA>Mf&SF-EMp8o*#1o5BC zY$ZF9m0Km+M)cX0thSx#jm|zxwaz{$S*x<^n!bMg?5t|C;U->g_AVSU|H}FW1_;KK sk>oT^867i9rhi$WrpPa-3UC_o;rz4k6bYAHc9L&f@s=Ud{zpsbKOSDIjsO4v literal 0 HcmV?d00001 diff --git a/ci/__pycache__/setup.cpython-39.pyc b/ci/__pycache__/setup.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a6aeba4f88a4a1f4ee501b7334633af89fe7d7f4 GIT binary patch literal 3296 zcma)8TW=f372eq!mlQ?OwrnRw(JmY~4(o(Wf}ll>AZTE#jayp@Vy9^~4cOJrkX&lH zOUw+Vh*-T;MS(sD^=sd#NB@Qb{UQ6>r~ZW$sQaBEDJz13b_veq%$zf4&gDB3Z*Dd$ ze5ZSV`NKc1TGl^la`Ce<`33&!0UB;`mRZrVXAv`VJF?N+nKN-Ccj84Jv$(_EKUtB_ zJ?^8g@fr`%2b?{zI`w}+lC|5htBsxfAeBWv5xK6~zf3dnDsO z{O{whBpPjv*}^uhqun!h#*S_6X}`2j7-y&K*eRVwjoYBRr8^Evt7P0cwU0er=Pvh7 z?7#lt*f0G>qx8-gv%bWoT>MTPX65boEXCionE8E$mRnHV-+j(1KQqeBZygqLe~=Z2 zeJDK5Vl7lJN&BDgeEi_?PIvr%cfz0BRfCIz{+^8UWK`9$yc~X4Uu~Q4iXC<~D!WjX zJB{_Is_|6j@kCU$cuyHh(C-gmnSNiAJ*0!CY7T`yKezIw$YHO_Ev6!`yhE94(Wyx? znIxOZCh<5TKd6GWvhoVi?7`@{C2wN*-TmIEn226HlOjt+-g{6aGxCe-eTj?qK9j{z z#*;~!4|@lLq>sA{Q=P?oxO7hmJ)3r?M^$4e^1c)?pNJNODmvJ5wpoicoR-sM@^#D; zm#C|66aBeg-(|1#t84t~uKeni2)2D&J}W)=*MWcGMfjJMHh1CQ8uyL^#6^7>A!TsJ zxX){+HnVi240vEXUoY#6jk5Mi&;R+N=W$wn-+spA+vdCmou`|8lstGF6w5Y za(h>jK`S5r7|r(PcV7{hlDwnIBa^DwwSE z1f5Vdq?i<1^ohGg*1;X=A}~Vdirj!?lT(tSS5l38|r6UpB8{L_m_C2L)|aAD}TQ>jX9>t;=q(CVR_iAcX@K*jF)Y z+Ag!#zkmCI3!3bJFCn9^KT2y4e*@XSH>te&(XL z)&4cKn~QC}F*MxzI!QeN#27kYVM(XixWzZ=bkxWefe>gb>0>|ybg9t|c>8pzg*CoW zI{XTtfdK0!zec<#Si^XmdH~XO14zFEw{EzUXjSxgw79SoOB*u&6bS$sGNqvTE+#R`<*T5_X`bA^}Q9 z9=0c9{?WsHP+V}v$Cp)Jqb95gy@kj_Q%dP7u;=`5m-rt8Nx)~ITns|80bz~Sotelv0!h0^hjr?WIM0l@Jb-{}dwvF6R5R#Qkff>~iL%0^K zNRPTnaUjf#DGHL2NcIcV3~wsaTz3NbCTVqredaU! zKfc>!jTgSx_Dz|1VZU%)j9$2YgUZGW`7=oD)MXc4<)|ZNYHH+<(|jDif1!@jd(jxu ha9q&Q)G<@Sf)6JJpJn1B2YbznGq9l}Y1a;V{{`8XkHr80 literal 0 HcmV?d00001 diff --git a/ci/__pycache__/test.cpython-39.pyc b/ci/__pycache__/test.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fa73d452612722f74b4fa60f0eb72f15333d46a3 GIT binary patch literal 7108 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 literal 0 HcmV?d00001 diff --git a/ci/serve.py b/ci/serve.py new file mode 100755 index 0000000..8685fb0 --- /dev/null +++ b/ci/serve.py @@ -0,0 +1,28 @@ +# Server for the Verificarlo CI report. This is simply a wrapper to avoid +# calling Bokeh directly. + +import os + +def serve(show, git_directory, git_url, port, allow_origin, logo_url): + + # Prepare arguments + show = "--show" if show else "" + + git = "" + if git_directory != None: + git = "git directory %s" % git_directory + if git_url != None: + git = "git url %s" % git_url + + logo = "" + if logo_url != None: + logo = "logo %s" % logo_url + + dirname = os.path.dirname(__file__) + + + # Call the "bokeh serve" command on the system + command = "bokeh serve %s/vfc_ci_report %s --allow-websocket-origin=%s:%s --port %s --args %s %s" \ + % (dirname, show, allow_origin, port, port, git, logo) + + os.system(command) diff --git a/ci/setup.py b/ci/setup.py new file mode 100644 index 0000000..1159963 --- /dev/null +++ b/ci/setup.py @@ -0,0 +1,155 @@ +# Helper script to set up Verificarlo CI on the current branch + +import git + +import sys +import os +from jinja2 import Environment, FileSystemLoader + +################################################################################ + + + # Helper functions + +def gen_readme(dev_branch, ci_branch): + + # Init template loader + path = os.path.dirname(os.path.abspath(__file__)) + env = Environment(loader=FileSystemLoader(path)) + template = env.get_template("workflow_templates/ci_README.j2.md") + + # Render template + render = template.render(dev_branch=dev_branch, ci_branch=ci_branch) + + # Write template + with open("README.md", "w") as fh: + fh.write(render) + + + +def gen_workflow(git_host, dev_branch, ci_branch, repo): + + # Init template loader + path = os.path.dirname(os.path.abspath(__file__)) + env = Environment(loader=FileSystemLoader(path)) + + + if git_host == "github": + # Load template + template = env.get_template("workflow_templates/vfc_test_workflow.j2.yml") + + # Render it + render = template.render(dev_branch=dev_branch, ci_branch=ci_branch) + + # Write the file + filename = ".github/workflows/vfc_test_workflow.yml" + os.makedirs(os.path.dirname(filename), exist_ok=True) + with open(filename, "w") as fh: + fh.write(render) + + + if git_host == "gitlab": + template = env.get_template("workflow_templates/gitlab-ci.j2.yml") + + # Ask for the user who will run the jobs (Gitlab specific) + username = input("[vfc_ci] Enter the name of the user who will run the CI jobs:") + email = input("[vfc_ci] Enter the e-mail of the user who will run the CI jobs:") + + remote_url = repo.remotes[0].config_reader.get("url") + remote_url = remote_url.replace("http://", "") + remote_url = remote_url.replace("https://", "") + + render = template.render( + dev_branch=dev_branch, + ci_branch=ci_branch, + username=username, + email=email, + remote_url = remote_url + ) + + filename = ".gitlab-ci.yml" + with open(filename, "w") as fh: + fh.write(render) + + + +################################################################################ + +def setup(git_host): + + + # Init repo and make sure that the workflow setup is possible + + repo = git.Repo(".") + repo.remotes.origin.fetch() + + # Make sure that repository is clean + assert(not repo.is_dirty()), "Error [vfc_ci]: Unstaged changes detected " \ + "in your work tree." + + dev_branch = repo.active_branch + dev_branch_name = str(dev_branch) + dev_remote = dev_branch.tracking_branch() + + # Make sure that the active branch (on which to setup the workflow) has a remote + assert(dev_remote != None), "Error [vfc_ci]: The current branch doesn't " \ + "have a remote." + + # Make sure that we are not behind the remote (so we can push safely later) + rev = "%s...%s" % (dev_branch_name, str(dev_remote)) + commits_behind = list(repo.iter_commits(rev)) + assert(commits_behind == []), "Error [vfc_ci]: The local branch seems " \ + "to be at least one commit behind remote." + + + + # Commit the workflow on the current (dev) branch + + ci_branch_name = "vfc_ci_%s" % dev_branch_name + gen_workflow(git_host, dev_branch_name, ci_branch_name, repo) + repo.git.add(".") + repo.index.commit("[auto] Set up Verificarlo CI on this branch") + repo.remote(name="origin").push() + + + + # Create the CI branch (orphan branch with a readme on it) + # (see : https://github.com/gitpython-developers/GitPython/issues/615) + + repo.head.reference = git.Head(repo, "refs/heads/"+ ci_branch_name) + + repo.index.remove(["*"]) + gen_readme(dev_branch_name, ci_branch_name) + repo.index.add(["README.md"]) + + repo.index.commit( + "[auto] Create the Verificarlo CI branch for %s" % dev_branch_name, + parent_commits=None + ) + repo.remote(name="origin").push( + refspec="%s:%s" % (ci_branch_name, ci_branch_name) + ) + + # Force checkout back to the original (dev) branch + repo.git.checkout(dev_branch_name, force=True) + + + + # Print termination messages + + print( + "Info [vfc_ci]: A Verificarlo CI workflow has been setup on " \ + "%s." % dev_branch_name + ) + print( + "Info [vfc_ci]: Make sure that you have a \"vfc_tests_config.json\" on " \ + "this branch. You can also perform a \"vfc_ci test\" dry run before "\ + "pushing other commits." + ) + + if git_host == "gitlab": + print( + "Info [vfc_ci]: Since you are using GitLab, make sure that you " \ + "have created an access token for the user you specified (registered "\ + "as a variable called \"CI_PUSH_TOKEN\" in your repository)." + ) diff --git a/ci/test.py b/ci/test.py new file mode 100755 index 0000000..ce21010 --- /dev/null +++ b/ci/test.py @@ -0,0 +1,387 @@ +# This script reads the vfc_tests_config.json file and executes tests accordingly +# It will also generate a ... .vfcrun.hd5 file with the results of the run + +import os +import json + +import calendar +import time + +# Forcing an older pickle protocol allows backwards compatibility when reading +# HDF5 written in 3.8+ using an older version of Python +import pickle +pickle.HIGHEST_PROTOCOL = 4 + +import pandas as pd +import numpy as np +import scipy.stats + +import sigdigits as sd + +# Magic numbers +min_pvalue = 0.05 +max_zscore = 3 + + +################################################################################ + + + # Helper functions + +# Read a CSV file outputted by vfc_probe as a Pandas dataframe +def read_probes_csv(filepath, backend, warnings, execution_data): + + try: + results = pd.read_csv(filepath) + + except FileNotFoundError: + print( + "Warning [vfc_ci]: Probes not found, your code might have crashed " \ + "or you might have forgotten to call vfc_dump_probes" + ) + warnings.append(execution_data) + return pd.DataFrame( + columns = ["test", "variable", "values", "vfc_backend"] + ) + + except Exception: + print( + "Warning [vfc_ci]: Your probes could not be read for some unknown " \ + "reason" + ) + warnings.append(execution_data) + return pd.DataFrame( + columns = ["test", "variable", "values", "vfc_backend"] + ) + + if len(results) == 0: + print( + "Warning [vfc_ci]: Probes empty, it looks like you have dumped " \ + "them without calling vfc_put_probe" + ) + warnings.append(execution_data) + + + # Once the CSV has been opened and validated, return its content + results["value"] = results["value"].apply(lambda x: float.fromhex(x)) + results.rename(columns = {"value":"values"}, inplace = True) + + results["vfc_backend"] = backend + + return results + + +# Wrappers to sd.significant_digits (returns results in base 2) + +def significant_digits(x): + + # In a pandas DF, "values" actually refers to the array of columns, and + # not the column named "values" + distribution = x.values[3] + distribution = distribution.reshape(len(distribution), 1) + + # The distribution's empirical average will be used as the reference + mu = np.array([x.mu]) + + # If the null hypothesis is rejected, call sigdigits with General mode: + if x.pvalue < min_pvalue: + method = sd.Method.General + s = sd.significant_digits( + distribution, + mu, + precision=sd.Precision.Absolute, + method=method + ) + + + # Else, manually compute sMCA which is equivalent to a 66% confidence interval + else: + method = sd.Method.CNH + s = sd.significant_digits( + distribution, + mu, + precision=sd.Precision.Absolute, + method=method, + + probability=0.66, + confidence=0.66, + ) + + # s is returned as a size 1 list + return s[0] + + +def significant_digits_lower_bound(x): + # If the null hypothesis is rejected, no lower bound + if x.pvalue < min_pvalue: + return x.s2 + + # Else, the lower bound will be a 95% confidence interval + + distribution = x.values[3] + distribution = distribution.reshape(len(distribution), 1) + + mu = np.array([x.mu]) + + s = sd.significant_digits( + distribution, + mu, + precision=sd.Precision.Absolute, + method=sd.Method.CNH, + ) + + return s[0] + + +################################################################################ + + + + # Main functions + + +# Open and read the tests config file +def read_config(): + try: + with open("vfc_tests_config.json", "r") as file: + data = file.read() + + except FileNotFoundError as e: + e.strerror = "Error [vfc_ci]: This file is required to describe the tests "\ + "to run and generate a Verificarlo run file" + raise e + + return json.loads(data) + + + +# Set up metadata +def generate_metadata(is_git_commit): + + # Metadata and filename are initiated as if no commit was associated + metadata = { + "timestamp": calendar.timegm(time.gmtime()), + "is_git_commit": is_git_commit, + "hash": "", + "author": "", + "message": "" + } + + + if is_git_commit: + print("Fetching metadata from last commit...") + from git import Repo + + repo = Repo(".") + head_commit = repo.head.commit + + metadata["timestamp"] = head_commit.authored_date + + metadata["hash"] = str(head_commit)[0:7] + metadata["author"] = "%s <%s>" \ + % (str(head_commit.author), head_commit.author.email) + metadata["message"] = head_commit.message.split("\n")[0] + + return metadata + + + +# Execute tests and collect results in a Pandas dataframe (+ dataprocessing) +def run_tests(config): + + # Run the build command + print("Info [vfc_ci]: Building tests...") + os.system(config["make_command"]) + + # This is an array of Pandas dataframes for now + data = [] + + # Create tmp folder to export results + os.system("mkdir .vfcruns.tmp") + n_files = 0 + + # This will contain all executables/repetition numbers from which we could + # not get any data + warnings = [] + + + # Tests execution loop + for executable in config["executables"]: + print("Info [vfc_ci]: Running executable :", executable["executable"], "...") + + parameters = "" + if "parameters" in executable: + parameters = executable["parameters"] + + for backend in executable["vfc_backends"]: + + export_backend = "VFC_BACKENDS=\"" + backend["name"] + "\" " + command = "./" + executable["executable"] + " " + parameters + + repetitions = 1 + if "repetitions" in backend: + repetitions = backend["repetitions"] + + # Run test repetitions and save results + for i in range(repetitions): + file = ".vfcruns.tmp/%s.csv" % str(n_files) + export_output = "VFC_PROBES_OUTPUT=\"%s\" " % file + os.system(export_output + export_backend + command) + + # This will only be used if we need to append this exec to the + # warnings list + execution_data = { + "executable": executable["executable"], + "backend": backend["name"], + "repetition": i + 1 + } + + data.append(read_probes_csv( + file, + backend["name"], + warnings, + execution_data + )) + + n_files = n_files + 1 + + + # Clean CSV output files (by deleting the tmp folder) + os.system("rm -rf .vfcruns.tmp") + + + # Combine all separate executions in one dataframe + data = pd.concat(data, sort=False, ignore_index=True) + data = data.groupby(["test", "vfc_backend", "variable"])\ + .values.apply(list).reset_index() + + + # Make sure we have some data to work on + assert(len(data) != 0), "Error [vfc_ci]: No data have been generated " \ + "by your tests executions, aborting run without writing results file" + + return data, warnings + + + + # Data processing +def data_processing(data): + + data["values"] = data["values"].apply(lambda x: np.array(x).astype(float)) + + # Get empirical average, standard deviation and p-value + data["mu"] = data["values"].apply(np.average) + data["sigma"] = data["values"].apply(np.std) + data["pvalue"] = data["values"].apply(lambda x: scipy.stats.shapiro(x).pvalue) + + + # Significant digits + data["s2"] = data.apply(significant_digits, axis=1) + data["s10"] = data["s2"].apply(lambda x: sd.change_base(x, 10)) + + # Lower bound of the confidence interval using the sigdigits module + data["s2_lower_bound"] = data.apply(significant_digits_lower_bound, axis=1) + data["s10_lower_bound"] = data["s2_lower_bound"].apply(lambda x: sd.change_base(x, 10)) + + + # Compute moments of the distribution + # (including a new distribution obtained by filtering outliers) + data["values"] = data["values"].apply(np.sort) + + data["mu"] = data["values"].apply(np.average) + data["min"] = data["values"].apply(np.min) + data["quantile25"] = data["values"].apply(np.quantile, args=(0.25,)) + data["quantile50"] = data["values"].apply(np.quantile, args=(0.50,)) + data["quantile75"] = data["values"].apply(np.quantile, args=(0.75,)) + data["max"] = data["values"].apply(np.max) + + data["nsamples"] = data["values"].apply(len) + + + + # Display all executions that resulted in a warning +def show_warnings(warnings): + if len(warnings) > 0: + print( + "Warning [vfc_ci]: Some of your runs could not generate any data " \ + "(for instance because your code crashed) and resulted in " + "warnings. Here is the complete list :" + ) + + for i in range(0, len(warnings)): + print("- Warning %s:" % i) + + print(" Executable: %s" % warnings[i]["executable"]) + print(" Backend: %s" % warnings[i]["backend"]) + print(" Repetition: %s" % warnings[i]["repetition"]) + + + +################################################################################ + + + # Entry point + +def run(is_git_commit, export_raw_values, dry_run): + + # Get config, metadata and data + print("Info [vfc_ci]: Reading tests config file...") + config = read_config() + + print("Info [vfc_ci]: Generating run metadata...") + metadata = generate_metadata(is_git_commit) + + data, warnings = run_tests(config) + show_warnings(warnings) + + + # Data processing + print("Info [vfc_ci]: Processing data...") + data_processing(data) + + + # Prepare data for export (by creating a proper index and linking run timestamp) + data = data.set_index(["test", "variable", "vfc_backend"]).sort_index() + data["timestamp"] = metadata["timestamp"] + + filename = metadata["hash"] if is_git_commit else str(metadata["timestamp"]) + + + # Prepare metadata for export + metadata = pd.DataFrame.from_dict([metadata]) + metadata = metadata.set_index("timestamp") + + + # NOTE : Exporting to HDF5 requires to install "tables" on the system + + # Export raw data if needed + if export_raw_values and not dry_run: + data.to_hdf(filename + ".vfcraw.hd5", key="data") + metadata.to_hdf(filename + ".vfcraw.hd5", key="metadata") + + # Export data + del data["values"] + if not dry_run: + data.to_hdf(filename + ".vfcrun.hd5", key="data") + metadata.to_hdf(filename + ".vfcrun.hd5", key="metadata") + + + # Print termination messages + print( + "Info [vfc_ci]: The results have been successfully written to " \ + "%s.vfcrun.hd5." \ + % filename + ) + + if export_raw_values: + print( + "Info [vfc_ci]: A file containing the raw values has also been " \ + "created : %s.vfcraw.hd5." + % filename + ) + + if dry_run: + print( + "Info [vfc_ci]: The dry run flag was enabled, so no files were " \ + "actually created." + ) diff --git a/ci/vfc_ci_report/__pycache__/compare_runs.cpython-39.pyc b/ci/vfc_ci_report/__pycache__/compare_runs.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0be4ed463e7dfb486022766db9121075b31904b2 GIT binary patch literal 9285 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 P_zY9QCz|tgGui(KS}F1J literal 0 HcmV?d00001 diff --git a/ci/vfc_ci_report/__pycache__/compare_variables.cpython-39.pyc b/ci/vfc_ci_report/__pycache__/compare_variables.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..88a3c9568007af9c7b43c6a1e11057fe702578ac GIT binary patch literal 463 zcmYjN%}N6?5KcDPb&F90NxSR;d17$-l|nIS6zK9Tel zt*FeGs4Bjp5>+@BOQn?v$rHVkR*01N7a&6g=nbep2M91+W-tnHn@RdcUr@mB*)#eW z>0oreh-71JBx~*>s%WGwH!9|#2^!46b+6)y?LuQ)UlEsLC5%_%Hw2h_i8scRx0fed(IA_PTLTG&k<-J>&H!x VU79Nk z)ur{U=mEnT0ttbfLdaU&i6_o`oYG8zpS zp6C3JpZ#^8v40cu>f?d=5dZoM5XmIZ*{mJ;jDr`sD7=}+TbVx#q&EwtKkLarhF`K- zBzrQ#*q41dz&Mah4dNT}2Ix=@yH&cU13`%dy=1lFxSKzI+X`u{@BkW89Pc z5t|%d!3#E>a2usnvCyinuXZ81A~#b(%I={#{XfFLrVtzUgf;v&d&Iutw1Jmb=|tG5 zP$rRyNo?O_g{nTpytrnFw$7d>EDE;>0nH|oRiP!JmBPX5r zT;ISvaDmePVy?UZYWYxP@w;c6DHr|0~7oyf46RgO-_zh>P5ty@Tsn@a(`fN1> zBa>&Hi2doU*6eeo&Rf}P2V+r{=B(u{uP2cn<5f1C7p}>oG|5#d6KzA{=S6!s^sU)SyG=_51U!9tUgCaXQ!vutBtn2wBaIO>LkC` zw)!qsejopO3c^Ih2k6#_`Awr1s3UP;T4*&=lp-drM;80z` zs`fz`54nC5!h43+dEBCQ|TJet4iB1l8e}6>3MB~i{v7! z?dwJIq|#0n=UJ%$R(Yi%&dP5P-)XJ${}w={8`tpHfoU*wh1Zz00#IUBV( z>zrD`qNZv9tx&-Tbb#7MLKD(%cchr3oWviXlr0Ja#{_1` zQHy9mF9Gx-z2C4#+#=io!l4G<0XuhShBol0S5%@;Tr*4pJpp4yxv*iOWR{fF+R}Q- z<9ZU>AkjK`W(SnaRh?E^>33nT-=js5%y6HTshaInOM@#+*Riv|o|9dvj7m+sw)#C* z*Z3MhR)%~B=K-gK`#2dxp??bLR$jbQ^auYn%Oi$MpWpTu+AK01JiDw4w)O~$xS zevH9J>(_nF9j%J$soJ>n7g(>aM*_B#%CLTDzIpw>z)%^`x`6)MlweNIpoJYzPOUk* zEHTH0LzbP!ah=BB(m1Zu1X~)%b((NX~OUW-RWAJACsK`XTMTuW!@d4*vTYkla*N zUc0WaLAfjz&-6QF@IxZ+6QR!`_XTks4+-1cA^pGW?j5iA>LAkrWpq+ha+#}#)GhV* dKyb#<&ynYIKa7HCC;A1j+l#_zf4Cd@{{!t{cwhhk literal 0 HcmV?d00001 diff --git a/ci/vfc_ci_report/__pycache__/inspect_runs.cpython-39.pyc b/ci/vfc_ci_report/__pycache__/inspect_runs.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4c7717c0c780adbd0504d5ea6f7de8a68e003505 GIT binary patch literal 10125 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 literal 0 HcmV?d00001 diff --git a/ci/vfc_ci_report/__pycache__/plot.cpython-39.pyc b/ci/vfc_ci_report/__pycache__/plot.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9e4b5971eaf6cb3b45368078cade265fce44ad32 GIT binary patch literal 2455 zcmaKtTW{P%6vsWj+j~uuCcSWn6c%VVEkxW(Thyu`BqBsBfmR6P^>}x^vDeG7H{C?e z8&61)_z3MA`35}lA$S^Ika)^hCriF>0%^nrIy@(K~u#bPQ?JVl%Ni7Pc$g-Usa?FeU5T1=R|s6T)6&07&i{szAGbK8DYb;P=*FK3w2c~)LG3f*<;-1&VjjK!3dL=zCtY+cX{Q&*sm5A z{DeMhJ{mn$+)u4A<+{HV)uBCf9=aSYk5oE3jIMZ9S=X?xW53Sp=apf@Yo6*Y@y3Gh zOuo#U7ishgMSEwtf``1cC5)Xo8im3PA_(H}P!o2J2b@RaOz260TW*P9KEeb<@d+3!@vO^UxIPbVI1S_)M>2eN~uQI)NY*F0JSV zX`I4Q6>p|x2%Q!YY%16;tf5KhS+s|D4i~Wl&yYy76^(clgc;ynDn}X#-EV6Zs4d)H z3W=ZRA!NewIrr#YGSJZn1_fAI*iXVy4m3*W^3^Nc&wa1lo1KMm7~~-rPCD{}fj{cw z5ls6KanT_4PBt%$U1>LV{b_^?9xpDMV|gBNltj5Vi24K3ShV1231Ykr)rCHe(_9`y$CX>|MPbZ=5>qVCFU>pNL?#-;%**|; zH@`2joP~fHblPap3uU5m>Iw&xX+p!%o!ZQ?cyRCvu6d}y`&d2xsy#@Pu`3W6!JE` z=auoUsP>{b_IR3;fzmpA7e#Sw)>Lg~s;-VL=IT1rna!$9|I4&>rn2harlqqL^5SEw zb%s9`uH#st1QyLv7UBa-1 zxFdDec1vDVF#k>D(MeQoA*y~V3MnM1GMk~n?lJoAVpIoC0Wg``)=Zo z@+c19*@PtuJVSxxjz){_Yny#^VEO%K%YqBokZcmhgNWw?OqFyj%x;?F$4KTVoWqdC z2{t!c<_u>yY49zQk4Ok?vuNaLGC6t<`z>REe9z9Kgdw2`6d?%+&r|CKl#+n(A{kyH zIffp*j9sDcbbZWd%qCbT_a%~7NnRsqk-Sdw2FaTwmr1UWv`Gk4ut9ParB#P()RtH_ z5oWz;Dp>??k@;E4p{lYao0fm=%e literal 0 HcmV?d00001 diff --git a/ci/vfc_ci_report/compare_runs.py b/ci/vfc_ci_report/compare_runs.py new file mode 100644 index 0000000..27ff0de --- /dev/null +++ b/ci/vfc_ci_report/compare_runs.py @@ -0,0 +1,556 @@ +# Manage the view comparing a variable over different runs + +import time + +import pandas as pd + +from math import pi + +from bokeh.plotting import figure, curdoc +from bokeh.embed import components +from bokeh.models import Select, ColumnDataSource, Panel, Tabs, HoverTool, \ +TextInput, CheckboxGroup, TapTool, CustomJS + +import helper +import plot + + +################################################################################ + + + +class CompareRuns: + + # Helper functions related to CompareRuns + + # From an array of timestamps, returns the array of runs names (for the x + # axis ticks), as well as the metadata (in a dict of arrays) associated to + # this array (for the tooltips) + def gen_x_series(self, timestamps): + + # Initialize the objects to return + x_series= [] + x_metadata = dict( + date = [], + is_git_commit = [], + hash = [], + author = [], + message = [] + ) + + # n == 0 means we want all runs, we also make sure not to go out of + # bound if asked for more runs than we have + n = self.current_n_runs + if n == 0 or n > len(timestamps): + n = len(timestamps) + + + for i in range(0, n): + # Get metadata associated to this run + row_metadata = helper.get_metadata(self.metadata, timestamps[-i-1]) + date = time.ctime(timestamps[-i-1]) + + # Fill the x series + str = row_metadata["name"] + x_series.insert(0, helper.get_metadata(self.metadata, timestamps[-i-1])["name"]) + + # Fill the metadata lists + x_metadata["date"].insert(0, date) + x_metadata["is_git_commit"].insert(0, row_metadata["is_git_commit"]) + x_metadata["hash"].insert(0, row_metadata["hash"]) + x_metadata["author"].insert(0, row_metadata["author"]) + x_metadata["message"].insert(0, row_metadata["message"]) + + + return x_series, x_metadata + + + + # Plots update function + + def update_plots(self): + + # Select all data matching current test/var/backend + + runs = self.data.loc[ + [self.widgets["select_test"].value], + self.widgets["select_var"].value, self.widgets["select_backend"].value + ] + + timestamps = runs["timestamp"] + x_series, x_metadata = self.gen_x_series(timestamps.sort_values()) + + + # Update source + + main_dict = runs.to_dict("series") + main_dict["x"] = x_series + + # Add metadata (for tooltip) + main_dict.update(x_metadata) + + # Select the last n runs only + n = self.current_n_runs + main_dict = {key:value[-n:] for key, value in main_dict.items()} + + + # Generate ColumnDataSources for the 3 dotplots + for stat in ["sigma", "s10", "s2"]: + dict = { + "%s_x" % stat: main_dict["x"], + + "is_git_commit": main_dict["is_git_commit"], + "date": main_dict["date"], + "hash": main_dict["hash"], + "author": main_dict["author"], + "message": main_dict["message"], + + stat: main_dict[stat], + + "nsamples": main_dict["nsamples"], + } + + if stat == "s10" or stat == "s2": + dict["%s_lower_bound" % stat] = main_dict["%s_lower_bound" % stat] + + # Filter outliers if the box is checked + if len(self.widgets["outliers_filtering_compare"].active) > 0: + outliers = helper.detect_outliers(dict[stat]) + dict[stat] = helper.remove_outliers(dict[stat], outliers) + dict["%s_x" % stat] = helper.remove_outliers(dict["%s_x" % stat], outliers) + + # Assign ColumnDataSource + self.sources["%s_source" % stat].data = dict + + + # Generate ColumnDataSource for the boxplot + dict = { + "is_git_commit": main_dict["is_git_commit"], + "date": main_dict["date"], + "hash": main_dict["hash"], + "author": main_dict["author"], + "message": main_dict["message"], + + "x": main_dict["x"], + "min" : main_dict["min"], + "quantile25" : main_dict["quantile25"], + "quantile50" : main_dict["quantile50"], + "quantile75" : main_dict["quantile75"], + "max" : main_dict["max"], + "mu" : main_dict["mu"], + "pvalue" : main_dict["pvalue"], + + "nsamples": main_dict["nsamples"] + } + + + + self.sources["boxplot_source"].data = dict + + + # Update x_ranges + helper.reset_x_range(self.plots["boxplot"], self.sources["boxplot_source"].data["x"]) + helper.reset_x_range(self.plots["sigma_plot"], self.sources["sigma_source"].data["sigma_x"]) + helper.reset_x_range(self.plots["s10_plot"], self.sources["s10_source"].data["s10_x"]) + helper.reset_x_range(self.plots["s2_plot"], self.sources["s2_source"].data["s2_x"]) + + + + + # Widgets' callback functions + + def update_test(self, attrname, old, new): + + # If the value is updated by the CustomJS, self.widgets["select_var"].value + # won't be updated, so we have to look for that case and assign it manually + + # "new" should be a list when updated by CustomJS + if type(new) == list: + # If filtering removed all options, we might have an empty list + # (in this case, we just skip the callback and do nothing) + if len(new) > 0: + new = new[0] + else: + return + + if new != self.widgets["select_test"].value: + # The callback will be triggered again with the updated value + self.widgets["select_test"].value = new + return + + # New list of available vars + self.vars = self.data.loc[new]\ + .index.get_level_values("variable").drop_duplicates().tolist() + self.widgets["select_var"].options = self.vars + + + # Reset var selection if old one is not available in new vars + if self.widgets["select_var"].value not in self.vars: + self.widgets["select_var"].value = self.vars[0] + # The update_var callback will be triggered by the assignment + + else: + # Trigger the callback manually (since the plots need to be updated + # anyway) + self.update_var("", "", self.widgets["select_var"].value) + + + def update_var(self, attrname, old, new): + + # If the value is updated by the CustomJS, self.widgets["select_var"].value + # won't be updated, so we have to look for that case and assign it manually + + # new should be a list when updated by CustomJS + if type(new) == list: + new = new[0] + + if new != self.widgets["select_var"].value: + # The callback will be triggered again with the updated value + self.widgets["select_var"].value = new + return + + + # New list of available backends + self.backends = self.data.loc[self.widgets["select_test"].value, self.widgets["select_var"].value]\ + .index.get_level_values("vfc_backend").drop_duplicates().tolist() + self.widgets["select_backend"].options = self.backends + + # Reset backend selection if old one is not available in new backends + if self.widgets["select_backend"].value not in self.backends: + self.widgets["select_backend"].value = self.backends[0] + # The update_backend callback will be triggered by the assignment + + else: + # Trigger the callback manually (since the plots need to be updated + # anyway) + self.update_backend("", "", self.widgets["select_backend"].value) + + + def update_backend(self, attrname, old, new): + + # Simply update plots, since no other data is affected + self.update_plots() + + + def update_n_runs(self, attrname, old, new): + # Simply update runs selection (value and string display) + self.select_n_runs.value = new + self.current_n_runs = self.n_runs_dict[self.select_n_runs.value] + + self.update_plots() + + + def update_outliers_filtering(self, attrname, old, new): + self.update_plots() + + + + # Bokeh setup functions + + def setup_plots(self): + + tools = "pan, wheel_zoom, xwheel_zoom, ywheel_zoom, reset, save" + + # Custom JS callback that will be used when tapping on a run + # Only switches the view, a server callback is required to update plots + # (defined inside template to avoid bloating server w/ too much JS code) + js_tap_callback = "goToInspectRuns();" + + + # Box plot + self.plots["boxplot"] = figure( + name="boxplot", title="Variable distribution over runs", + plot_width=900, plot_height=400, x_range=[""], + tools=tools, sizing_mode="scale_width" + ) + + box_tooltips = [ + ("Git commit", "@is_git_commit"), + ("Date", "@date"), + ("Hash", "@hash"), + ("Author", "@author"), + ("Message", "@message"), + ("Min", "@min{%0.18e}"), + ("Max", "@max{%0.18e}"), + ("1st quartile", "@quantile25{%0.18e}"), + ("Median", "@quantile50{%0.18e}"), + ("3rd quartile", "@quantile75{%0.18e}"), + ("μ", "@mu{%0.18e}"), + ("p-value", "@pvalue"), + ("Number of samples", "@nsamples") + ] + box_tooltips_formatters = { + "@min" : "printf", + "@max" : "printf", + "@quantile25" : "printf", + "@quantile50" : "printf", + "@quantile75" : "printf", + "@mu" : "printf" + } + + plot.fill_boxplot( + self.plots["boxplot"], self.sources["boxplot_source"], + tooltips = box_tooltips, + tooltips_formatters = box_tooltips_formatters, + js_tap_callback = js_tap_callback, + server_tap_callback = self.inspect_run_callback_boxplot, + ) + self.doc.add_root(self.plots["boxplot"]) + + + # Sigma plot (bar plot) + self.plots["sigma_plot"] = figure( + name="sigma_plot", title="Standard deviation σ over runs", + plot_width=900, plot_height=400, x_range=[""], + tools=tools, sizing_mode="scale_width" + ) + + sigma_tooltips = [ + ("Git commit", "@is_git_commit"), + ("Date", "@date"), + ("Hash", "@hash"), + ("Author", "@author"), + ("Message", "@message"), + ("σ", "@sigma"), + ("Number of samples", "@nsamples") + ] + + plot.fill_dotplot( + self.plots["sigma_plot"], self.sources["sigma_source"], "sigma", + tooltips = sigma_tooltips, + js_tap_callback = js_tap_callback, + server_tap_callback = self.inspect_run_callback_sigma, + lines = True + ) + self.doc.add_root(self.plots["sigma_plot"]) + + + # s plot (bar plot with 2 tabs) + self.plots["s10_plot"] = figure( + name="s10_plot", title="Significant digits s over runs", + plot_width=900, plot_height=400, x_range=[""], + tools=tools, sizing_mode="scale_width" + ) + + s10_tooltips = [ + ("Git commit", "@is_git_commit"), + ("Date", "@date"), + ("Hash", "@hash"), + ("Author", "@author"), + ("Message", "@message"), + ("s", "@s10"), + ("s lower bound", "@s10_lower_bound"), + ("Number of samples", "@nsamples") + ] + + plot.fill_dotplot( + self.plots["s10_plot"], self.sources["s10_source"], "s10", + tooltips = s10_tooltips, + js_tap_callback = js_tap_callback, + server_tap_callback = self.inspect_run_callback_s10, + lines = True, + lower_bound=True + ) + s10_tab = Panel(child=self.plots["s10_plot"], title="Base 10") + + + self.plots["s2_plot"] = figure( + name="s2_plot", title="Significant digits s over runs", + plot_width=900, plot_height=400, x_range=[""], + tools=tools, sizing_mode="scale_width" + ) + + s2_tooltips = [ + ("Git commit", "@is_git_commit"), + ("Date", "@date"), + ("Hash", "@hash"), + ("Author", "@author"), + ("Message", "@message"), + ("s", "@s2"), + ("s lower bound", "@s2_lower_bound"), + ("Number of samples", "@nsamples") + ] + + plot.fill_dotplot( + self.plots["s2_plot"], self.sources["s2_source"], "s2", + tooltips = s2_tooltips, + js_tap_callback = js_tap_callback, + server_tap_callback = self.inspect_run_callback_s2, + lines = True, + lower_bound=True + ) + s2_tab = Panel(child=self.plots["s2_plot"], title="Base 2") + + s_tabs = Tabs( + name = "s_tabs", + tabs=[s10_tab, s2_tab], + tabs_location = "below" + ) + + self.doc.add_root(s_tabs) + + + def setup_widgets(self): + + # Initial selections + + # Test/var/backend combination (we select all first elements at init) + self.tests = self.data\ + .index.get_level_values("test").drop_duplicates().tolist() + + self.vars = self.data.loc[self.tests[0]]\ + .index.get_level_values("variable").drop_duplicates().tolist() + + self.backends = self.data.loc[self.tests[0], self.vars[0]]\ + .index.get_level_values("vfc_backend").drop_duplicates().tolist() + + + # Custom JS callback that will be used client side to filter selections + filter_callback_js = """ + selector.options = options.filter(e => e.includes(cb_obj.value)); + """ + + + # Test selector widget + + # Number of runs to display + # The dict structure allows us to get int value from the display string + # in O(1) + self.n_runs_dict = { + "Last 3 runs": 3, + "Last 5 runs": 5, + "Last 10 runs": 10, + "All runs": 0 + } + + # Contains all options strings + n_runs_display = list(self.n_runs_dict.keys()) + + # Will be used when updating plots (contains actual number to diplay) + self.current_n_runs = self.n_runs_dict[n_runs_display[1]] + + # Selector widget + self.widgets["select_test"] = Select( + name="select_test", title="Test :", + value=self.tests[0], options=self.tests + ) + self.doc.add_root(self.widgets["select_test"]) + self.widgets["select_test"].on_change("value", self.update_test) + self.widgets["select_test"].on_change("options", self.update_test) + + # Filter widget + self.widgets["test_filter"] = TextInput( + name="test_filter", title="Tests filter:" + ) + self.widgets["test_filter"].js_on_change("value", CustomJS( + args=dict(options=self.tests, selector=self.widgets["select_test"]), + code=filter_callback_js + )) + self.doc.add_root(self.widgets["test_filter"]) + + + # Number of runs to display + + self.widgets["select_n_runs"] = Select( + name="select_n_runs", title="Display :", + value=n_runs_display[1], options=n_runs_display + ) + self.doc.add_root(self.widgets["select_n_runs"]) + self.widgets["select_n_runs"].on_change("value", self.update_n_runs) + + + # Variable selector widget + + self.widgets["select_var"] = Select( + name="select_var", title="Variable :", + value=self.vars[0], options=self.vars + ) + self.doc.add_root(self.widgets["select_var"]) + self.widgets["select_var"].on_change("value", self.update_var) + self.widgets["select_var"].on_change("options", self.update_var) + + + # Backend selector widget + + self.widgets["select_backend"] = Select( + name="select_backend", title="Verificarlo backend :", + value=self.backends[0], options=self.backends + ) + self.doc.add_root(self.widgets["select_backend"]) + self.widgets["select_backend"].on_change("value", self.update_backend) + + + # Outliers filtering checkbox + + self.widgets["outliers_filtering_compare"] = CheckboxGroup( + name="outliers_filtering_compare", + labels=["Filter outliers"], active =[] + ) + self.doc.add_root(self.widgets["outliers_filtering_compare"]) + self.widgets["outliers_filtering_compare"]\ + .on_change("active", self.update_outliers_filtering) + + + + # Communication methods + # (to send/receive messages to/from master) + + # Callback to change view of Inspect runs when data is selected + def inspect_run_callback(self, new, source_name, x_name): + + # In case we just unselected everything, then do nothing + if new == []: + return + + index = new[-1] + run_name = self.sources[source_name].data[x_name][index] + + self.master.go_to_inspect(run_name) + + + # Wrappers for each plot (since new is the index of the clicked element, + # it is dependent of the plot because we could have filtered some outliers) + # There doesn't seem to be an easy way to add custom parameters to a + # Bokeh callback, so using wrappers seems to be the best solution for now + + def inspect_run_callback_boxplot(self, attr, old, new): + self.inspect_run_callback(new, "boxplot_source", "x") + + def inspect_run_callback_sigma(self, attr, old, new): + self.inspect_run_callback(new, "sigma_source", "sigma_x") + + def inspect_run_callback_s2(self, attr, old, new): + self.inspect_run_callback(new, "s2_source", "s2_x") + + def inspect_run_callback_s10(self, attr, old, new): + self.inspect_run_callback(new, "s10_source", "s10_x") + + + # Constructor + + def __init__(self, master, doc, data, metadata): + + self.master = master + + self.doc = doc + self.data = data + self.metadata = metadata + + + self.sources = { + "boxplot_source": ColumnDataSource(data={}), + "sigma_source": ColumnDataSource(data={}), + "s10_source" :ColumnDataSource(data={}), + "s2_source": ColumnDataSource(data={}) + } + + self.plots = {} + self.widgets = {} + + # Setup Bokeh objects + self.setup_plots() + self.setup_widgets() + + # At this point, everything should have been initialized, so we can + # show the plots for the first time + self.update_plots() diff --git a/ci/vfc_ci_report/helper.py b/ci/vfc_ci_report/helper.py new file mode 100644 index 0000000..57c84d7 --- /dev/null +++ b/ci/vfc_ci_report/helper.py @@ -0,0 +1,166 @@ +# General helper functions for both compare_runs and compare_variables + +import calendar +import time +from itertools import compress + +import numpy as np + +# Magic numbers +max_ticks = 15 +max_zscore = 3 + +################################################################################ + + +# From a timestamp, return the associated metadata as a Pandas serie +def get_metadata(metadata, timestamp): + return metadata.loc[timestamp] + + +# Convert a metadata Pandas series to a JS readable dict +def metadata_to_dict(metadata): + dict = metadata.to_dict() + + # JS doesn't accept True for booleans, and Python doesn't accept true + # (because of the caps) => using an integer is a portable solution + dict["is_git_commit"] = 1 if dict["is_git_commit"] else 0 + + dict["date"] = time.ctime(metadata.name) + + return dict + + +# Return a string that indicates the elapsed time since the run, used as the +# x-axis tick in "Compare runs" or when selecting run in "Inspect run" +def get_run_name(timestamp, hash): + + gmt = time.gmtime() + now = calendar.timegm(gmt) + diff = now - timestamp + + + # Special case : < 1 minute (return string directly) + if diff < 60: + str = "Less than a minute ago" + + if hash != "": + str = str + " (%s)" % hash + + if str == get_run_name.previous: + get_run_name.counter = get_run_name.counter + 1 + str = "%s (%s)" % (str, get_run_name.counter) + else: + get_run_name.counter = 0 + get_run_name.previous = str + + return str + + # < 1 hour + if diff < 3600: + n = int(diff / 60) + str = "%s minute%s ago" + # < 1 day + elif diff < 86400: + n = int(diff / 3600) + str = "%s hour%s ago" + # < 1 week + elif diff < 604800: + n = int(diff / 86400) + str = "%s day%s ago" + # < 1 month + elif diff < 2592000: + n = int(diff / 604800) + str = "%s week%s ago" + # > 1 month + else: + n = diff / 2592000 + str = "%s month%s ago" + + plural = "" + if n != 1: + plural = "s" + + str = str % (n, plural) + + + # We might want to add the git hash + if hash != "": + str = str + " (%s)" % hash + + + # Finally, check for duplicate with previously generated string + if str == get_run_name.previous: + # Increment the duplicate counter and add it to str + get_run_name.counter = get_run_name.counter + 1 + str = "%s (%s)" % (str, get_run_name.counter) + + else: + # No duplicate, reset both previously generated str and duplicate counter + get_run_name.counter = 0 + get_run_name.previous = str + + return str + +# These external variables will store data about the last generated string to +# avoid duplicates (assuming the runs are sorted by time) +get_run_name.counter = 0 +get_run_name.previous = "" + + +def reset_run_strings(): + get_run_name.counter = 0 + get_run_name.previous = "" + + +# Update all the x-ranges from a dict of plots +def reset_x_range(plot, x_range): + plot.x_range.factors = x_range + + if len(x_range) < max_ticks: + plot.xaxis.major_tick_line_color = "#000000" + plot.xaxis.minor_tick_line_color = "#000000" + + plot.xaxis.major_label_text_font_size = "8pt" + + else: + plot.xaxis.major_tick_line_color = None + plot.xaxis.minor_tick_line_color = None + + plot.xaxis.major_label_text_font_size = "0pt" + + +# Return an array of booleans that indicate which elements are outliers +# (True means element is not an outlier and must be kept) +def detect_outliers(array, max_zscore=max_zscore): + if len(array) <= 2: + return [True] * len(array) + + median = np.median(array) + std = np.std(array) + if std == 0: + return array + distance = abs(array - median) + # Array of booleans with elements to be filtered + outliers_array = distance < max_zscore * std + + return outliers_array + + +def remove_outliers(array, outliers): + return list(compress(array, outliers)) + + +def remove_boxplot_outliers(dict, outliers, prefix): + outliers = detect_outliers(dict["%s_max" % prefix]) + + dict["%s_x" % prefix] = remove_outliers(dict["%s_x" % prefix], outliers) + + dict["%s_min" % prefix] = remove_outliers(dict["%s_min" % prefix], outliers) + dict["%s_quantile25" % prefix] = remove_outliers(dict["%s_quantile25" % prefix], outliers) + dict["%s_quantile50" % prefix] = remove_outliers(dict["%s_quantile50" % prefix], outliers) + dict["%s_quantile75" % prefix] = remove_outliers(dict["%s_quantile75" % prefix], outliers) + dict["%s_max" % prefix] = remove_outliers(dict["%s_max" % prefix], outliers) + dict["%s_mu" % prefix] = remove_outliers(dict["%s_mu" % prefix], outliers) + + dict["nsamples"] = remove_outliers(dict["nsamples"], outliers) diff --git a/ci/vfc_ci_report/inspect_runs.py b/ci/vfc_ci_report/inspect_runs.py new file mode 100644 index 0000000..57a1caa --- /dev/null +++ b/ci/vfc_ci_report/inspect_runs.py @@ -0,0 +1,588 @@ +# Manage the view comparing the variables of a run + +from math import pi +from functools import partial + +import pandas as pd +import numpy as np + +from bokeh.plotting import figure, curdoc +from bokeh.embed import components +from bokeh.models import Select, ColumnDataSource, Panel, Tabs, HoverTool,\ +RadioButtonGroup, CheckboxGroup, CustomJS + +import helper +import plot + + +################################################################################ + + + +class InspectRuns: + + # Helper functions related to InspectRun + + # Returns a dictionary mapping user-readable strings to all run timestamps + def gen_runs_selection(self): + + runs_dict = {} + + # Iterate over timestamp rows (runs) and fill dict + for row in self.metadata.iloc: + # The syntax used by pandas makes this part a bit tricky : + # row.name is the index of metadata (so it refers to the + # timestamp), whereas row["name"] is the column called "name" + # (which is the display string used for the run) + + # runs_dict[run's name] = run's timestamp + runs_dict[row["name"]] = row.name + + return runs_dict + + + def gen_boxplot_tooltips(self, prefix): + return [ + ("Name", "@%s_x" % prefix), + ("Min", "@" + prefix + "_min{%0.18e}"), + ("Max", "@" + prefix + "_max{%0.18e}"), + ("1st quartile", "@" + prefix + "_quantile25{%0.18e}"), + ("Median", "@" + prefix + "_quantile50{%0.18e}"), + ("3rd quartile", "@" + prefix + "_quantile75{%0.18e}"), + ("μ", "@" + prefix + "_mu{%0.18e}"), + ("Number of samples (tests)", "@nsamples") + ] + + def gen_boxplot_tooltips_formatters(self, prefix): + return { + "@%s_min" % prefix : "printf", + "@%s_max" % prefix : "printf", + "@%s_quantile25" % prefix : "printf", + "@%s_quantile50" % prefix : "printf", + "@%s_quantile75" % prefix : "printf", + "@%s_mu" % prefix : "printf" + } + + + # Data processing helper + # (computes new distributions for sigma, s2, s10) + def data_processing(self, dataframe): + + # Compute aggragated mu + dataframe["mu"] = np.vectorize(np.average)(dataframe["mu"], weights=dataframe["nsamples"]) + + # nsamples is the number of aggregated elements (as well as the number + # of samples for our new sigma and s distributions) + dataframe["nsamples"] = dataframe["nsamples"].apply(lambda x: len(x)) + + + dataframe["mu_x"] = dataframe.index + # Make sure that strings don't excede a certain length + dataframe["mu_x"] = dataframe["mu_x"].apply( + lambda x: x[:17] + "[...]" + x[-17:] if len(x) > 39 else x + ) + + + # Get quantiles and mu for sigma, s10, s2 + for prefix in ["sigma", "s10", "s2"]: + + dataframe["%s_x" % prefix] = dataframe["mu_x"] + + dataframe[prefix] = dataframe[prefix].apply(np.sort) + + dataframe["%s_min" % prefix] = dataframe[prefix].apply(np.min) + dataframe["%s_quantile25" % prefix] = dataframe[prefix].apply(np.quantile, args=(0.25,)) + dataframe["%s_quantile50" % prefix] = dataframe[prefix].apply(np.quantile, args=(0.50,)) + dataframe["%s_quantile75" % prefix] = dataframe[prefix].apply(np.quantile, args=(0.75,)) + dataframe["%s_max" % prefix] = dataframe[prefix].apply(np.max) + dataframe["%s_mu" % prefix] = dataframe[prefix].apply(np.average) + del dataframe[prefix] + + + return dataframe + + + + # Plots update function + + def update_plots(self): + + groupby_display = self.widgets["groupby_radio"].labels[ + self.widgets["groupby_radio"].active + ] + groupby = self.factors_dict[groupby_display] + + filterby_display = self.widgets["filterby_radio"].labels[ + self.widgets["filterby_radio"].active + ] + filterby = self.factors_dict[filterby_display] + + + # Groupby and aggregate lines belonging to the same group in lists + + groups = self.run_data[ + self.run_data.index.isin( + [self.widgets["select_filter"].value], + level=filterby + ) + ].groupby(groupby) + + groups = groups.agg({ + "sigma": lambda x: x.tolist(), + "s10": lambda x: x.tolist(), + "s2": lambda x: x.tolist(), + "mu": lambda x: x.tolist(), + + # Used for mu weighted average first, then will be replaced + "nsamples": lambda x: x.tolist() + }) + + + # Compute the new distributions, ... + groups = self.data_processing(groups).to_dict("list") + + + # Update source + + # Assign each ColumnDataSource, starting with the boxplots + for prefix in ["sigma", "s10", "s2"]: + + dict = { + "%s_x" % prefix: groups["%s_x" % prefix], + "%s_min" % prefix: groups["%s_min" % prefix], + "%s_quantile25" % prefix: groups["%s_quantile25" % prefix], + "%s_quantile50" % prefix: groups["%s_quantile50" % prefix], + "%s_quantile75" % prefix: groups["%s_quantile75" % prefix], + "%s_max" % prefix: groups["%s_max" % prefix], + "%s_mu" % prefix: groups["%s_mu" % prefix], + + "nsamples": groups["nsamples"] + } + + # Filter outliers if the box is checked + if len(self.widgets["outliers_filtering_inspect"].active) > 0: + + # Boxplots will be filtered by max then min + top_outliers = helper.detect_outliers(dict["%s_max" % prefix]) + helper.remove_boxplot_outliers(dict, top_outliers, prefix) + + bottom_outliers = helper.detect_outliers(dict["%s_min" % prefix]) + helper.remove_boxplot_outliers(dict, bottom_outliers, prefix) + + self.sources["%s_source" % prefix].data = dict + + # Finish with the mu plot + dict = { + "mu_x": groups["mu_x"], + "mu": groups["mu"], + + "nsamples": groups["nsamples"] + } + + self.sources["mu_source"].data = dict + + # Filter outliers if the box is checked + if len(self.widgets["outliers_filtering_inspect"].active) > 0: + mu_outliers = helper.detect_outliers(groups["mu"]) + groups["mu"] = helper.remove_outliers(groups["mu"], mu_outliers) + groups["mu_x"] = helper.remove_outliers(groups["mu_x"], mu_outliers) + + + # Update plots axis/titles + + # Get display string of the last (unselected) factor + factors_dict = self.factors_dict.copy() + del factors_dict[groupby_display] + del factors_dict[filterby_display] + over_all = list(factors_dict.keys())[0] + + # Update all display strings for plot title (remove caps, plural) + groupby_display = groupby_display.lower() + filterby_display = filterby_display.lower()[:-1] + over_all = over_all.lower() + + self.plots["mu_inspect"].title.text = \ + "Empirical average μ of %s (groupped by %s, for all %s)" \ + % (filterby_display, groupby_display, over_all) + + self.plots["sigma_inspect"].title.text = \ + "Standard deviation σ of %s (groupped by %s, for all %s)" \ + % (filterby_display, groupby_display, over_all) + + self.plots["s10_inspect"].title.text = \ + "Significant digits s of %s (groupped by %s, for all %s)" \ + % (filterby_display, groupby_display, over_all) + + self.plots["s2_inspect"].title.text = \ + "Significant digits s of %s (groupped by %s, for all %s)" \ + % (filterby_display, groupby_display, over_all) + + + # Update x_ranges + + helper.reset_x_range(self.plots["mu_inspect"], groups["mu_x"]) + helper.reset_x_range(self.plots["sigma_inspect"], groups["sigma_x"]) + helper.reset_x_range(self.plots["s10_inspect"], groups["s10_x"]) + helper.reset_x_range(self.plots["s2_inspect"], groups["s2_x"]) + + + + # Widets' callback functions + + # Run selector callback + def update_run(self, attrname, old, new): + + filterby = self.widgets["filterby_radio"].labels[ + self.widgets["filterby_radio"].active + ] + filterby = self.factors_dict[filterby] + + # Update run selection (by using dict mapping) + self.current_run = self.runs_dict[new] + + # Update run data + self.run_data = self.data[self.data["timestamp"] == self.current_run] + + # Save old selected option + old_value = self.widgets["select_filter"].value + + # Update filter options + options = self.run_data.index\ + .get_level_values(filterby).drop_duplicates().tolist() + self.widgets["select_filter"].options = options + + if old_value not in self.widgets["select_filter"].options: + self.widgets["select_filter"].value = options[0] + # The update_var callback will be triggered by the assignment + + else: + # Trigger the callback manually (since the plots need to be updated + # anyway) + self.update_filter("", "", old_value) + + + # "Group by" radio + def update_groupby(self, attrname, old, new): + + # Update "Filter by" radio list + filterby_list = list(self.factors_dict.keys()) + del filterby_list[self.widgets["groupby_radio"].active] + self.widgets["filterby_radio"].labels = filterby_list + + + filterby = self.widgets["filterby_radio"].labels[ + self.widgets["filterby_radio"].active + ] + filterby = self.factors_dict[filterby] + + # Save old selected option + old_value = self.widgets["select_filter"].value + + # Update filter options + options = self.run_data.index\ + .get_level_values(filterby).drop_duplicates().tolist() + self.widgets["select_filter"].options = options + + if old_value not in self.widgets["select_filter"].options: + self.widgets["select_filter"].value = options[0] + # The update_var callback will be triggered by the assignment + + else: + # Trigger the callback manually (since the plots need to be updated + # anyway) + self.update_filter("", "", old_value) + + + # "Filter by" radio + def update_filterby(self, attrname, old, new): + + filterby = self.widgets["filterby_radio"].labels[ + self.widgets["filterby_radio"].active + ] + filterby = self.factors_dict[filterby] + + # Save old selected option + old_value = self.widgets["select_filter"].value + + # Update filter selector options + options = self.run_data.index\ + .get_level_values(filterby).drop_duplicates().tolist() + self.widgets["select_filter"].options = options + + if old_value not in self.widgets["select_filter"].options: + self.widgets["select_filter"].value = options[0] + # The update_var callback will be triggered by the assignment + + else: + # Trigger the callback manually (since the plots need to be updated + # anyway) + self.update_filter("", "", old_value) + + + # Filter selector callback + def update_filter(self, attrname, old, new): + self.update_plots() + + + # Filter outliers checkbox callback + def update_outliers_filtering(self, attrname, old, new): + # The status (checked/unchecked) of the checkbox is also verified inside + # self.update_plots(), so calling this function is enough + self.update_plots() + + + + # Bokeh setup functions + # (for both variable and backend selection at once) + + def setup_plots(self): + + tools = "pan, wheel_zoom, xwheel_zoom, ywheel_zoom, reset, save" + + + # Tooltips and formatters + + dotplot_tooltips = [ + ("Name", "@mu_x"), + ("μ", "@mu{%0.18e}"), + ("Number of samples (tests)", "@nsamples") + ] + dotplot_formatters = { + "@mu" : "printf" + } + + sigma_boxplot_tooltips = self.gen_boxplot_tooltips("sigma") + sigma_boxplot_tooltips_formatters = self.gen_boxplot_tooltips_formatters("sigma") + + s10_boxplot_tooltips = self.gen_boxplot_tooltips("s10") + s10_boxplot_tooltips_formatters = self.gen_boxplot_tooltips_formatters("s10") + + s2_boxplot_tooltips = self.gen_boxplot_tooltips("s2") + s2_boxplot_tooltips_formatters = self.gen_boxplot_tooltips_formatters("s2") + + + # Plots + + # Mu plot + self.plots["mu_inspect"] = figure( + name="mu_inspect", + title="", + plot_width=900, plot_height=400, x_range=[""], + tools=tools, sizing_mode="scale_width" + ) + plot.fill_dotplot( + self.plots["mu_inspect"], self.sources["mu_source"], "mu", + tooltips = dotplot_tooltips, + tooltips_formatters = dotplot_formatters + ) + self.doc.add_root(self.plots["mu_inspect"]) + + + # Sigma plot + self.plots["sigma_inspect"] = figure( + name="sigma_inspect", + title="", + plot_width=900, plot_height=400, x_range=[""], + tools=tools, sizing_mode="scale_width" + ) + plot.fill_boxplot( + self.plots["sigma_inspect"], self.sources["sigma_source"], prefix="sigma", + tooltips = sigma_boxplot_tooltips, + tooltips_formatters = sigma_boxplot_tooltips_formatters + ) + self.doc.add_root(self.plots["sigma_inspect"]) + + + # s plots + self.plots["s10_inspect"] = figure( + name="s10_inspect", + title="", + plot_width=900, plot_height=400, x_range=[""], + tools=tools, sizing_mode='scale_width' + ) + plot.fill_boxplot( + self.plots["s10_inspect"], self.sources["s10_source"], prefix="s10", + tooltips = s10_boxplot_tooltips, + tooltips_formatters = s10_boxplot_tooltips_formatters + ) + s10_tab_inspect = Panel(child=self.plots["s10_inspect"], title="Base 10") + + self.plots["s2_inspect"] = figure( + name="s2_inspect", + title="", + plot_width=900, plot_height=400, x_range=[""], + tools=tools, sizing_mode='scale_width' + ) + plot.fill_boxplot( + self.plots["s2_inspect"], self.sources["s2_source"], prefix="s2", + tooltips = s2_boxplot_tooltips, + tooltips_formatters = s2_boxplot_tooltips_formatters + ) + s2_tab_inspect = Panel(child=self.plots["s2_inspect"], title="Base 2") + + s_tabs_inspect = Tabs( + name = "s_tabs_inspect", + tabs=[s10_tab_inspect, s2_tab_inspect], tabs_location = "below" + ) + self.doc.add_root(s_tabs_inspect) + + + + def setup_widgets(self): + + # Generation of selectable items + + # Dict contains all inspectable runs (maps display strings to timestamps) + # The dict structure allows to get the timestamp from the display string + # in O(1) + self.runs_dict = self.gen_runs_selection() + + # Dict maps display strings to column names for the different factors + # (var, backend, test) + self.factors_dict = { + "Variables": "variable", + "Backends": "vfc_backend", + "Tests": "test" + } + + + # Run selection + + # Contains all options strings + runs_display = list(self.runs_dict.keys()) + # Will be used when updating plots (contains actual number) + self.current_run = self.runs_dict[runs_display[-1]] + # Contains the selected option string, used to update current_n_runs + current_run_display = runs_display[-1] + # This contains only entries matching the run + self.run_data = self.data[self.data["timestamp"] == self.current_run] + + + change_run_callback_js="updateRunMetadata(cb_obj.value);" + + self.widgets["select_run"] = Select( + name="select_run", title="Run :", + value=current_run_display, options=runs_display + ) + self.doc.add_root(self.widgets["select_run"]) + self.widgets["select_run"].on_change("value", self.update_run) + self.widgets["select_run"].js_on_change("value", CustomJS( + code = change_run_callback_js, + args=(dict( + metadata=helper.metadata_to_dict( + helper.get_metadata(self.metadata, self.current_run) + ) + )) + )) + + + # Factors selection + + # "Group by" radio + self.widgets["groupby_radio"] = RadioButtonGroup( + name="groupby_radio", + labels=list(self.factors_dict.keys()), active=0 + ) + self.doc.add_root(self.widgets["groupby_radio"]) + # The functions are defined inside the template to avoid writing too + # much JS server side + self.widgets["groupby_radio"].on_change( + "active", + self.update_groupby + ) + + + # "Filter by" radio + # Get all possible factors, and remove the one selected in "Group by" + filterby_list = list(self.factors_dict.keys()) + del filterby_list[self.widgets["groupby_radio"].active] + + self.widgets["filterby_radio"] = RadioButtonGroup( + name="filterby_radio", + labels=filterby_list, active=0 + ) + self.doc.add_root(self.widgets["filterby_radio"]) + # The functions are defined inside the template to avoid writing too + # much JS server side + self.widgets["filterby_radio"].on_change( + "active", + self.update_filterby + ) + + + # Filter selector + + filterby = self.widgets["filterby_radio"].labels[ + self.widgets["filterby_radio"].active + ] + filterby = self.factors_dict[filterby] + + options = self.run_data.index\ + .get_level_values(filterby).drop_duplicates().tolist() + + self.widgets["select_filter"] = Select( + # We need a different name to avoid collision in the template with + # the runs comparison's widget + name="select_filter", title="Select a filter :", + value=options[0], options=options + ) + self.doc.add_root(self.widgets["select_filter"]) + self.widgets["select_filter"]\ + .on_change("value", self.update_filter) + + + # Toggle for outliers filtering + + self.widgets["outliers_filtering_inspect"] = CheckboxGroup( + name="outliers_filtering_inspect", + labels=["Filter outliers"], active = [] + ) + self.doc.add_root(self.widgets["outliers_filtering_inspect"]) + self.widgets["outliers_filtering_inspect"]\ + .on_change("active", self.update_outliers_filtering) + + + + # Communication methods + # (to send/receive messages to/from master) + + # When received, switch to the run_name in parameter + def switch_view(self, run_name): + self.widgets["select_run"].value = run_name + + + + # Constructor + + def __init__(self, master, doc, data, metadata): + + self.master = master + + self.doc = doc + self.data = data + self.metadata = metadata + + + self.sources = { + "mu_source": ColumnDataSource(data={}), + "sigma_source": ColumnDataSource(data={}), + "s10_source" :ColumnDataSource(data={}), + "s2_source": ColumnDataSource(data={}) + } + + self.plots = {} + self.widgets = {} + + # Setup Bokeh objects + self.setup_plots() + self.setup_widgets() + + # Pass the initial metadata to the template (will be updated in CustomJS + # callbacks). This is required because metadata is not displayed in a + # Bokeh widget, so we can't update this with a server callback. + initial_run = helper.get_metadata(self.metadata, self.current_run) + self.doc.template_variables["initial_timestamp"] = self.current_run + + # At this point, everything should have been initialized, so we can + # show the plots for the first time + self.update_plots() diff --git a/ci/vfc_ci_report/main.py b/ci/vfc_ci_report/main.py new file mode 100644 index 0000000..d011b3e --- /dev/null +++ b/ci/vfc_ci_report/main.py @@ -0,0 +1,217 @@ +# Look for and read all the run files in the current directory (ending with +# .vfcrun.hd5), and lanch a Bokeh server for the visualization of this data. + +import os +import sys +import time + +import pandas as pd + +from bokeh.plotting import curdoc + +# Local imports from vfc_ci_server +import compare_runs +import inspect_runs +import helper + +################################################################################ + + + # Read vfcrun files, and aggregate them in one dataset + +run_files = [ f for f in os.listdir(".") if f.endswith(".vfcrun.hd5") ] + +if len(run_files) == 0: + print( + "Warning [vfc_ci]: Could not find any vfcrun files in the directory. " \ + "This will result in server errors and prevent you from viewing the report." + ) + +# These are arrays of Pandas dataframes for now +metadata = [] +data = [] + +for f in run_files: + metadata.append(pd.read_hdf(f, "metadata")) + data.append(pd.read_hdf(f, "data")) + +metadata = pd.concat(metadata).sort_index() +data = pd.concat(data).sort_index() + + +# Generate the display strings for runs (runs ticks) +# By doing this in master, we ensure the homogeneity of display strings +# across all plots +metadata["name"] = metadata.index.to_series().map( + lambda x: helper.get_run_name( + x, + helper.get_metadata(metadata, x)["hash"] + ) +) +helper.reset_run_strings() + +metadata["date"] = metadata.index.to_series().map( + lambda x: time.ctime(x) +) + + +################################################################################ + + +curdoc().title = "Verificarlo Report" + + + # Read server arguments + # (this is quite easy because Bokeh server is called through a wrapper, so + # we know exactly what the arguments might be) + +git_repo_linked = False +commit_link = "" + +has_logo = False +logo_url = "" + +for i in range(1, len(sys.argv)): + + # Look for the Git repository remote address + # (if a Git repo is specified, the webpage will contain hyperlinks to the + # repository and the different commits) + if sys.argv[i] == "git": + from urllib.parse import urlparse + + method = sys.argv[i + 1] + address = sys.argv[i + 2] + url = "" + + + # Here, address is either the remote URL or the path to the local Git + # repo (depending on the method) + + if method == "url": + # We should directly have a Git URL + url = address + + elif method == "directory": + # Get the remote URL from the local repo + from git import Repo + repo = Repo(address) + url = repo.remotes.origin.url + + else: + raise ValueError( + "Error [vfc_ci]: The specified method to get the Git " \ + "repository is invalid. Are you calling Bokeh directly " \ + "instead of using the Verificarlo wrapper ?" + ) + + + # At this point, "url" should be set correctly, we can get the repo's + # URL and name, after making sure we're on a Git URL + + parsed_url = urlparse(url) + + path = parsed_url.path.split("/") + if len(path) < 3: + raise ValueError( + "Error [vfc_ci]: The found URL doesn't seem to be pointing " \ + "to a Git repository (path is too short)" + ) + + repo_name = path[2] + + curdoc().template_variables["repo_url"] = url + curdoc().template_variables["repo_name"] = repo_name + + + # We should have a "github.com" or a "*gitlab*" URL + + if parsed_url.netloc == "github.com": + commit_link = "https://%s%s/commit/" \ + % (parsed_url.netloc, parsed_url.path) + + curdoc().template_variables["commit_link"] = commit_link + curdoc().template_variables["git_host"] = "GitHub" + + # Used in Bokeh tooltips + commit_link = commit_link + "@hash" + + # We assume we have a GitLab URL + else: + commit_link = "https://%s%s/-/commit/" \ + % (parsed_url.netloc, parsed_url.path) + + curdoc().template_variables["commit_link"] = commit_link + curdoc().template_variables["git_host"] = "GitLab" + + # Used in Bokeh tooltips + commit_link = commit_link + "@hash" + + git_repo_linked = True + + + + # Look for a logo URL + # If a logo URL is specified, it will be included in the report's header + if sys.argv[i] == "logo": + curdoc().template_variables["logo_url"] = sys.argv[i + 1] + has_logo = True + + +# After the loop, we know if a repo has been linked, if we have a logo, ... +curdoc().template_variables["git_repo_linked"] = git_repo_linked +curdoc().template_variables["has_logo"] = has_logo + + +################################################################################ + + + # Setup report views + +# Define a ViewsMaster class to allow two-ways communication between views. +# This approach by classes allows us to have separate scopes for each view and +# will be useful if we want to add new views at some point in the future +# (instead of having n views with n-1 references each). + +class ViewsMaster: + + # Communication functions + + def go_to_inspect(self, run_name): + self.inspect.switch_view(run_name) + + + #Constructor + + def __init__(self, data, metadata, git_repo_linked, commit_link): + + self.data = data + self.metadata = metadata + self.git_repo_linked = git_repo_linked + self.commit_link = commit_link + + # Pass metadata to the template as a JSON string + curdoc().template_variables["metadata"] = self.metadata.to_json(orient="index") + + # Runs comparison + self.compare = compare_runs.CompareRuns( + master = self, + doc = curdoc(), + data = data, + metadata = metadata, + ) + + # Runs inspection + self.inspect = inspect_runs.InspectRuns( + master = self, + doc = curdoc(), + data = data, + metadata = metadata, + ) + + +views_master = ViewsMaster( + data = data, + metadata = metadata, + git_repo_linked = git_repo_linked, + commit_link = commit_link +) diff --git a/ci/vfc_ci_report/plot.py b/ci/vfc_ci_report/plot.py new file mode 100644 index 0000000..270266e --- /dev/null +++ b/ci/vfc_ci_report/plot.py @@ -0,0 +1,151 @@ +# General functions for filling plots with data in all report's views + +from bokeh.plotting import figure +from bokeh.models import HoverTool, TapTool, CustomJS + +from math import pi + + +def fill_dotplot( + plot, source, data_field, + tooltips=None, tooltips_formatters=None, + js_tap_callback=None, server_tap_callback=None, + lines=False, + lower_bound=False +): + + # (Optional) Tooltip and tooltip formatters + if tooltips != None: + hover = HoverTool(tooltips = tooltips, mode="vline", names=["circle"]) + + if tooltips_formatters != None: + hover.formatters = tooltips_formatters + + plot.add_tools(hover) + + + # (Optional) Add TapTool (for JS tap callback) + if js_tap_callback != None: + tap = TapTool(callback=CustomJS(code=js_tap_callback)) + plot.add_tools(tap) + + + # (Optional) Add segment to represent a lower bound + if lower_bound: + lower_segment = plot.segment( + x0="%s_x" % data_field, y0=data_field, + x1="%s_x" % data_field, y1="%s_lower_bound" % data_field, + source=source, line_color="black" + ) + + + # Draw dots (actually Bokeh circles) + circle = plot.circle( + name="circle", + x="%s_x" % data_field, y=data_field, source=source, size=12 + ) + + + # (Optional) Draw lines between dots + if lines: + line = plot.line(x="%s_x" % data_field, y=data_field, source=source) + + + # (Optional) Add server tap callback + if server_tap_callback != None: + circle.data_source.selected.on_change("indices", server_tap_callback) + + + # Plot appearance + plot.xgrid.grid_line_color = None + plot.ygrid.grid_line_color = None + + plot.yaxis[0].formatter.power_limit_high = 0 + plot.yaxis[0].formatter.power_limit_low = 0 + plot.yaxis[0].formatter.precision = 3 + + plot.xaxis[0].major_label_orientation = pi/8 + + + +def fill_boxplot( + plot, source, + prefix="", + tooltips=None, tooltips_formatters=None, + js_tap_callback=None, server_tap_callback=None, +): + + # (Optional) Tooltip and tooltip formatters + if tooltips != None: + hover = HoverTool(tooltips = tooltips, mode="vline", names=["full_box"]) + + if tooltips_formatters != None: + hover.formatters = tooltips_formatters + + plot.add_tools(hover) + + + # (Optional) Add TapTool (for JS tap callback) + if js_tap_callback != None: + tap = TapTool(callback=CustomJS(code=js_tap_callback)) + plot.add_tools(tap) + + + # Draw boxes (the prefix argument modifies the fields of ColumnDataSource + # that are used) + + if prefix != "": + prefix = "%s_" % prefix + + # Stems + top_stem = plot.segment( + x0="%sx" % prefix, y0="%smax" % prefix, + x1="%sx" % prefix, y1="%squantile75" % prefix, + source=source, line_color="black" + ) + bottom_stem = plot.segment( + x0="%sx" % prefix, y0="%smin" % prefix, + x1="%sx" % prefix, y1="%squantile25" % prefix, + source=source, line_color="black" + ) + + # Boxes + full_box = plot.vbar( + name="full_box", + x="%sx" % prefix, width=0.5, + top="%squantile75" % prefix, bottom="%squantile25" % prefix, + source=source, line_color="black" + ) + bottom_box = plot.vbar( + x="%sx" % prefix, width=0.5, + top="%squantile50" % prefix, bottom="%squantile25" % prefix, + source=source, line_color="black" + ) + + # Mu dot + mu_dot = plot.dot( + x="%sx" % prefix, y="%smu" % prefix, size=30, source=source, + color="black" + ) + + + # (Optional) Add server tap callback + if server_tap_callback != None: + top_stem.data_source.selected.on_change("indices", server_tap_callback) + bottom_stem.data_source.selected.on_change("indices", server_tap_callback) + + full_box.data_source.selected.on_change("indices", server_tap_callback) + bottom_box.data_source.selected.on_change("indices", server_tap_callback) + + mu_dot.data_source.selected.on_change("indices", server_tap_callback) + + + # Plot appearance + plot.xgrid.grid_line_color = None + plot.ygrid.grid_line_color = None + + plot.yaxis[0].formatter.power_limit_high = 0 + plot.yaxis[0].formatter.power_limit_low = 0 + plot.yaxis[0].formatter.precision = 3 + + plot.xaxis[0].major_label_orientation = pi/8 diff --git a/ci/vfc_ci_report/templates/index.html b/ci/vfc_ci_report/templates/index.html new file mode 100644 index 0000000..2ec7fc6 --- /dev/null +++ b/ci/vfc_ci_report/templates/index.html @@ -0,0 +1,480 @@ + + + + + Verificarlo Report + + + + + + + + + + {% extends base %} + + + + + {% block contents %} + + + + + + + +
+ + {% if has_logo %} + + {% else %} + + {% endif %} +
+ + + + + {% endblock %} + + + diff --git a/ci/workflow_templates/ci_README.j2.md b/ci/workflow_templates/ci_README.j2.md new file mode 100644 index 0000000..a41ca96 --- /dev/null +++ b/ci/workflow_templates/ci_README.j2.md @@ -0,0 +1,7 @@ +## Verificarlo CI : `{{dev_branch}}` + +You are on the `{{ci_branch}}` branch, which is automatically updated with the +[Verificarlo](https://github.com/verificarlo/verificarlo) test results from +`{{dev_branch}}` (in the `vfcruns` directory). + +You can start a Verificarlo CI server at anytime using the run files of this branch. diff --git a/ci/workflow_templates/gitlab-ci.j2.yml b/ci/workflow_templates/gitlab-ci.j2.yml new file mode 100644 index 0000000..4a4c83d --- /dev/null +++ b/ci/workflow_templates/gitlab-ci.j2.yml @@ -0,0 +1,42 @@ +# This workflow will be executed when {{dev_branch}} is updated: +# it will run the configured tests and upload the results on vfc_ci_master. + +image: verificarlo/verificarlo + + +stages: + - run_verificarlo_tests + + +run_verificarlo_tests: + stage: run_verificarlo_tests + + before_script: + - git remote set-url origin https://{{username}}:${CI_PUSH_TOKEN}@{{remote_url}}.git + - git config --global user.email "{{email}}" + - git config --global user.name "{{username}}" + + script: + # We will probably drop these installations when integrating CI into + # Verificarlo + - pip install numpy scipy pandas bokeh jinja2 tables GitPython + - apt update + - apt install wget + - wget https://raw.githubusercontent.com/verificarlo/significantdigits/main/sigdigits.py -P /usr/local/lib/python3.8/dist-packages + + - ./vfc_ci test -g -r + - git_hash=$(git rev-parse --short "$CI_COMMIT_SHA") + - git fetch --all + - git checkout -b {{ci_branch}} origin/{{ci_branch}} + - mkdir -p vfcruns + - mv *.vfcrun.hd5 vfcruns + - git add vfcruns/* + - git commit -m "[auto] New test results for commit ${git_hash}" + - git push + + rules: + - if: '$CI_COMMIT_BRANCH == "{{dev_branch}}"' + + artifacts: + paths: + - "*.vfcraw.hd5" diff --git a/ci/workflow_templates/vfc_test_workflow.j2.yml b/ci/workflow_templates/vfc_test_workflow.j2.yml new file mode 100644 index 0000000..f332226 --- /dev/null +++ b/ci/workflow_templates/vfc_test_workflow.j2.yml @@ -0,0 +1,57 @@ +# This workflow will be executed when {{dev_branch}} is updated: +# it will run the configured tests and upload the results on {{ci_branch}}. + +name: "Verificarlo CI ({{dev_branch}})" + +on: + # Triggers the workflow when {{dev_branch}} is updated + push: + branches: [ {{dev_branch}} ] + + workflow_dispatch: + + +jobs: + run_verificarlo_tests: + runs-on: ubuntu-latest + container: verificarlo/verificarlo + + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + + # We will probably drop these installations when integrating CI into + # Verificarlo + - name: Install Python requirements + run: | + pip install numpy scipy pandas bokeh jinja2 tables GitPython + + apt install wget + wget https://raw.githubusercontent.com/verificarlo/significantdigits/main/sigdigits.py -P /usr/local/lib/python3.8/dist-packages + + - name: Run tests + # We assume the script is included in the repo for now + # (we'll probably want to remove "./" if the script ends up being integrated + # in Verificarlo and becomes available system-wide) + run: ./vfc_ci test -g -r + + - name: Commit test results + run: | + git_hash=$(git rev-parse --short "$GITHUB_SHA") + + git config --local user.email "action@github.com" + git config --local user.name "GitHub Action" + + git checkout {{ci_branch}} + mkdir -p vfcruns + mv *.vfcrun.hd5 vfcruns + git add vfcruns/* + git commit -m "[auto] New test results for commit ${git_hash}" + git push + + - name: Upload raw results as artifacts + uses: actions/upload-artifact@v2 + with: + {% raw %}name: ${{github.sha}}.vfcraw{% endraw %} + path: ./*.vfcraw.hd5 diff --git a/include/vfc_hashmap.h b/include/vfc_hashmap.h new file mode 100644 index 0000000..c314f0e --- /dev/null +++ b/include/vfc_hashmap.h @@ -0,0 +1,248 @@ +/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* + * Copyright 2012 Couchbase, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#define HASH_MULTIPLIER 31 +static const unsigned int hashmap_prime_1 = 73; +static const unsigned int hashmap_prime_2 = 5009; + +#ifndef __VFC_HASHMAP_HEADER__ + +struct vfc_hashmap_st { + size_t nbits; + size_t mask; + + size_t capacity; + size_t *items; + size_t nitems; + size_t n_deleted_items; +}; +typedef struct vfc_hashmap_st *vfc_hashmap_t; + +// allocate and initialize the map +vfc_hashmap_t vfc_hashmap_create(); + +// get the value at an index of a map +size_t get_value_at(size_t *items, size_t i); + +// get the key at an index of a map +size_t get_key_at(size_t *items, size_t i); + +// set the value at an index of a map +void set_value_at(size_t *items, size_t value, size_t i); + +// set the key at an index of a map +void set_key_at(size_t *items, size_t key, size_t i); + +// free the map +void vfc_hashmap_destroy(vfc_hashmap_t map); + +// insert an element in the map +void vfc_hashmap_insert(vfc_hashmap_t map, size_t key, void *item); + +// remove an element of the map +void vfc_hashmap_remove(vfc_hashmap_t map, size_t key); + +// test if an element is in the map +char vfc_hashmap_have(vfc_hashmap_t map, size_t key); + +// get an element of the map +void *vfc_hashmap_get(vfc_hashmap_t map, size_t key); + +// get the number of elements in the map +size_t vfc_hashmap_num_items(vfc_hashmap_t map); + +// Hash function +size_t vfc_hashmap_str_function(const char *id); + +#endif + +/***************** Verificarlo hashmap FUNCTIONS ******************** + * The following set of functions are used in backends and wrapper + * to stock and access quickly internal data. + *******************************************************************/ + +// free the map +void vfc_hashmap_destroy(vfc_hashmap_t map) { + if (map) { + free(map->items); + } + free(map); +} + +// allocate and initialize the map +vfc_hashmap_t vfc_hashmap_create() { + vfc_hashmap_t map = (vfc_hashmap_t) calloc(1, sizeof(struct vfc_hashmap_st)); + + if (map == NULL) { + return NULL; + } + map->nbits = 3; + map->capacity = (size_t)(1 << map->nbits); + map->mask = map->capacity - 1; + // an item is now a value and a key + map->items = (size_t *) calloc(map->capacity, 2 * sizeof(size_t)); + if (map->items == NULL) { + vfc_hashmap_destroy(map); + return NULL; + } + map->nitems = 0; + map->n_deleted_items = 0; + return map; +} + +size_t get_value_at(size_t *items, size_t i) { return items[i * 2]; } + +size_t get_key_at(size_t *items, size_t i) { return items[(i * 2) + 1]; } + +void set_value_at(size_t *items, size_t value, size_t i) { + items[i * 2] = value; +} + +void set_key_at(size_t *items, size_t key, size_t i) { + items[(i * 2) + 1] = key; +} + +// add a member in the table +static int hashmap_add_member(vfc_hashmap_t map, size_t key, void *item) { + size_t value = (size_t)item; + size_t ii; + + if (value == 0 || value == 1) { + return -1; + } + + ii = map->mask & (hashmap_prime_1 * key); + + while (get_value_at(map->items, ii) != 0 && + get_value_at(map->items, ii) != 1) { + if (get_value_at(map->items, ii) == value) { + return 0; + } else { + /* search free slot */ + ii = map->mask & (ii + hashmap_prime_2); + } + } + map->nitems++; + if (get_value_at(map->items, ii) == 1) { + map->n_deleted_items--; + } + + set_value_at(map->items, value, ii); + set_key_at(map->items, key, ii); + + return 1; +} + +// rehash the table if necessary +static void maybe_rehash_map(vfc_hashmap_t map) { + size_t *old_items; + size_t old_capacity, ii; + + if (map->nitems + map->n_deleted_items >= (double)map->capacity * 0.85) { + old_items = map->items; + old_capacity = map->capacity; + map->nbits++; + map->capacity = (size_t)(1 << map->nbits); + map->mask = map->capacity - 1; + map->items = (size_t *) calloc(map->capacity, 2 * sizeof(size_t)); + map->nitems = 0; + map->n_deleted_items = 0; + for (ii = 0; ii < old_capacity; ii++) { + hashmap_add_member(map, get_key_at(old_items, ii), + (void *)get_value_at(old_items, ii)); + } + free(old_items); + } +} + +// insert an element in the map +void vfc_hashmap_insert(vfc_hashmap_t map, size_t key, void *item) { + hashmap_add_member(map, key, item); + maybe_rehash_map(map); +} + +// remove an element of the map +void vfc_hashmap_remove(vfc_hashmap_t map, size_t key) { + size_t ii = map->mask & (hashmap_prime_1 * key); + + while (get_value_at(map->items, ii) != 0) { + if (get_key_at(map->items, ii) == key) { + set_value_at(map->items, 1, ii); + map->nitems--; + map->n_deleted_items++; + break; + } else { + ii = map->mask & (ii + hashmap_prime_2); + } + } +} + +// test if an element is in the map +char vfc_hashmap_have(vfc_hashmap_t map, size_t key) { + size_t ii = map->mask & (hashmap_prime_1 * key); + + while (get_value_at(map->items, ii) != 0) { + if (get_key_at(map->items, ii) == key) { + return 1; + } else { + ii = map->mask & (ii + hashmap_prime_2); + } + } + return 0; +} + +// get an element of the map +void *vfc_hashmap_get(vfc_hashmap_t map, size_t key) { + size_t ii = map->mask & (hashmap_prime_1 * key); + + while (get_value_at(map->items, ii) != 0) { + if (get_key_at(map->items, ii) == key) { + return (void *)get_value_at(map->items, ii); + } else { + ii = map->mask & (ii + hashmap_prime_2); + } + } + return NULL; +} + +// get the number of elements in the map +size_t vfc_hashmap_num_items(vfc_hashmap_t map) { return map->nitems; } + +// Hash function for strings +size_t vfc_hashmap_str_function(const char *id) { + unsigned const char *us; + + us = (unsigned const char *)id; + + size_t index = 0; + + while (*us != '\0') { + index = index * HASH_MULTIPLIER + *us; + us++; + } + + return index; +} + +// Free the hashmap +void vfc_hashmap_free(vfc_hashmap_t map) { + for (int ii = 0; ii < map->capacity; ii++) + if (get_value_at(map->items, ii) != 0 && get_value_at(map->items, ii) != 0) + free((void *)get_value_at(map->items, ii)); +} diff --git a/include/vfc_probe.h b/include/vfc_probe.h new file mode 100644 index 0000000..0d716d1 --- /dev/null +++ b/include/vfc_probe.h @@ -0,0 +1,254 @@ +/* +* This file defines "vfc_probes", a hashtable-based structure which can be used +* to place "probes" in a code and store the different values of test variables. +* These test results can then be exported in a CSV file, and used to generate a +* Verificarlo test report. +*/ + + +#include +#include +#include + +#include "vfc_hashmap.h" + +#define VAR_NAME(var) #var // Simply returns the name of var into a string + + +/* +* A probe containing a double value as well as its key, which is needed when +* dumping the probes +*/ + +struct vfc_probe_node { + char * key; + double value; +}; + +typedef struct vfc_probe_node vfc_probe_node; + + + +/* +* The probes structure. It simply acts as a wrapper for a Verificarlo hashmap. +*/ + +struct vfc_probes { + vfc_hashmap_t map; +}; + +typedef struct vfc_probes vfc_probes; + + +/* +* Initialize an empty vfc_probes instance +*/ + +vfc_probes vfc_init_probes() { + vfc_probes probes; + probes.map = vfc_hashmap_create(); + + return probes; +} + + + +/* +* Free all probes +*/ + +void vfc_free_probes(vfc_probes * probes) { + + // Before freeing the map, iterate manually over all items to free the keys + vfc_probe_node * probe = NULL; + for(int i = 0; i < probes->map->capacity; i++) { + probe = (vfc_probe_node*) get_value_at(probes->map->items, i); + if(probe != NULL) { + if(probe->key != NULL) { + free(probe->key); + } + } + } + + vfc_hashmap_free(probes->map); +} + + + +/* +* Helper function to generate the key from test and variable name +*/ + +char * gen_probe_key(char * testName, char * varName) { + char * key = (char *) malloc(strlen(testName) + strlen(varName) + 2); + strcpy(key, testName); + strcat(key, ","); + strcat(key, varName); + + return key; +} + + + +/* +* Helper function to detect forbidden character ',' in the keys +*/ + +void validate_probe_key(char * str) { + unsigned int len = strlen(str); + + for(unsigned int i=0; imap, vfc_hashmap_str_function(key) + ); + + if(oldProbe != NULL) { + if(strcmp(key, oldProbe->key) == 0) { + fprintf( + stderr, + "Error [verificarlo]: you have a duplicate error with one of \ + your probes (\"%s\"). Please make sure to use different names.\n", + key + ); + exit(1); + } + } + + // Insert the element in the hashmap + vfc_probe_node * newProbe = (vfc_probe_node*) malloc(sizeof(vfc_probe_node)); + newProbe->key = key; + newProbe->value = val; + + vfc_hashmap_insert( + probes->map, vfc_hashmap_str_function(key), newProbe + ); + + return 0; +} + + + +/* +* Remove (free) an element from the hash table +*/ + +int vfc_remove_probe(vfc_probes * probes, char * testName, char * varName) { + + if(probes == NULL) { + return 1; + } + + // Get the key, which is : testName + "," + varName + char * key = gen_probe_key(testName, varName); + + vfc_hashmap_remove(probes->map, vfc_hashmap_str_function(key)); + + return 0; +} + + + +/* +* Return the number of probes stored in the hashmap +*/ + +unsigned int vfc_num_probes(vfc_probes * probes) { + return vfc_hashmap_num_items(probes->map); +} + + + +/* +* Dump probes in a .csv file (the double values are converted to hex), then +* free it. +*/ + +int vfc_dump_probes(vfc_probes * probes) { + + if(probes == NULL) { + return 1; + } + + // Get export path from the VFC_PROBES_OUTPUT env variable + char* exportPath = getenv("VFC_PROBES_OUTPUT"); + if(!exportPath) { + printf( + "Warning [verificarlo]: VFC_PROBES_OUTPUT is not set, probes will \ + not be dumped\n" + ); + vfc_free_probes(probes); + return 0; + } + + FILE * fp = fopen(exportPath, "w"); + + if(fp == NULL) { + fprintf( + stderr, + "Error [verificarlo]: impossible to open the CSV file to save your \ + probes (\"%s\")\n", + exportPath + ); + exit(1); + } + + // First line gives the column names + fprintf(fp, "test,variable,value\n"); + + // Iterate over all table elements + vfc_probe_node * probe = NULL; + for(int i = 0; i < probes->map->capacity; i++) { + probe = (vfc_probe_node*) get_value_at(probes->map->items, i); + if(probe != NULL) { + fprintf( + fp, "%s,%a\n", + probe->key, + probe->value + ); + } + } + + fclose(fp); + + vfc_free_probes(probes); + + return 0; +} diff --git a/tests/vfc_test_h5.cpp b/tests/vfc_test_h5.cpp new file mode 100644 index 0000000..18b0435 --- /dev/null +++ b/tests/vfc_test_h5.cpp @@ -0,0 +1,196 @@ +// This files is almost the same as test_h5.cpp, with the difference that it +// dumps Verificarlo probes for vfc_ci integration, and that it reads a list of +// cycles in a CSV file, instead of accepting a start and an end cycle (which +// makes it easier to select the exact cycles we are interested in with vfc_ci). + +#include +#include + +#include +#include +#include + + +#include "SM_MaponiA3.hpp" +#include "SM_Standard.hpp" +#include "SM_Helpers.hpp" +#include "vfc_probe.h" + +using namespace H5; +// #define DEBUG + +const H5std_string FILE_NAME( "datasets/dataset.hdf5" ); + +double residual_max(double * A, unsigned int Dim) { + double max = 0.0; + for (unsigned int i = 0; i < Dim; i++) { + for (unsigned int j = 0; j < Dim; j++) { + double delta = (A[i * Dim + j] - (i == j)); + delta = abs(delta); + if (delta > max) max = delta; + } + } + return max; +} + +double residual2(double * A, unsigned int Dim) { + double res = 0.0; + for (unsigned int i = 0; i < Dim; i++) { + for (unsigned int j = 0; j < Dim; j++) { + double delta = (A[i * Dim + j] - (i == j)); + res += delta*delta; + } + } + return res; +} + +void read_int(H5File file, std::string key, unsigned int * data) { + DataSet ds = file.openDataSet(key); + ds.read(data, PredType::STD_U32LE); + ds.close(); +} + +void read_double(H5File file, std::string key, double * data) { + DataSet ds = file.openDataSet(key); + ds.read(data, PredType::IEEE_F64LE); + ds.close(); +} + + +/* Return a vector containing all cycles to execute by reading a data file */ +std::vector get_cycles_list(std::string path) { + std::ifstream file_stream(path); + std::stringstream string_stream; + string_stream << file_stream.rdbuf(); + + std::string cycle_str; + std::vector cycles_list = {}; + + while(string_stream >> cycle_str) { + cycles_list.push_back(std::stoi(cycle_str)); + } + + return cycles_list; +} + +int test_cycle(H5File file, int cycle, std::string version, vfc_probes * probes) { + + /* Read the data */ + + std::string group = "cycle_" + std::to_string(cycle); + + try{ + file.openGroup(group); + } catch(H5::Exception& e){ + std::cerr << "group " << group << "not found" << std::endl; + return 0; + } + + unsigned int dim, nupdates, col, i, j; + read_int(file, group + "/slater_matrix_dim", &dim); + read_int(file, group + "/nupdates", &nupdates); + + + double * slater_matrix = new double[dim*dim]; + read_double(file, group + "/slater_matrix", slater_matrix); + + double * slater_inverse = new double[dim*dim]; + read_double(file, group + "/slater_inverse", slater_inverse); + //slater_inverse = transpose(slater_inverse, dim); + + unsigned int * col_update_index = new unsigned int[nupdates]; + read_int(file, group + "/col_update_index", col_update_index); + + double * updates = new double[nupdates*dim]; + read_double(file, group + "/updates", updates); + + double * u = new double[nupdates*dim]; + + /* Test */ +#ifdef DEBUG + showMatrix(slater_matrix, dim, "OLD Slater"); +#endif + +#ifdef DEBUG + showMatrix(slater_inverse, dim, "OLD Inverse"); +#endif + + for (j = 0; j < nupdates; j++) { + for (i = 0; i < dim; i++) { + col = col_update_index[j]; + u[i + j*dim] = updates[i + j*dim] - slater_matrix[i*dim + (col - 1)]; + slater_matrix[i*dim + (col - 1)] = updates[i + j*dim]; + } + } + + if (version == "maponia3") { + MaponiA3(slater_inverse, dim, nupdates, u, col_update_index); + } else if (version == "sm1") { + SM1(slater_inverse, dim, nupdates, u, col_update_index); + } else if (version == "sm2") { + SM2(slater_inverse, dim, nupdates, u, col_update_index); + } else if (version == "sm3") { + SM3(slater_inverse, dim, nupdates, u, col_update_index); + } else { + std::cerr << "Unknown version " << version << std::endl; + exit(1); + } + +#ifdef DEBUG + showMatrix(slater_matrix, dim, "NEW Slater"); +#endif + +#ifdef DEBUG + showMatrix(slater_inverse, dim, "NEW Inverse"); +#endif + + double * res = new double[dim*dim] {0}; + matMul(slater_matrix, slater_inverse, res, dim); + bool ok = is_identity(res, dim, 1e-3); + + double res_max = residual_max(res, dim); + double res2 = residual2(res, dim); + +#ifdef DEBUG + showMatrix(res, dim, "Result"); +#endif + + vfc_put_probe(probes, &(group)[0], &("res_max_" + version)[0], res_max); + vfc_put_probe(probes, &(group)[0], &("res2_" + version)[0], res2); + + delete [] res, updates, u, col_update_index, + slater_matrix, slater_inverse; + + return ok; +} + +int main(int argc, char **argv) { + if (argc != 3) { + std::cerr << "Execute from within '/'" << std::endl; + std::cerr << "usage: test_h5 " << std::endl; + return 1; + } + std::string version(argv[1]); + std::vector cycles_list = get_cycles_list(argv[2]); + H5File file(FILE_NAME, H5F_ACC_RDONLY); + + vfc_probes probes = vfc_init_probes(); + probes = vfc_init_probes(); + + bool ok; + for (int i = 0; i < cycles_list.size(); i++) { + ok = test_cycle(file, cycles_list[i], version, &probes); + if (ok) { + std::cout << "ok -- cycle " << std::to_string(i) + << std::endl; + } + else { + std::cerr << "failed -- cycle " << std::to_string(i) + << std::endl; + } + } + + vfc_dump_probes(&probes); + + return ok; +} diff --git a/vfc_ci b/vfc_ci new file mode 100755 index 0000000..c695834 --- /dev/null +++ b/vfc_ci @@ -0,0 +1,205 @@ +#!/usr/bin/env python3 + +# This is the entry point of the Verificarlo CI command line interface, which is +# based on argparse and this article : +# https://mike.depalatis.net/blog/simplifying-argparse.html +# From here, 3 subcommands can be called : +# - setup : create a vfc_ci branch and workflow on the current Git repo +# - test : run and export test results according to the vfc_tests_config.json +# - serve : launch a Bokeh server to visualize run results + +import argparse + +################################################################################ + + # Parameters validation helpers + +def is_port(string): + value = int(string) + if value < 0 or value > 65535: + raise argparse.ArgumentTypeError("Value has to be between 0 and 65535") + return value + + +def is_directory(string): + import os + + isdir = os.path.isdir(string) + if not isdir: + raise argparse.ArgumentTypeError("Directory does not exist") + + return string + + +################################################################################ + + + # Subcommand decorator + +cli = argparse.ArgumentParser( + description="Define, run, automatize, and visualize custom Verificarlo tests." +) +subparsers = cli.add_subparsers(dest="subcommand") + +def subcommand(description="", args=[], parent=subparsers): + def decorator(func): + parser = parent.add_parser(func.__name__, description=description) + for arg in args: + parser.add_argument(*arg[0], **arg[1]) + parser.set_defaults(func=func) + return decorator + + +def argument(*name_or_flags, **kwargs): + return ([*name_or_flags], kwargs) + + + +################################################################################ + + + # "setup" subcommand + +@subcommand( + description="Create an automated workflow to execute Verificarlo tests.", + args = [ + argument( + "git_host", + help=""" + specify where your repository is hosted + """, + choices=["github", "gitlab"] + ) + ] +) +def setup(args): + import ci.setup + ci.setup.setup(args.git_host) + + + + # "test" subcommand + +@subcommand( + description="Execute predefined Verificarlo tests and save their results.", + args = [ + argument( + "-g", "--is-git-commit", + help=""" + When specified, the last Git commit of the local repository (working + directory) will be fetched and associated with the run. + """, + action="store_true" + ), + argument( + "-r", "--export-raw-results", + help=""" + Specify if an additional HDF5 file containing the raw results must be + exported. + """, + action="store_true" + ), + argument( + "-d", "--dry-run", + help=""" + Perform a dry run by not saving the test results. + """, + action="store_true" + ) + ] +) +def test(args): + import ci.test + ci.test.run(args.is_git_commit, args.export_raw_results, args.dry_run) + + + + # "serve" subcommand + +@subcommand( + description=""" + Start a server to visualize Verificarlo test results. + """, + args = [ + argument( + "-s", "--show", + help=""" + Specify if the report must be opened in the browser at server + startup. + """, + action="store_true" + ), + argument( + "-gd", "--git-directory", + help=""" + Path to a local Git repository. The report will be linked to the + remote URL (GitHub and GitLab are supported). + """, + type=is_directory + ), + argument( + "-gu", "--git-url", + help=""" + GitHub or GitLab repository URL. The report will be linked to this + URL. + """, + type=str + ), + argument( + "-p", "--port", + help=""" + The port on which the server will run. Defaults to 8080. + """, + type=is_port, + default=8080 + ), + argument( + "-a", "--allow-origin", + help=""" + The origin (URL) from which the report will be accessible. + Port number must not be specified. Defaults to * (allow everything). + """, + type=str, + default="*" + ), + argument( + "-l", "--logo", + help=""" + Specify the URL of an image to be displayed in the report header. + """, + type=str + ) + ] +) +def serve(args): + + # git_directory and git_url are supposed to be exclusive + if args.git_directory != None and args.git_url != None: + raise argparse.ArgumentTypeError( + "\"-gd\" / \"--git-directory\" and \"-gu\" / \"--git-url\" are "\ + "mutually exclusive. Please make sure to use at most one of them." + ) + + import ci.serve + ci.serve.serve( + args.show, + args.git_directory, + args.git_url, + args.port, + args.allow_origin, + args.logo + ) + + + +############################################################################### + + + # Main command group and entry point + +if __name__ == "__main__": + args = cli.parse_args() + if args.subcommand is None: + cli.print_help() + else: + args.func(args) diff --git a/vfc_ci_cycles.txt b/vfc_ci_cycles.txt new file mode 100644 index 0000000..840505a --- /dev/null +++ b/vfc_ci_cycles.txt @@ -0,0 +1,2 @@ +1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 +327 655 983 1311 1639 1967 2295 2623 2951 3279 3607 3935 4263 4591 4919 5247 5575 5903 6231 6559 6887 7215 7543 7871 8199 diff --git a/vfc_tests_config.json b/vfc_tests_config.json new file mode 100644 index 0000000..abae182 --- /dev/null +++ b/vfc_tests_config.json @@ -0,0 +1,92 @@ +{ + "make_command": "make -f Makefile.vfc_ci", + "executables": [ + { + "executable": "bin/vfc_test_h5", + "parameters" : "maponia3 vfc_ci_cycles.txt", + "vfc_backends": [ + { + "name": "libinterflop_mca.so", + "repetitions": 50 + } + ] + }, + + { + "executable": "bin/vfc_test_h5", + "parameters" : "sm1 vfc_ci_cycles.txt", + "vfc_backends": [ + { + "name": "libinterflop_mca.so", + "repetitions": 50 + } + ] + }, + + { + "executable": "bin/vfc_test_h5", + "parameters" : "sm2 vfc_ci_cycles.txt", + "vfc_backends": [ + { + "name": "libinterflop_mca.so", + "repetitions": 50 + } + ] + }, + + { + "executable": "bin/vfc_test_h5", + "parameters" : "sm3 vfc_ci_cycles.txt", + "vfc_backends": [ + { + "name": "libinterflop_mca.so", + "repetitions": 50 + } + ] + }, + + { + "executable": "bin/vfc_test_h5", + "parameters" : "maponia3 vfc_ci_cycles.txt", + "vfc_backends": [ + { + "name": "libinterflop_mca.so --mode=rr", + "repetitions": 50 + } + ] + }, + + { + "executable": "bin/vfc_test_h5", + "parameters" : "sm1 vfc_ci_cycles.txt", + "vfc_backends": [ + { + "name": "libinterflop_mca.so --mode=rr", + "repetitions": 50 + } + ] + }, + + { + "executable": "bin/vfc_test_h5", + "parameters" : "sm2 vfc_ci_cycles.txt", + "vfc_backends": [ + { + "name": "libinterflop_mca.so --mode=rr", + "repetitions": 50 + } + ] + }, + + { + "executable": "bin/vfc_test_h5", + "parameters" : "sm3 vfc_ci_cycles.txt", + "vfc_backends": [ + { + "name": "libinterflop_mca.so --mode=rr", + "repetitions": 50 + } + ] + } + ] +} From 18d1e2b785fb83c5023cdfb0ad3c8197221172df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Delval?= Date: Fri, 30 Apr 2021 11:22:22 +0200 Subject: [PATCH 2/7] Move Makefile.vfc_ci to Makefile.verificarlo With the current setup, the CI should be able to be deployed correcly. However, we still ned to find the best solution to pull the dataset on the runner so the tests can be executed on it. --- .gitignore | 2 ++ Makefile.verificarlo | 6 ++-- Makefile.vfc_ci | 64 ------------------------------------------- tests/vfc_test_h5.cpp | 2 +- 4 files changed, 7 insertions(+), 67 deletions(-) delete mode 100644 Makefile.vfc_ci diff --git a/.gitignore b/.gitignore index a295ba0..88d4332 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,5 @@ datasets/dataset.* bin/ *.vfcrun.hd5 *.vfcraw.hd5 +__pycache__ +ci/__pycache__ diff --git a/Makefile.verificarlo b/Makefile.verificarlo index 167b4b2..bd10702 100644 --- a/Makefile.verificarlo +++ b/Makefile.verificarlo @@ -33,6 +33,7 @@ BIN_DIR := bin EXEC := $(BIN_DIR)/cMaponiA3_test_3x3_3 \ $(BIN_DIR)/test_h5 \ + $(BIN_DIR)/vfc_test_h5 \ $(BIN_DIR)/fMaponiA3_test_3x3_3 \ $(BIN_DIR)/fMaponiA3_test_4x4_2 \ $(BIN_DIR)/QMCChem_dataset_test @@ -84,6 +85,9 @@ $(BIN_DIR)/cMaponiA3_test_3x3_3: $(OBJ_DIR)/cMaponiA3_test_3x3_3.o $(DEPS_CXX) | $(BIN_DIR)/test_h5: $(OBJ_DIR)/test_h5.o $(DEPS_CXX) | $(BIN_DIR) $(CXX) -o $@ $^ $(H5FLAGS) +$(BIN_DIR)/vfc_test_h5: $(OBJ_DIR)/vfc_test_h5.o $(DEPS_CXX) | $(BIN_DIR) + $(CXX) -o $@ $^ $(H5FLAGS) + $(BIN_DIR)/fMaponiA3_test_3x3_3: $(DEPS_F) $(OBJ_DIR)/fMaponiA3_test_3x3_3.o | $(BIN_DIR) $(FC) $(FLIBS) -o $@ $^ @@ -92,5 +96,3 @@ $(BIN_DIR)/fMaponiA3_test_4x4_2: $(DEPS_F) $(OBJ_DIR)/fMaponiA3_test_4x4_2.o | $(BIN_DIR)/QMCChem_dataset_test: $(DEPS_F) $(OBJ_DIR)/QMCChem_dataset_test.o | $(BIN_DIR) $(FC) $(FLIBS) -o $@ $^ - - diff --git a/Makefile.vfc_ci b/Makefile.vfc_ci deleted file mode 100644 index 8064b40..0000000 --- a/Makefile.vfc_ci +++ /dev/null @@ -1,64 +0,0 @@ -## Compiler -CXX = verificarlo-c++ - -## Compiler flags -H5FLAGS = -I/usr/include/hdf5/serial -lhdf5_serial -lhdf5_cpp -# H5FLAGS = -lhdf5 -lhdf5_cpp -CXXFLAGS = -O0 -g $(H5FLAGS) - -INCLUDE = -I $(INC_DIR)/ -I="/usr/include" -DEPS_CXX = $(OBJ_DIR)/SM_MaponiA3.o $(OBJ_DIR)/SM_MaponiA3S.o $(OBJ_DIR)/SM_Standard.o $(OBJ_DIR)/SM_Helpers.o - -SRC_DIR := src -TST_DIR := tests -INC_DIR := include -OBJ_DIR := build -BIN_DIR := bin - -EXEC := $(BIN_DIR)/vfc_test_h5 - -## Build tagets -.PHONY: all clean distclean - -all: $(EXEC) - -clean: - @rm -vrf $(OBJ_DIR) - @rm -vrf $(BIN_DIR) - -distclean: clean - @rm -vrf $(BIN_DIR) \ - Slater* Updates.dat - - -#### COMPILING -$(BIN_DIR) $(OBJ_DIR): - mkdir -p $@ - -### IMPLICIT BUILD RULES -## C++ objects -$(OBJ_DIR)/%.o: $(TST_DIR)/%.cpp $(INC_DIR)/* | $(OBJ_DIR) - $(CXX) $(CXXFLAGS) $(INCLUDE) -c -o $@ $< - -$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp $(INC_DIR)/* | $(OBJ_DIR) - $(CXX) $(CXXFLAGS) -fPIE $(INCLUDE) -c -o $@ $< - -## HDF5/C++ objects -$(OBJ_DIR)/%_h5.o: $(TST_DIR)/%_h5.cpp $(INC_DIR)/* | $(OBJ_DIR) - $(CXX) $(H5CXXFLAGS) $(INCLUDE) -c -o $@ $< - -### EXPLICIT BUILD RULES -## special compiler flag -fPIC otherwise h5c++ builds fail -$(OBJ_DIR)/SM_MaponiA3.o: $(SRC_DIR)/SM_MaponiA3.cpp $(INC_DIR)/* | $(OBJ_DIR) - $(CXX) $(CXXFLAGS) -fPIC $(INCLUDE) -c -o $@ $< - -$(OBJ_DIR)/SM_MaponiA3S.o: $(SRC_DIR)/SM_MaponiA3S.cpp $(INC_DIR)/* | $(OBJ_DIR) - $(CXX) $(CXXFLAGS) -fPIC $(INCLUDE) -c -o $@ $< - -$(OBJ_DIR)/SM_Standard.o: $(SRC_DIR)/SM_Standard.cpp $(INC_DIR)/* | $(OBJ_DIR) - $(CXX) $(CXXFLAGS) -fPIC $(INCLUDE) -c -o $@ $< - - -#### LINKING -$(BIN_DIR)/vfc_test_h5: $(OBJ_DIR)/vfc_test_h5.o $(DEPS_CXX) | $(BIN_DIR) - $(CXX) $(CXXFLAGS) $(INCLUDE) -o $@ $^ $(H5FLAGS) diff --git a/tests/vfc_test_h5.cpp b/tests/vfc_test_h5.cpp index 18b0435..2273773 100644 --- a/tests/vfc_test_h5.cpp +++ b/tests/vfc_test_h5.cpp @@ -167,7 +167,7 @@ int test_cycle(H5File file, int cycle, std::string version, vfc_probes * probes) int main(int argc, char **argv) { if (argc != 3) { std::cerr << "Execute from within '/'" << std::endl; - std::cerr << "usage: test_h5 " << std::endl; + std::cerr << "usage: test_h5 " << std::endl; return 1; } std::string version(argv[1]); From d81777e347329726e145fcdd6768b6e787c6e72f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Delval?= Date: Mon, 3 May 2021 13:59:43 +0200 Subject: [PATCH 3/7] Add CI dataset and the tool to generate it. Since the dataset must be accessible from the CI runner, the best solution is probably to commit a small dataset containing only the required cycles. It's included in this commit, and can be generated by extract-from-h5.py using the same cycles list as the one used by vfc_test_h5.cpp. Moreover, the probes exported by vfc_test_h5.cpp are now 0-padded, which will result in a better sorting in the results. --- datasets/ci_dataset.hdf5 | Bin 0 -> 840847 bytes tests/vfc_test_h5.cpp | 12 +++++-- tools/extract-from-h5.py | 72 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 3 deletions(-) create mode 100644 datasets/ci_dataset.hdf5 create mode 100644 tools/extract-from-h5.py diff --git a/datasets/ci_dataset.hdf5 b/datasets/ci_dataset.hdf5 new file mode 100644 index 0000000000000000000000000000000000000000..c7c91c24b07cb9db23c81a6e611a19bbd61f6073 GIT binary patch literal 840847 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

uYsCA{7pHl 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 M` \n" + ) + exit(1) + +source_dataset_path = sys.argv[1] +cycles_list_path = sys.argv[2] +destination_dataset_path = sys.argv[3] + + + # Read the cycles list + +cycles_list = [] + +try: + f = open(cycles_list_path) + for line in f: + cycles_list.extend([cycle for cycle in line.split()]) +except IOError: + sys.stderr.write("Error: Could not read " + cycles_list_path + "\n") + exit(1) +finally: + f.close() + + + # Read the source dataset, and extract the cycles to the destination dataset + +try: + fs = h5py.File(source_dataset_path, "r") + +except IOError: + sys.stderr.write("Error: Could not read " + source_dataset_path + "\n") + exit(1) + +fd = h5py.File(destination_dataset_path, "w") + +# Copy cycles groups + +groups = [ + "slater_matrix_dim", + "nupdates", + "slater_matrix", + "slater_inverse", + "col_update_index", + "updates" +] + +for cycle in cycles_list: + cycle_name = "cycle_" + cycle + + new_cycle = fd.create_group(cycle_name) + + # Copy all datasets + for group_name in groups: + fs.copy(cycle_name + "/" + group_name, new_cycle) + + +print("Dataset successfully exported to %s" % source_dataset_path) From 44f0fc1f51b97a44902f46244be655c7955eb9bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Delval?= Date: Mon, 3 May 2021 15:47:44 +0200 Subject: [PATCH 4/7] Update vfc_ci code --- ci/__pycache__/__init__.cpython-39.pyc | Bin 154 -> 154 bytes ci/__pycache__/serve.cpython-39.pyc | Bin 656 -> 656 bytes ci/__pycache__/setup.cpython-39.pyc | Bin 3296 -> 3309 bytes ci/__pycache__/test.cpython-39.pyc | Bin 7108 -> 7071 bytes ci/serve.py | 10 +- ci/setup.py | 67 +++--- ci/test.py | 178 +++++++------- .../__pycache__/compare_runs.cpython-39.pyc | Bin 9285 -> 9336 bytes .../__pycache__/helper.cpython-39.pyc | Bin 2839 -> 2844 bytes .../__pycache__/inspect_runs.cpython-39.pyc | Bin 10125 -> 10165 bytes .../__pycache__/plot.cpython-39.pyc | Bin 2455 -> 2448 bytes ci/vfc_ci_report/compare_runs.py | 220 ++++++++---------- ci/vfc_ci_report/helper.py | 24 +- ci/vfc_ci_report/inspect_runs.py | 208 ++++++++--------- ci/vfc_ci_report/main.py | 75 +++--- ci/vfc_ci_report/plot.py | 43 ++-- ci/vfc_ci_report/templates/index.html | 8 +- ci/workflow_templates/gitlab-ci.j2.yml | 4 +- .../vfc_test_workflow.j2.yml | 6 +- vfc_ci | 32 ++- 20 files changed, 398 insertions(+), 477 deletions(-) diff --git a/ci/__pycache__/__init__.cpython-39.pyc b/ci/__pycache__/__init__.cpython-39.pyc index 0135b7144a5614d2edd969d33d163e71293481c8..18acc29125bbcc374f0eacb0949d9c8f051260e3 100644 GIT binary patch delta 19 ZcmbQmIE#@xk(ZZ?0SF#_>z~No4*)DN1z7+9 delta 19 ZcmbQmIE#@xk(ZZ?0SGQ9cTVK)2LLGG1hD`B diff --git a/ci/__pycache__/serve.cpython-39.pyc b/ci/__pycache__/serve.cpython-39.pyc index b39aba02ae1a52a39f4b57bb54ccd28adafb97bf..aac8c1020fe7d167601c159ddf3b67dadd1ff46b 100644 GIT binary patch delta 103 zcmbQhI)Rlhk(ZZ?0SILO_9rkiPvpx}D`hNFNMWvF6l17mt6@rE0P+n|SZbI+{1m2I o_8L}@*v3WujPmS2jm0t`?aVw(EQ}lw2w^etFi#F(vS(xl06IVsWdHyG delta 103 zcmbQhI)Rlhk(ZZ?0SFi?x)MG!P2|f{%VsW8NMWvF6l17mt6@rE0P+n|SZbI+{1m2I o_8L}@*v3WujPh(ijm0t`?aVw(EQ}lw2w^etuuKkMvS(xh07|(Ll>h($ diff --git a/ci/__pycache__/setup.cpython-39.pyc b/ci/__pycache__/setup.cpython-39.pyc index a6aeba4f88a4a1f4ee501b7334633af89fe7d7f4..f6d3998e0829c5fbd8d9ab5e1374024bdcdfff3b 100644 GIT binary patch delta 125 zcmaDL`BsuQk(ZZ?0SGE{yArN#;J zICt}6mR~H4vnS8v)D%|&sVPYe+%Q%1AR z>sWrVFwUI3l2cQ(EG;>{B(=DtI6gT)FD)}&FRM5|Z}Lk{4PJGSRC1;QNLGEb92XxG Mqwi#0p8bsa0OGGB<^TWy diff --git a/ci/__pycache__/test.cpython-39.pyc b/ci/__pycache__/test.cpython-39.pyc index fa73d452612722f74b4fa60f0eb72f15333d46a3..f7a0037aff6919223e9dc5a48e1291c8412e966e 100644 GIT binary patch delta 1431 zcmZ8hO>7%Q6!z?{*Xwos)7XUAX&|Yaq?@Lp39U+1leDx|Lm(k>C`Ajx*?2ehrvA&D zb^eqR!HG)+(j2%TLB$Dip;+Psf&;gL#0jJoYLBQ0ap(aF2?X!0iv-MSzMYx(&3p5{ zx3gcLdH+n@ipTX3wmT2rUM=2^w`6usye^NcTkGXg+3kEGTP&fVUB!M8I|nfl9z56& zZOEQ-Jp?a$;SW@tMJntTyCHenMs%O;(_7z&A@*#iN!AY+*O48f56XbYUO%iU(fSL=>fZQ4MVf^i7wM1BMuUbR{dWND_h zwyav)@%6gfC_NlYjg}v_0IXeKs<(ZK+hRc-J}5dh%X7CJUtI{?nvp9`!vU*iDz#>1 z+SIHy-mJAf#}9M2Qnx-*Ab}yw9^2&}xNB_>&jjNXm2pVoy9+5AO&~mvo%bVz6rH7H zT}ns_lkicQ`iGj=G$o*wDV={B39VrdgkBR$WVv7~cKD_m$fuHgfk=_ANN@zXm2bbH z_RDN#J!rqq8Vcmm07u2W@X_Z+X*h;}sZR%@!3ZspU~r7UAfQa(H~}3VP7q8IJb_@! z7Z>MXO8gL+Rx3E?hecBBk4l)%@2U=`Iulx*W#1wTi4?*td)T;?V5*dpV5akFG|z_5 zqv3u80iHqFi;VE0!U&%MO4esOToS+OC)s5&78@O>H8bqgEw=`j$R6gcn(G;1xIi-v zKLyLSJPR(1?buW7UGYim1Y7Fdjin_vD;~t(V9UZw++_=5CApL>khe&qwC>g%4v*ms zmI;dD^W>4}Rr1JOI46EePO;BKHg%1yb~aPDnc9^{9P2fhDvG@mYM|0dv6;$4LUhKHE|RU#;(!Jr`C%jB6NzRDP^+W9$C zVyM7;-}tL9A<2-t)qaFFn6w~uRVdNIf4^Nn&a2Js(zXQ+w^89^m=~wKLRe8O_g{+I z%X*{?%P?>|-}T*LXU~(9prraF{x!hbo~)h*(%fLaeBIfF7l=XEb+5~4H;}P6FTU@e zQ%+CrT^0H4irCJ+GBrcQC4yA~m!OJZM!Dma+=lJ!m^yF5!!axfIhSV_#8_@9_8O6c zNCi>Mjk2f3Zf=Un;^W-lqjj_yS$LT!X9=Dqm>2hQ(+7d0J23*NZRsaA1 delta 1424 zcmZuwO>7%g5cb=D+p(S6sbz;IAxRThlcY`Bs1-B~rKChHiJAo3;vU?McjK&Muibg; zkVFm?plW&J3pD_j*Sx}74K`XI$`-rxTZ}bD zpW3(Q%kL@8P+2Xp_t~z5C(YM4La^)`<#0K&E8~B($(j=Wca>vJ*_LlByNWjy*yI0W zS8T;rZ)>|sQ?a#dXeDIoiy&il4;jJ-QafA+r|5FG=C!q|xTmVg(!d)(E#2?`an@Ae zC_2H2nA49AYItnx;P7>;?m(6#$*Z?j3&7fLOVx(>PEDt{-PRTyf4yes^%oq^0jnZ@ zRR{OZt@2u>;X7^l{NlW+LY(5eY?u4st~PwU9?ak_(lZVT5(4O^(*(kc_~SW*kP>0t za$JrugDFhHug0WDM&uuogxcS=Xb@M#PKBnXSzg@NmiBO9G7e4&hM{(b0YjJ-h6!ja zW&-FQcnYB{@hPC*VU&RSh9?M~BnWCAqZ3sK#|VxSj1x>E;1H=-m?A)TIRq!f&2&n9 zsSjv?N}drv>lyWtro(hAW>i`BZPHRu2wUr7IVsLGsaJy8mIx2C!E}E@x*bn~sa?RvZrfD8Vwpig+h66uv?k znG0vcSBXjXnfN1dm09AKWTsW_zRR@E&_pr9E;NI@+x;rRZDz(s8`%dPO_YM zH+7^hg(N_dG6yseIVQ_1)|SiRBxXF##>8mKWEpWeHLn%P(V;+gM0}dMb(U_*>((YN zU&+bK+_yXIOq1g^f;I9mZZ<5>$5vpSbi}O5U?w2vt)6byCH8wv=C;1>DKH#^na=fJ zB_Fx71cxc;Iw_>iC~jcnVBayUom1^0qz2KIGL|})z=)~q) z5v*4y*6nGa>6)x9Z#dg_WI;3IWG}d z1Z4sjAs^ 0: print( - "Warning [vfc_ci]: Some of your runs could not generate any data " \ + "Warning [vfc_ci]: Some of your runs could not generate any data " "(for instance because your code crashed) and resulted in " "warnings. Here is the complete list :" ) @@ -316,9 +301,7 @@ def show_warnings(warnings): print(" Repetition: %s" % warnings[i]["repetition"]) - -################################################################################ - +########################################################################## # Entry point @@ -334,54 +317,51 @@ def run(is_git_commit, export_raw_values, dry_run): data, warnings = run_tests(config) show_warnings(warnings) - # Data processing print("Info [vfc_ci]: Processing data...") data_processing(data) - - # Prepare data for export (by creating a proper index and linking run timestamp) + # Prepare data for export (by creating a proper index and linking run + # timestamp) data = data.set_index(["test", "variable", "vfc_backend"]).sort_index() data["timestamp"] = metadata["timestamp"] - filename = metadata["hash"] if is_git_commit else str(metadata["timestamp"]) - + filename = metadata["hash"] if is_git_commit else str( + metadata["timestamp"]) # Prepare metadata for export metadata = pd.DataFrame.from_dict([metadata]) metadata = metadata.set_index("timestamp") - # NOTE : Exporting to HDF5 requires to install "tables" on the system # Export raw data if needed if export_raw_values and not dry_run: - data.to_hdf(filename + ".vfcraw.hd5", key="data") - metadata.to_hdf(filename + ".vfcraw.hd5", key="metadata") + data.to_hdf(filename + ".vfcraw.h5", key="data") + metadata.to_hdf(filename + ".vfcraw.h5", key="metadata") # Export data del data["values"] if not dry_run: - data.to_hdf(filename + ".vfcrun.hd5", key="data") - metadata.to_hdf(filename + ".vfcrun.hd5", key="metadata") - + data.to_hdf(filename + ".vfcrun.h5", key="data") + metadata.to_hdf(filename + ".vfcrun.h5", key="metadata") # Print termination messages print( - "Info [vfc_ci]: The results have been successfully written to " \ - "%s.vfcrun.hd5." \ - % filename - ) + "Info [vfc_ci]: The results have been successfully written to " + "%s.vfcrun.h5." + % filename + ) if export_raw_values: print( - "Info [vfc_ci]: A file containing the raw values has also been " \ - "created : %s.vfcraw.hd5." + "Info [vfc_ci]: A file containing the raw values has also been " + "created : %s.vfcraw.h5." % filename ) if dry_run: print( - "Info [vfc_ci]: The dry run flag was enabled, so no files were " \ + "Info [vfc_ci]: The dry run flag was enabled, so no files were " "actually created." ) diff --git a/ci/vfc_ci_report/__pycache__/compare_runs.cpython-39.pyc b/ci/vfc_ci_report/__pycache__/compare_runs.cpython-39.pyc index 0be4ed463e7dfb486022766db9121075b31904b2..faade86f027048e2829586b4a93c46dbfb88db59 100644 GIT binary patch delta 684 zcmZ`$&ubGw6yEpd?PQp2HX%)7s%D$CUSbP^2wr*+Y9Ss(JSvEW#7J7`A&H(MLJNZ6 z5AcCM@TSFcWxaUtAmTv~Jo^t=K@Xlvpt|eKZdE)u55Dr_=lxCD8I`okI203NA#bWC;Hg_E%W-w8H*8Y;NZ{*$6^Dzuu6kEx3V=j z$-V4pc)%~SXSD7Q`)k8dd#%G6Z?o~-c5g#*GFo_`k+6Usknl~vKKg<`c*l7mtAfP4 zI2K))cCL%D7&|N2#c5|ntct-=p3k-65#PzZEx)&x)zs1in%ePYe+b+B$$t&s!iV`2 zDnGHZ`&NeJlHkw#njpAPJz#L5S_8BgUa1D|%sLq9x|O=hwk1jl1{R4lZ`NiP_1<5a zv?3DtgCfcl2~El>GATnT;aBx&f6@P1RO&Dp0QBuDao5RZkU^NXq4_b00ze0t~o*ApigX delta 613 zcmY+AL1+^}6o&WByq%1j*-hMT!WO$pnucOZi#=4l3WDZRg?bcfBdKVDP2Gfo5b@Ac zun6{D#AEf~O=Nr3gQ6Fu9zE*Clf8)`78_@_h&Vqy-kW*<_lEbg@wVYLUDvVnnXBDj z*=xM;atJF_!kNP58>{iH=Gxq1H;!-ix@%XjcjFFS#8amu-QJruCXT@V=|DIF0+8He zAp~4Pjpuc3ROHEPtaDgS_A@(d>VhF$GXxZ%AQ-U`+7f)*(QbzeC?Y*~3a+LU!PEW; z?%VX)iH;Q%mcWRj>;lcYGT4MZbXYvyX9K4!RVa#vsUEdxkl!GO15+`7vLd|k4PX{o+&`2Ew2Y(w{tJyTk3vk4_YC1sqHm|%LxnyBX|9g) z|0|p7r4f9mdie=MMtkK4EW>EIvc()m`;{TM$;RY47#m}MH^l@KpoR3In$(N>Grfuq eG9zc?6; z*^hBOGb797e=O$QEL@B{EIdp+i~=l^9atL~^EV%2)n{ZZ-TaA7l##K0G6zQ=lN2KyG8NfPF5pULw3~c|%bM4njggI+gN;Loho6H5 E0Af8P`~Uy| diff --git a/ci/vfc_ci_report/__pycache__/inspect_runs.cpython-39.pyc b/ci/vfc_ci_report/__pycache__/inspect_runs.cpython-39.pyc index 4c7717c0c780adbd0504d5ea6f7de8a68e003505..1f6f2f40b72ca83d6743ada64fa8be32d39735b3 100644 GIT binary patch delta 645 zcmaJ;F>4e-6wdeN?d-dCcR4rb-E!p4kn=)3A=oGuf&?oI4H3JDMgoB#7|B79R2o52 zC<@aALC``Dv5JF*MYIsHva#_81nXcCRN~z^a}Y3%^Wb~TH}k&ty_rYTZ>N(RNfHgY zRqsBYTiZ;Q2{Yy{we-ru{Pp=o^MOvGYIo@)(6aBi2AsCvf?eRE{Stn{)OlChKH~)x zgZo4px*LUMib$aQ5(pKkL^=E}9dP@Y!?9$y3ZK=Xdrn|^(!pxW{K$vRP8OI>GK)3S zNoR21qq&k^#=8BTR+S1DmP{oZo4x5O+Rq&fQG}?^D%#J?u44@9ai0U)8FN`VvUi+Pz%7Pt%_tGTylcd|`j+rB7m;jn`9Q1>2G ziWD)~rSc_U%)GBW!&!4RU&oaFo|l3X7yQkQfm>$L&KXBwkoSEsYjd(*Ij0Cd1pFt~ zejXX@X;16yKWDyzdYbKA{WaG*zUc$sG>n3QU{?yM`xK#^%tWJhJoaqbi#c;P2;Ae) z4MLvf1FX5#s39;98yl$D=CP+39w8?_I+)14tbbo+zBb=9k2tD5;=uiXQDRACLhi_@ S9F?kLM6Stg3CyeUZRo!qA9aKP delta 556 zcmXX?ziSjh81>D3JNwWjV8(Bj-i@5y3(bEJd&|Mq?>rQbhcjgFRFbA}J&) zYBd%?uoeW3-e{?fiWX`77Ze0*vCt%UnK?6$nfd0MkM|z$-Sp$>XfBF^9d>n^4`=f? zQ7JI1m&Cr|vzO+}>vIc}Q?0VR+-@ygxY#PM>eu2hcA1~zBXGdHpd2`2zIuOvljei} z8T*f0ruMkwlXa@fKrmE~6^j9piVUNDWXQnMe5!nr`dnPmPof*Rt6#-u^vie#%dWzM z&d!=7Zrz;Mc`|M3BaUK@FaWBN*VA1BQ3 zEcJ>RH+iS;i9A+TpR6b6%WZwA$TAXeV9-XW2#I@bDlgIZirhRZo>RW+NR}OmA9(%g zO%7rk7mG~l(~W#6a^1KaQX&IeQI}XRHHOD{I{+K8=!H^98-!I!5ZK5`>9>s)Oqi+N zPcbwptVq4@)CSdf-J)hY0iWkv?CWn6Kj3cx9SCa< diff --git a/ci/vfc_ci_report/__pycache__/plot.cpython-39.pyc b/ci/vfc_ci_report/__pycache__/plot.cpython-39.pyc index 9e4b5971eaf6cb3b45368078cade265fce44ad32..db14f8d270b175d19cc3e2b3d74073db82349149 100644 GIT binary patch delta 235 zcmbO(JVBT*k(ZZ?0SM&&_9rk2PUPFqRLVH%EDVurXc`>PM<|4HkmKx4@#u|nNOf{Sf85tRB zSW_5)vj59~YBrZME@fhjm@LbpB^sQOT9liZr|X+vRFqkqpBJB&Uz9!Bm&IC{g@aLm zk&A_ek%f_ik%y7xFB=C7BNHRfKQ?w2MiG!K%jDH8#z6BXKVX4d$_}-Z9bxHY0oHpU zTR*T)W|DRXy0 len(timestamps): n = len(timestamps) - for i in range(0, n): # Get metadata associated to this run - row_metadata = helper.get_metadata(self.metadata, timestamps[-i-1]) - date = time.ctime(timestamps[-i-1]) + row_metadata = helper.get_metadata( + self.metadata, timestamps[-i - 1]) + date = time.ctime(timestamps[-i - 1]) # Fill the x series str = row_metadata["name"] - x_series.insert(0, helper.get_metadata(self.metadata, timestamps[-i-1])["name"]) + x_series.insert(0, helper.get_metadata( + self.metadata, timestamps[-i - 1])["name"]) # Fill the metadata lists x_metadata["date"].insert(0, date) - x_metadata["is_git_commit"].insert(0, row_metadata["is_git_commit"]) + x_metadata["is_git_commit"].insert( + 0, row_metadata["is_git_commit"]) x_metadata["hash"].insert(0, row_metadata["hash"]) x_metadata["author"].insert(0, row_metadata["author"]) x_metadata["message"].insert(0, row_metadata["message"]) - return x_series, x_metadata - - # Plots update function def update_plots(self): - # Select all data matching current test/var/backend + # Select all data matching current test/var/backend - runs = self.data.loc[ - [self.widgets["select_test"].value], - self.widgets["select_var"].value, self.widgets["select_backend"].value - ] + runs = self.data.loc[[self.widgets["select_test"].value], + self.widgets["select_var"].value, + self.widgets["select_backend"].value] timestamps = runs["timestamp"] x_series, x_metadata = self.gen_x_series(timestamps.sort_values()) - - # Update source + # Update source main_dict = runs.to_dict("series") main_dict["x"] = x_series @@ -91,8 +87,7 @@ class CompareRuns: # Select the last n runs only n = self.current_n_runs - main_dict = {key:value[-n:] for key, value in main_dict.items()} - + main_dict = {key: value[-n:] for key, value in main_dict.items()} # Generate ColumnDataSources for the 3 dotplots for stat in ["sigma", "s10", "s2"]: @@ -111,18 +106,20 @@ class CompareRuns: } if stat == "s10" or stat == "s2": - dict["%s_lower_bound" % stat] = main_dict["%s_lower_bound" % stat] + dict["%s_lower_bound" % + stat] = main_dict["%s_lower_bound" % + stat] # Filter outliers if the box is checked if len(self.widgets["outliers_filtering_compare"].active) > 0: outliers = helper.detect_outliers(dict[stat]) dict[stat] = helper.remove_outliers(dict[stat], outliers) - dict["%s_x" % stat] = helper.remove_outliers(dict["%s_x" % stat], outliers) + dict["%s_x" % stat] = helper.remove_outliers( + dict["%s_x" % stat], outliers) # Assign ColumnDataSource self.sources["%s_source" % stat].data = dict - # Generate ColumnDataSource for the boxplot dict = { "is_git_commit": main_dict["is_git_commit"], @@ -132,40 +129,48 @@ class CompareRuns: "message": main_dict["message"], "x": main_dict["x"], - "min" : main_dict["min"], - "quantile25" : main_dict["quantile25"], - "quantile50" : main_dict["quantile50"], - "quantile75" : main_dict["quantile75"], - "max" : main_dict["max"], - "mu" : main_dict["mu"], - "pvalue" : main_dict["pvalue"], + "min": main_dict["min"], + "quantile25": main_dict["quantile25"], + "quantile50": main_dict["quantile50"], + "quantile75": main_dict["quantile75"], + "max": main_dict["max"], + "mu": main_dict["mu"], + "pvalue": main_dict["pvalue"], "nsamples": main_dict["nsamples"] } - - self.sources["boxplot_source"].data = dict + # Update x axis - # Update x_ranges - helper.reset_x_range(self.plots["boxplot"], self.sources["boxplot_source"].data["x"]) - helper.reset_x_range(self.plots["sigma_plot"], self.sources["sigma_source"].data["sigma_x"]) - helper.reset_x_range(self.plots["s10_plot"], self.sources["s10_source"].data["s10_x"]) - helper.reset_x_range(self.plots["s2_plot"], self.sources["s2_source"].data["s2_x"]) - - - + helper.reset_x_range( + self.plots["boxplot"], + self.sources["boxplot_source"].data["x"] + ) + helper.reset_x_range( + self.plots["sigma_plot"], + self.sources["sigma_source"].data["sigma_x"] + ) + helper.reset_x_range( + self.plots["s10_plot"], + self.sources["s10_source"].data["s10_x"] + ) + helper.reset_x_range( + self.plots["s2_plot"], + self.sources["s2_source"].data["s2_x"] + ) # Widgets' callback functions def update_test(self, attrname, old, new): # If the value is updated by the CustomJS, self.widgets["select_var"].value - # won't be updated, so we have to look for that case and assign it manually + # won't be updated, so we have to look for that case and assign it + # manually # "new" should be a list when updated by CustomJS - if type(new) == list: + if isinstance(new, list): # If filtering removed all options, we might have an empty list # (in this case, we just skip the callback and do nothing) if len(new) > 0: @@ -180,10 +185,9 @@ class CompareRuns: # New list of available vars self.vars = self.data.loc[new]\ - .index.get_level_values("variable").drop_duplicates().tolist() + .index.get_level_values("variable").drop_duplicates().tolist() self.widgets["select_var"].options = self.vars - # Reset var selection if old one is not available in new vars if self.widgets["select_var"].value not in self.vars: self.widgets["select_var"].value = self.vars[0] @@ -194,14 +198,14 @@ class CompareRuns: # anyway) self.update_var("", "", self.widgets["select_var"].value) - def update_var(self, attrname, old, new): # If the value is updated by the CustomJS, self.widgets["select_var"].value - # won't be updated, so we have to look for that case and assign it manually + # won't be updated, so we have to look for that case and assign it + # manually # new should be a list when updated by CustomJS - if type(new) == list: + if isinstance(new, list): new = new[0] if new != self.widgets["select_var"].value: @@ -209,10 +213,9 @@ class CompareRuns: self.widgets["select_var"].value = new return - # New list of available backends self.backends = self.data.loc[self.widgets["select_test"].value, self.widgets["select_var"].value]\ - .index.get_level_values("vfc_backend").drop_duplicates().tolist() + .index.get_level_values("vfc_backend").drop_duplicates().tolist() self.widgets["select_backend"].options = self.backends # Reset backend selection if old one is not available in new backends @@ -225,13 +228,11 @@ class CompareRuns: # anyway) self.update_backend("", "", self.widgets["select_backend"].value) - def update_backend(self, attrname, old, new): # Simply update plots, since no other data is affected self.update_plots() - def update_n_runs(self, attrname, old, new): # Simply update runs selection (value and string display) self.select_n_runs.value = new @@ -239,12 +240,9 @@ class CompareRuns: self.update_plots() - def update_outliers_filtering(self, attrname, old, new): self.update_plots() - - # Bokeh setup functions def setup_plots(self): @@ -256,7 +254,6 @@ class CompareRuns: # (defined inside template to avoid bloating server w/ too much JS code) js_tap_callback = "goToInspectRuns();" - # Box plot self.plots["boxplot"] = figure( name="boxplot", title="Variable distribution over runs", @@ -280,24 +277,23 @@ class CompareRuns: ("Number of samples", "@nsamples") ] box_tooltips_formatters = { - "@min" : "printf", - "@max" : "printf", - "@quantile25" : "printf", - "@quantile50" : "printf", - "@quantile75" : "printf", - "@mu" : "printf" + "@min": "printf", + "@max": "printf", + "@quantile25": "printf", + "@quantile50": "printf", + "@quantile75": "printf", + "@mu": "printf" } plot.fill_boxplot( self.plots["boxplot"], self.sources["boxplot_source"], - tooltips = box_tooltips, - tooltips_formatters = box_tooltips_formatters, - js_tap_callback = js_tap_callback, - server_tap_callback = self.inspect_run_callback_boxplot, + tooltips=box_tooltips, + tooltips_formatters=box_tooltips_formatters, + js_tap_callback=js_tap_callback, + server_tap_callback=self.inspect_run_callback_boxplot, ) self.doc.add_root(self.plots["boxplot"]) - # Sigma plot (bar plot) self.plots["sigma_plot"] = figure( name="sigma_plot", title="Standard deviation σ over runs", @@ -317,14 +313,13 @@ class CompareRuns: plot.fill_dotplot( self.plots["sigma_plot"], self.sources["sigma_source"], "sigma", - tooltips = sigma_tooltips, - js_tap_callback = js_tap_callback, - server_tap_callback = self.inspect_run_callback_sigma, - lines = True + tooltips=sigma_tooltips, + js_tap_callback=js_tap_callback, + server_tap_callback=self.inspect_run_callback_sigma, + lines=True ) self.doc.add_root(self.plots["sigma_plot"]) - # s plot (bar plot with 2 tabs) self.plots["s10_plot"] = figure( name="s10_plot", title="Significant digits s over runs", @@ -345,15 +340,14 @@ class CompareRuns: plot.fill_dotplot( self.plots["s10_plot"], self.sources["s10_source"], "s10", - tooltips = s10_tooltips, - js_tap_callback = js_tap_callback, - server_tap_callback = self.inspect_run_callback_s10, - lines = True, + tooltips=s10_tooltips, + js_tap_callback=js_tap_callback, + server_tap_callback=self.inspect_run_callback_s10, + lines=True, lower_bound=True ) s10_tab = Panel(child=self.plots["s10_plot"], title="Base 10") - self.plots["s2_plot"] = figure( name="s2_plot", title="Significant digits s over runs", plot_width=900, plot_height=400, x_range=[""], @@ -373,45 +367,42 @@ class CompareRuns: plot.fill_dotplot( self.plots["s2_plot"], self.sources["s2_source"], "s2", - tooltips = s2_tooltips, - js_tap_callback = js_tap_callback, - server_tap_callback = self.inspect_run_callback_s2, - lines = True, + tooltips=s2_tooltips, + js_tap_callback=js_tap_callback, + server_tap_callback=self.inspect_run_callback_s2, + lines=True, lower_bound=True ) s2_tab = Panel(child=self.plots["s2_plot"], title="Base 2") s_tabs = Tabs( - name = "s_tabs", + name="s_tabs", tabs=[s10_tab, s2_tab], - tabs_location = "below" + tabs_location="below" ) self.doc.add_root(s_tabs) - def setup_widgets(self): - # Initial selections + # Initial selections # Test/var/backend combination (we select all first elements at init) self.tests = self.data\ - .index.get_level_values("test").drop_duplicates().tolist() + .index.get_level_values("test").drop_duplicates().tolist() self.vars = self.data.loc[self.tests[0]]\ - .index.get_level_values("variable").drop_duplicates().tolist() + .index.get_level_values("variable").drop_duplicates().tolist() self.backends = self.data.loc[self.tests[0], self.vars[0]]\ - .index.get_level_values("vfc_backend").drop_duplicates().tolist() - + .index.get_level_values("vfc_backend").drop_duplicates().tolist() # Custom JS callback that will be used client side to filter selections filter_callback_js = """ selector.options = options.filter(e => e.includes(cb_obj.value)); """ - - # Test selector widget + # Test selector widget # Number of runs to display # The dict structure allows us to get int value from the display string @@ -442,14 +433,16 @@ class CompareRuns: self.widgets["test_filter"] = TextInput( name="test_filter", title="Tests filter:" ) - self.widgets["test_filter"].js_on_change("value", CustomJS( - args=dict(options=self.tests, selector=self.widgets["select_test"]), - code=filter_callback_js - )) + self.widgets["test_filter"].js_on_change( + "value", + CustomJS( + args=dict( + options=self.tests, + selector=self.widgets["select_test"]), + code=filter_callback_js)) self.doc.add_root(self.widgets["test_filter"]) - - # Number of runs to display + # Number of runs to display self.widgets["select_n_runs"] = Select( name="select_n_runs", title="Display :", @@ -458,8 +451,7 @@ class CompareRuns: self.doc.add_root(self.widgets["select_n_runs"]) self.widgets["select_n_runs"].on_change("value", self.update_n_runs) - - # Variable selector widget + # Variable selector widget self.widgets["select_var"] = Select( name="select_var", title="Variable :", @@ -469,8 +461,7 @@ class CompareRuns: self.widgets["select_var"].on_change("value", self.update_var) self.widgets["select_var"].on_change("options", self.update_var) - - # Backend selector widget + # Backend selector widget self.widgets["select_backend"] = Select( name="select_backend", title="Verificarlo backend :", @@ -479,23 +470,21 @@ class CompareRuns: self.doc.add_root(self.widgets["select_backend"]) self.widgets["select_backend"].on_change("value", self.update_backend) - - # Outliers filtering checkbox + # Outliers filtering checkbox self.widgets["outliers_filtering_compare"] = CheckboxGroup( name="outliers_filtering_compare", - labels=["Filter outliers"], active =[] + labels=["Filter outliers"], active=[] ) self.doc.add_root(self.widgets["outliers_filtering_compare"]) self.widgets["outliers_filtering_compare"]\ - .on_change("active", self.update_outliers_filtering) - - + .on_change("active", self.update_outliers_filtering) # Communication methods # (to send/receive messages to/from master) # Callback to change view of Inspect runs when data is selected + def inspect_run_callback(self, new, source_name, x_name): # In case we just unselected everything, then do nothing @@ -507,7 +496,6 @@ class CompareRuns: self.master.go_to_inspect(run_name) - # Wrappers for each plot (since new is the index of the clicked element, # it is dependent of the plot because we could have filtered some outliers) # There doesn't seem to be an easy way to add custom parameters to a @@ -525,7 +513,6 @@ class CompareRuns: def inspect_run_callback_s10(self, attr, old, new): self.inspect_run_callback(new, "s10_source", "s10_x") - # Constructor def __init__(self, master, doc, data, metadata): @@ -536,11 +523,10 @@ class CompareRuns: self.data = data self.metadata = metadata - self.sources = { "boxplot_source": ColumnDataSource(data={}), "sigma_source": ColumnDataSource(data={}), - "s10_source" :ColumnDataSource(data={}), + "s10_source": ColumnDataSource(data={}), "s2_source": ColumnDataSource(data={}) } diff --git a/ci/vfc_ci_report/helper.py b/ci/vfc_ci_report/helper.py index 57c84d7..f258959 100644 --- a/ci/vfc_ci_report/helper.py +++ b/ci/vfc_ci_report/helper.py @@ -10,7 +10,7 @@ import numpy as np max_ticks = 15 max_zscore = 3 -################################################################################ +########################################################################## # From a timestamp, return the associated metadata as a Pandas serie @@ -39,7 +39,6 @@ def get_run_name(timestamp, hash): now = calendar.timegm(gmt) diff = now - timestamp - # Special case : < 1 minute (return string directly) if diff < 60: str = "Less than a minute ago" @@ -83,12 +82,10 @@ def get_run_name(timestamp, hash): str = str % (n, plural) - # We might want to add the git hash if hash != "": str = str + " (%s)" % hash - # Finally, check for duplicate with previously generated string if str == get_run_name.previous: # Increment the duplicate counter and add it to str @@ -96,12 +93,14 @@ def get_run_name(timestamp, hash): str = "%s (%s)" % (str, get_run_name.counter) else: - # No duplicate, reset both previously generated str and duplicate counter + # No duplicate, reset both previously generated str and duplicate + # counter get_run_name.counter = 0 get_run_name.previous = str return str + # These external variables will store data about the last generated string to # avoid duplicates (assuming the runs are sorted by time) get_run_name.counter = 0 @@ -156,11 +155,16 @@ def remove_boxplot_outliers(dict, outliers, prefix): dict["%s_x" % prefix] = remove_outliers(dict["%s_x" % prefix], outliers) - dict["%s_min" % prefix] = remove_outliers(dict["%s_min" % prefix], outliers) - dict["%s_quantile25" % prefix] = remove_outliers(dict["%s_quantile25" % prefix], outliers) - dict["%s_quantile50" % prefix] = remove_outliers(dict["%s_quantile50" % prefix], outliers) - dict["%s_quantile75" % prefix] = remove_outliers(dict["%s_quantile75" % prefix], outliers) - dict["%s_max" % prefix] = remove_outliers(dict["%s_max" % prefix], outliers) + dict["%s_min" % prefix] = remove_outliers( + dict["%s_min" % prefix], outliers) + dict["%s_quantile25" % prefix] = remove_outliers( + dict["%s_quantile25" % prefix], outliers) + dict["%s_quantile50" % prefix] = remove_outliers( + dict["%s_quantile50" % prefix], outliers) + dict["%s_quantile75" % prefix] = remove_outliers( + dict["%s_quantile75" % prefix], outliers) + dict["%s_max" % prefix] = remove_outliers( + dict["%s_max" % prefix], outliers) dict["%s_mu" % prefix] = remove_outliers(dict["%s_mu" % prefix], outliers) dict["nsamples"] = remove_outliers(dict["nsamples"], outliers) diff --git a/ci/vfc_ci_report/inspect_runs.py b/ci/vfc_ci_report/inspect_runs.py index 57a1caa..f53ab17 100644 --- a/ci/vfc_ci_report/inspect_runs.py +++ b/ci/vfc_ci_report/inspect_runs.py @@ -9,19 +9,18 @@ import numpy as np from bokeh.plotting import figure, curdoc from bokeh.embed import components from bokeh.models import Select, ColumnDataSource, Panel, Tabs, HoverTool,\ -RadioButtonGroup, CheckboxGroup, CustomJS + RadioButtonGroup, CheckboxGroup, CustomJS import helper import plot -################################################################################ - +########################################################################## class InspectRuns: - # Helper functions related to InspectRun + # Helper functions related to InspectRun # Returns a dictionary mapping user-readable strings to all run timestamps def gen_runs_selection(self): @@ -40,7 +39,6 @@ class InspectRuns: return runs_dict - def gen_boxplot_tooltips(self, prefix): return [ ("Name", "@%s_x" % prefix), @@ -55,34 +53,35 @@ class InspectRuns: def gen_boxplot_tooltips_formatters(self, prefix): return { - "@%s_min" % prefix : "printf", - "@%s_max" % prefix : "printf", - "@%s_quantile25" % prefix : "printf", - "@%s_quantile50" % prefix : "printf", - "@%s_quantile75" % prefix : "printf", - "@%s_mu" % prefix : "printf" + "@%s_min" % prefix: "printf", + "@%s_max" % prefix: "printf", + "@%s_quantile25" % prefix: "printf", + "@%s_quantile50" % prefix: "printf", + "@%s_quantile75" % prefix: "printf", + "@%s_mu" % prefix: "printf" } - # Data processing helper # (computes new distributions for sigma, s2, s10) + def data_processing(self, dataframe): # Compute aggragated mu - dataframe["mu"] = np.vectorize(np.average)(dataframe["mu"], weights=dataframe["nsamples"]) + dataframe["mu"] = np.vectorize( + np.average)( + dataframe["mu"], + weights=dataframe["nsamples"]) # nsamples is the number of aggregated elements (as well as the number # of samples for our new sigma and s distributions) dataframe["nsamples"] = dataframe["nsamples"].apply(lambda x: len(x)) - dataframe["mu_x"] = dataframe.index # Make sure that strings don't excede a certain length dataframe["mu_x"] = dataframe["mu_x"].apply( lambda x: x[:17] + "[...]" + x[-17:] if len(x) > 39 else x ) - # Get quantiles and mu for sigma, s10, s2 for prefix in ["sigma", "s10", "s2"]: @@ -91,19 +90,19 @@ class InspectRuns: dataframe[prefix] = dataframe[prefix].apply(np.sort) dataframe["%s_min" % prefix] = dataframe[prefix].apply(np.min) - dataframe["%s_quantile25" % prefix] = dataframe[prefix].apply(np.quantile, args=(0.25,)) - dataframe["%s_quantile50" % prefix] = dataframe[prefix].apply(np.quantile, args=(0.50,)) - dataframe["%s_quantile75" % prefix] = dataframe[prefix].apply(np.quantile, args=(0.75,)) + dataframe["%s_quantile25" % prefix] = dataframe[prefix].apply( + np.quantile, args=(0.25,)) + dataframe["%s_quantile50" % prefix] = dataframe[prefix].apply( + np.quantile, args=(0.50,)) + dataframe["%s_quantile75" % prefix] = dataframe[prefix].apply( + np.quantile, args=(0.75,)) dataframe["%s_max" % prefix] = dataframe[prefix].apply(np.max) dataframe["%s_mu" % prefix] = dataframe[prefix].apply(np.average) del dataframe[prefix] - return dataframe - - - # Plots update function + # Plots update function def update_plots(self): @@ -117,8 +116,7 @@ class InspectRuns: ] filterby = self.factors_dict[filterby_display] - - # Groupby and aggregate lines belonging to the same group in lists + # Groupby and aggregate lines belonging to the same group in lists groups = self.run_data[ self.run_data.index.isin( @@ -131,32 +129,31 @@ class InspectRuns: "sigma": lambda x: x.tolist(), "s10": lambda x: x.tolist(), "s2": lambda x: x.tolist(), + "mu": lambda x: x.tolist(), # Used for mu weighted average first, then will be replaced "nsamples": lambda x: x.tolist() }) - - # Compute the new distributions, ... + # Compute the new distributions, ... groups = self.data_processing(groups).to_dict("list") - - # Update source + # Update source # Assign each ColumnDataSource, starting with the boxplots for prefix in ["sigma", "s10", "s2"]: dict = { - "%s_x" % prefix: groups["%s_x" % prefix], - "%s_min" % prefix: groups["%s_min" % prefix], - "%s_quantile25" % prefix: groups["%s_quantile25" % prefix], - "%s_quantile50" % prefix: groups["%s_quantile50" % prefix], - "%s_quantile75" % prefix: groups["%s_quantile75" % prefix], - "%s_max" % prefix: groups["%s_max" % prefix], - "%s_mu" % prefix: groups["%s_mu" % prefix], + "%s_x" % prefix: groups["%s_x" % prefix], + "%s_min" % prefix: groups["%s_min" % prefix], + "%s_quantile25" % prefix: groups["%s_quantile25" % prefix], + "%s_quantile50" % prefix: groups["%s_quantile50" % prefix], + "%s_quantile75" % prefix: groups["%s_quantile75" % prefix], + "%s_max" % prefix: groups["%s_max" % prefix], + "%s_mu" % prefix: groups["%s_mu" % prefix], - "nsamples": groups["nsamples"] + "nsamples": groups["nsamples"] } # Filter outliers if the box is checked @@ -166,7 +163,8 @@ class InspectRuns: top_outliers = helper.detect_outliers(dict["%s_max" % prefix]) helper.remove_boxplot_outliers(dict, top_outliers, prefix) - bottom_outliers = helper.detect_outliers(dict["%s_min" % prefix]) + bottom_outliers = helper.detect_outliers( + dict["%s_min" % prefix]) helper.remove_boxplot_outliers(dict, bottom_outliers, prefix) self.sources["%s_source" % prefix].data = dict @@ -185,8 +183,8 @@ class InspectRuns: if len(self.widgets["outliers_filtering_inspect"].active) > 0: mu_outliers = helper.detect_outliers(groups["mu"]) groups["mu"] = helper.remove_outliers(groups["mu"], mu_outliers) - groups["mu_x"] = helper.remove_outliers(groups["mu_x"], mu_outliers) - + groups["mu_x"] = helper.remove_outliers( + groups["mu_x"], mu_outliers) # Update plots axis/titles @@ -194,42 +192,38 @@ class InspectRuns: factors_dict = self.factors_dict.copy() del factors_dict[groupby_display] del factors_dict[filterby_display] - over_all = list(factors_dict.keys())[0] + for_all = list(factors_dict.keys())[0] # Update all display strings for plot title (remove caps, plural) groupby_display = groupby_display.lower() filterby_display = filterby_display.lower()[:-1] - over_all = over_all.lower() + for_all = for_all.lower() self.plots["mu_inspect"].title.text = \ - "Empirical average μ of %s (groupped by %s, for all %s)" \ - % (filterby_display, groupby_display, over_all) + "Empirical average μ of %s (groupped by %s, for all %s)" \ + % (filterby_display, groupby_display, for_all) self.plots["sigma_inspect"].title.text = \ - "Standard deviation σ of %s (groupped by %s, for all %s)" \ - % (filterby_display, groupby_display, over_all) + "Standard deviation σ of %s (groupped by %s, for all %s)" \ + % (filterby_display, groupby_display, for_all) self.plots["s10_inspect"].title.text = \ - "Significant digits s of %s (groupped by %s, for all %s)" \ - % (filterby_display, groupby_display, over_all) + "Significant digits s of %s (groupped by %s, for all %s)" \ + % (filterby_display, groupby_display, for_all) self.plots["s2_inspect"].title.text = \ - "Significant digits s of %s (groupped by %s, for all %s)" \ - % (filterby_display, groupby_display, over_all) - - - # Update x_ranges + "Significant digits s of %s (groupped by %s, for all %s)" \ + % (filterby_display, groupby_display, for_all) helper.reset_x_range(self.plots["mu_inspect"], groups["mu_x"]) helper.reset_x_range(self.plots["sigma_inspect"], groups["sigma_x"]) helper.reset_x_range(self.plots["s10_inspect"], groups["s10_x"]) helper.reset_x_range(self.plots["s2_inspect"], groups["s2_x"]) - - # Widets' callback functions # Run selector callback + def update_run(self, attrname, old, new): filterby = self.widgets["filterby_radio"].labels[ @@ -248,7 +242,7 @@ class InspectRuns: # Update filter options options = self.run_data.index\ - .get_level_values(filterby).drop_duplicates().tolist() + .get_level_values(filterby).drop_duplicates().tolist() self.widgets["select_filter"].options = options if old_value not in self.widgets["select_filter"].options: @@ -260,8 +254,8 @@ class InspectRuns: # anyway) self.update_filter("", "", old_value) - # "Group by" radio + def update_groupby(self, attrname, old, new): # Update "Filter by" radio list @@ -269,7 +263,6 @@ class InspectRuns: del filterby_list[self.widgets["groupby_radio"].active] self.widgets["filterby_radio"].labels = filterby_list - filterby = self.widgets["filterby_radio"].labels[ self.widgets["filterby_radio"].active ] @@ -280,7 +273,7 @@ class InspectRuns: # Update filter options options = self.run_data.index\ - .get_level_values(filterby).drop_duplicates().tolist() + .get_level_values(filterby).drop_duplicates().tolist() self.widgets["select_filter"].options = options if old_value not in self.widgets["select_filter"].options: @@ -292,8 +285,8 @@ class InspectRuns: # anyway) self.update_filter("", "", old_value) - # "Filter by" radio + def update_filterby(self, attrname, old, new): filterby = self.widgets["filterby_radio"].labels[ @@ -306,7 +299,7 @@ class InspectRuns: # Update filter selector options options = self.run_data.index\ - .get_level_values(filterby).drop_duplicates().tolist() + .get_level_values(filterby).drop_duplicates().tolist() self.widgets["select_filter"].options = options if old_value not in self.widgets["select_filter"].options: @@ -318,20 +311,18 @@ class InspectRuns: # anyway) self.update_filter("", "", old_value) - # Filter selector callback + def update_filter(self, attrname, old, new): self.update_plots() - # Filter outliers checkbox callback + def update_outliers_filtering(self, attrname, old, new): # The status (checked/unchecked) of the checkbox is also verified inside # self.update_plots(), so calling this function is enough self.update_plots() - - # Bokeh setup functions # (for both variable and backend selection at once) @@ -339,8 +330,7 @@ class InspectRuns: tools = "pan, wheel_zoom, xwheel_zoom, ywheel_zoom, reset, save" - - # Tooltips and formatters + # Tooltips and formatters dotplot_tooltips = [ ("Name", "@mu_x"), @@ -348,20 +338,22 @@ class InspectRuns: ("Number of samples (tests)", "@nsamples") ] dotplot_formatters = { - "@mu" : "printf" + "@mu": "printf" } sigma_boxplot_tooltips = self.gen_boxplot_tooltips("sigma") - sigma_boxplot_tooltips_formatters = self.gen_boxplot_tooltips_formatters("sigma") + sigma_boxplot_tooltips_formatters = self.gen_boxplot_tooltips_formatters( + "sigma") s10_boxplot_tooltips = self.gen_boxplot_tooltips("s10") - s10_boxplot_tooltips_formatters = self.gen_boxplot_tooltips_formatters("s10") + s10_boxplot_tooltips_formatters = self.gen_boxplot_tooltips_formatters( + "s10") s2_boxplot_tooltips = self.gen_boxplot_tooltips("s2") - s2_boxplot_tooltips_formatters = self.gen_boxplot_tooltips_formatters("s2") + s2_boxplot_tooltips_formatters = self.gen_boxplot_tooltips_formatters( + "s2") - - # Plots + # Plots # Mu plot self.plots["mu_inspect"] = figure( @@ -372,12 +364,11 @@ class InspectRuns: ) plot.fill_dotplot( self.plots["mu_inspect"], self.sources["mu_source"], "mu", - tooltips = dotplot_tooltips, - tooltips_formatters = dotplot_formatters + tooltips=dotplot_tooltips, + tooltips_formatters=dotplot_formatters ) self.doc.add_root(self.plots["mu_inspect"]) - # Sigma plot self.plots["sigma_inspect"] = figure( name="sigma_inspect", @@ -386,13 +377,13 @@ class InspectRuns: tools=tools, sizing_mode="scale_width" ) plot.fill_boxplot( - self.plots["sigma_inspect"], self.sources["sigma_source"], prefix="sigma", - tooltips = sigma_boxplot_tooltips, - tooltips_formatters = sigma_boxplot_tooltips_formatters - ) + self.plots["sigma_inspect"], + self.sources["sigma_source"], + prefix="sigma", + tooltips=sigma_boxplot_tooltips, + tooltips_formatters=sigma_boxplot_tooltips_formatters) self.doc.add_root(self.plots["sigma_inspect"]) - # s plots self.plots["s10_inspect"] = figure( name="s10_inspect", @@ -401,11 +392,14 @@ class InspectRuns: tools=tools, sizing_mode='scale_width' ) plot.fill_boxplot( - self.plots["s10_inspect"], self.sources["s10_source"], prefix="s10", - tooltips = s10_boxplot_tooltips, - tooltips_formatters = s10_boxplot_tooltips_formatters - ) - s10_tab_inspect = Panel(child=self.plots["s10_inspect"], title="Base 10") + self.plots["s10_inspect"], + self.sources["s10_source"], + prefix="s10", + tooltips=s10_boxplot_tooltips, + tooltips_formatters=s10_boxplot_tooltips_formatters) + s10_tab_inspect = Panel( + child=self.plots["s10_inspect"], + title="Base 10") self.plots["s2_inspect"] = figure( name="s2_inspect", @@ -415,22 +409,20 @@ class InspectRuns: ) plot.fill_boxplot( self.plots["s2_inspect"], self.sources["s2_source"], prefix="s2", - tooltips = s2_boxplot_tooltips, - tooltips_formatters = s2_boxplot_tooltips_formatters + tooltips=s2_boxplot_tooltips, + tooltips_formatters=s2_boxplot_tooltips_formatters ) s2_tab_inspect = Panel(child=self.plots["s2_inspect"], title="Base 2") s_tabs_inspect = Tabs( - name = "s_tabs_inspect", - tabs=[s10_tab_inspect, s2_tab_inspect], tabs_location = "below" + name="s_tabs_inspect", + tabs=[s10_tab_inspect, s2_tab_inspect], tabs_location="below" ) self.doc.add_root(s_tabs_inspect) - - def setup_widgets(self): - # Generation of selectable items + # Generation of selectable items # Dict contains all inspectable runs (maps display strings to timestamps) # The dict structure allows to get the timestamp from the display string @@ -445,8 +437,7 @@ class InspectRuns: "Tests": "test" } - - # Run selection + # Run selection # Contains all options strings runs_display = list(self.runs_dict.keys()) @@ -457,8 +448,7 @@ class InspectRuns: # This contains only entries matching the run self.run_data = self.data[self.data["timestamp"] == self.current_run] - - change_run_callback_js="updateRunMetadata(cb_obj.value);" + change_run_callback_js = "updateRunMetadata(cb_obj.value);" self.widgets["select_run"] = Select( name="select_run", title="Run :", @@ -467,7 +457,7 @@ class InspectRuns: self.doc.add_root(self.widgets["select_run"]) self.widgets["select_run"].on_change("value", self.update_run) self.widgets["select_run"].js_on_change("value", CustomJS( - code = change_run_callback_js, + code=change_run_callback_js, args=(dict( metadata=helper.metadata_to_dict( helper.get_metadata(self.metadata, self.current_run) @@ -475,8 +465,7 @@ class InspectRuns: )) )) - - # Factors selection + # Factors selection # "Group by" radio self.widgets["groupby_radio"] = RadioButtonGroup( @@ -491,7 +480,6 @@ class InspectRuns: self.update_groupby ) - # "Filter by" radio # Get all possible factors, and remove the one selected in "Group by" filterby_list = list(self.factors_dict.keys()) @@ -509,7 +497,6 @@ class InspectRuns: self.update_filterby ) - # Filter selector filterby = self.widgets["filterby_radio"].labels[ @@ -518,7 +505,7 @@ class InspectRuns: filterby = self.factors_dict[filterby] options = self.run_data.index\ - .get_level_values(filterby).drop_duplicates().tolist() + .get_level_values(filterby).drop_duplicates().tolist() self.widgets["select_filter"] = Select( # We need a different name to avoid collision in the template with @@ -528,30 +515,26 @@ class InspectRuns: ) self.doc.add_root(self.widgets["select_filter"]) self.widgets["select_filter"]\ - .on_change("value", self.update_filter) + .on_change("value", self.update_filter) - - # Toggle for outliers filtering + # Toggle for outliers filtering self.widgets["outliers_filtering_inspect"] = CheckboxGroup( name="outliers_filtering_inspect", - labels=["Filter outliers"], active = [] + labels=["Filter outliers"], active=[] ) self.doc.add_root(self.widgets["outliers_filtering_inspect"]) self.widgets["outliers_filtering_inspect"]\ - .on_change("active", self.update_outliers_filtering) - - + .on_change("active", self.update_outliers_filtering) # Communication methods # (to send/receive messages to/from master) # When received, switch to the run_name in parameter + def switch_view(self, run_name): self.widgets["select_run"].value = run_name - - # Constructor def __init__(self, master, doc, data, metadata): @@ -562,11 +545,10 @@ class InspectRuns: self.data = data self.metadata = metadata - self.sources = { "mu_source": ColumnDataSource(data={}), "sigma_source": ColumnDataSource(data={}), - "s10_source" :ColumnDataSource(data={}), + "s10_source": ColumnDataSource(data={}), "s2_source": ColumnDataSource(data={}) } diff --git a/ci/vfc_ci_report/main.py b/ci/vfc_ci_report/main.py index d011b3e..4af73d2 100644 --- a/ci/vfc_ci_report/main.py +++ b/ci/vfc_ci_report/main.py @@ -1,5 +1,5 @@ # Look for and read all the run files in the current directory (ending with -# .vfcrun.hd5), and lanch a Bokeh server for the visualization of this data. +# .vfcrunh5), and lanch a Bokeh server for the visualization of this data. import os import sys @@ -14,18 +14,16 @@ import compare_runs import inspect_runs import helper -################################################################################ +########################################################################## +# Read vfcrun files, and aggregate them in one dataset - # Read vfcrun files, and aggregate them in one dataset - -run_files = [ f for f in os.listdir(".") if f.endswith(".vfcrun.hd5") ] +run_files = [f for f in os.listdir(".") if f.endswith(".vfcrun.h5")] if len(run_files) == 0: print( - "Warning [vfc_ci]: Could not find any vfcrun files in the directory. " \ - "This will result in server errors and prevent you from viewing the report." - ) + "Warning [vfc_ci]: Could not find any vfcrun files in the directory. " + "This will result in server errors and prevent you from viewing the report.") # These are arrays of Pandas dataframes for now metadata = [] @@ -55,15 +53,14 @@ metadata["date"] = metadata.index.to_series().map( ) -################################################################################ +########################################################################## curdoc().title = "Verificarlo Report" - - # Read server arguments - # (this is quite easy because Bokeh server is called through a wrapper, so - # we know exactly what the arguments might be) +# Read server arguments +# (this is quite easy because Bokeh server is called through a wrapper, so +# we know exactly what the arguments might be) git_repo_linked = False commit_link = "" @@ -83,7 +80,6 @@ for i in range(1, len(sys.argv)): address = sys.argv[i + 2] url = "" - # Here, address is either the remote URL or the path to the local Git # repo (depending on the method) @@ -99,12 +95,11 @@ for i in range(1, len(sys.argv)): else: raise ValueError( - "Error [vfc_ci]: The specified method to get the Git " \ - "repository is invalid. Are you calling Bokeh directly " \ + "Error [vfc_ci]: The specified method to get the Git " + "repository is invalid. Are you calling Bokeh directly " "instead of using the Verificarlo wrapper ?" ) - # At this point, "url" should be set correctly, we can get the repo's # URL and name, after making sure we're on a Git URL @@ -113,7 +108,7 @@ for i in range(1, len(sys.argv)): path = parsed_url.path.split("/") if len(path) < 3: raise ValueError( - "Error [vfc_ci]: The found URL doesn't seem to be pointing " \ + "Error [vfc_ci]: The found URL doesn't seem to be pointing " "to a Git repository (path is too short)" ) @@ -122,12 +117,11 @@ for i in range(1, len(sys.argv)): curdoc().template_variables["repo_url"] = url curdoc().template_variables["repo_name"] = repo_name - # We should have a "github.com" or a "*gitlab*" URL if parsed_url.netloc == "github.com": commit_link = "https://%s%s/commit/" \ - % (parsed_url.netloc, parsed_url.path) + % (parsed_url.netloc, parsed_url.path) curdoc().template_variables["commit_link"] = commit_link curdoc().template_variables["git_host"] = "GitHub" @@ -138,7 +132,7 @@ for i in range(1, len(sys.argv)): # We assume we have a GitLab URL else: commit_link = "https://%s%s/-/commit/" \ - % (parsed_url.netloc, parsed_url.path) + % (parsed_url.netloc, parsed_url.path) curdoc().template_variables["commit_link"] = commit_link curdoc().template_variables["git_host"] = "GitLab" @@ -148,8 +142,6 @@ for i in range(1, len(sys.argv)): git_repo_linked = True - - # Look for a logo URL # If a logo URL is specified, it will be included in the report's header if sys.argv[i] == "logo": @@ -162,10 +154,9 @@ curdoc().template_variables["git_repo_linked"] = git_repo_linked curdoc().template_variables["has_logo"] = has_logo -################################################################################ +########################################################################## - - # Setup report views +# Setup report views # Define a ViewsMaster class to allow two-ways communication between views. # This approach by classes allows us to have separate scopes for each view and @@ -174,13 +165,12 @@ curdoc().template_variables["has_logo"] = has_logo class ViewsMaster: - # Communication functions + # Communication functions def go_to_inspect(self, run_name): self.inspect.switch_view(run_name) - - #Constructor + # Constructor def __init__(self, data, metadata, git_repo_linked, commit_link): @@ -190,28 +180,29 @@ class ViewsMaster: self.commit_link = commit_link # Pass metadata to the template as a JSON string - curdoc().template_variables["metadata"] = self.metadata.to_json(orient="index") + curdoc().template_variables["metadata"] = self.metadata.to_json( + orient="index") # Runs comparison self.compare = compare_runs.CompareRuns( - master = self, - doc = curdoc(), - data = data, - metadata = metadata, + master=self, + doc=curdoc(), + data=data, + metadata=metadata, ) # Runs inspection self.inspect = inspect_runs.InspectRuns( - master = self, - doc = curdoc(), - data = data, - metadata = metadata, + master=self, + doc=curdoc(), + data=data, + metadata=metadata, ) views_master = ViewsMaster( - data = data, - metadata = metadata, - git_repo_linked = git_repo_linked, - commit_link = commit_link + data=data, + metadata=metadata, + git_repo_linked=git_repo_linked, + commit_link=commit_link ) diff --git a/ci/vfc_ci_report/plot.py b/ci/vfc_ci_report/plot.py index 270266e..f4bb20f 100644 --- a/ci/vfc_ci_report/plot.py +++ b/ci/vfc_ci_report/plot.py @@ -15,21 +15,19 @@ def fill_dotplot( ): # (Optional) Tooltip and tooltip formatters - if tooltips != None: - hover = HoverTool(tooltips = tooltips, mode="vline", names=["circle"]) + if tooltips is not None: + hover = HoverTool(tooltips=tooltips, mode="vline", names=["circle"]) - if tooltips_formatters != None: + if tooltips_formatters is not None: hover.formatters = tooltips_formatters plot.add_tools(hover) - # (Optional) Add TapTool (for JS tap callback) - if js_tap_callback != None: + if js_tap_callback is not None: tap = TapTool(callback=CustomJS(code=js_tap_callback)) plot.add_tools(tap) - # (Optional) Add segment to represent a lower bound if lower_bound: lower_segment = plot.segment( @@ -38,24 +36,20 @@ def fill_dotplot( source=source, line_color="black" ) - # Draw dots (actually Bokeh circles) circle = plot.circle( name="circle", x="%s_x" % data_field, y=data_field, source=source, size=12 ) - # (Optional) Draw lines between dots if lines: line = plot.line(x="%s_x" % data_field, y=data_field, source=source) - # (Optional) Add server tap callback - if server_tap_callback != None: + if server_tap_callback is not None: circle.data_source.selected.on_change("indices", server_tap_callback) - # Plot appearance plot.xgrid.grid_line_color = None plot.ygrid.grid_line_color = None @@ -64,33 +58,30 @@ def fill_dotplot( plot.yaxis[0].formatter.power_limit_low = 0 plot.yaxis[0].formatter.precision = 3 - plot.xaxis[0].major_label_orientation = pi/8 - + plot.xaxis[0].major_label_orientation = pi / 8 def fill_boxplot( plot, source, prefix="", tooltips=None, tooltips_formatters=None, - js_tap_callback=None, server_tap_callback=None, + js_tap_callback=None, server_tap_callback=None ): # (Optional) Tooltip and tooltip formatters - if tooltips != None: - hover = HoverTool(tooltips = tooltips, mode="vline", names=["full_box"]) + if tooltips is not None: + hover = HoverTool(tooltips=tooltips, mode="vline", names=["full_box"]) - if tooltips_formatters != None: + if tooltips_formatters is not None: hover.formatters = tooltips_formatters plot.add_tools(hover) - # (Optional) Add TapTool (for JS tap callback) - if js_tap_callback != None: + if js_tap_callback is not None: tap = TapTool(callback=CustomJS(code=js_tap_callback)) plot.add_tools(tap) - # Draw boxes (the prefix argument modifies the fields of ColumnDataSource # that are used) @@ -128,18 +119,18 @@ def fill_boxplot( color="black" ) - # (Optional) Add server tap callback - if server_tap_callback != None: + if server_tap_callback is not None: top_stem.data_source.selected.on_change("indices", server_tap_callback) - bottom_stem.data_source.selected.on_change("indices", server_tap_callback) + bottom_stem.data_source.selected.on_change( + "indices", server_tap_callback) full_box.data_source.selected.on_change("indices", server_tap_callback) - bottom_box.data_source.selected.on_change("indices", server_tap_callback) + bottom_box.data_source.selected.on_change( + "indices", server_tap_callback) mu_dot.data_source.selected.on_change("indices", server_tap_callback) - # Plot appearance plot.xgrid.grid_line_color = None plot.ygrid.grid_line_color = None @@ -148,4 +139,4 @@ def fill_boxplot( plot.yaxis[0].formatter.power_limit_low = 0 plot.yaxis[0].formatter.precision = 3 - plot.xaxis[0].major_label_orientation = pi/8 + plot.xaxis[0].major_label_orientation = pi / 8 diff --git a/ci/vfc_ci_report/templates/index.html b/ci/vfc_ci_report/templates/index.html index 2ec7fc6..8fea8ec 100644 --- a/ci/vfc_ci_report/templates/index.html +++ b/ci/vfc_ci_report/templates/index.html @@ -291,19 +291,19 @@

Plots

-
+
{{ embed(roots.s_tabs_inspect) }}

-
+
{{ embed(roots.sigma_inspect) }}

-
+
{{ embed(roots.mu_inspect) }}
@@ -325,6 +325,8 @@
+ +