From c4dc251eb2adf15f02c56719174cf8532bab7284 Mon Sep 17 00:00:00 2001 From: zane <39070793+zaneenders@users.noreply.github.com> Date: Wed, 21 Aug 2024 14:17:29 -0600 Subject: [PATCH 1/5] Remove helper, break out pages. --- src/api/demo.rkt | 42 +++++++++++++++++++++++------------------- src/reports/pages.rkt | 42 ++++++++++++++++++++++++++---------------- 2 files changed, 49 insertions(+), 35 deletions(-) diff --git a/src/api/demo.rkt b/src/api/demo.rkt index 3f8c7181f..5a009bb5d 100644 --- a/src/api/demo.rkt +++ b/src/api/demo.rkt @@ -48,9 +48,14 @@ (and (not (and (*demo-output*) ; If we've already saved to disk, skip this job (directory-exists? (build-path (*demo-output*) x)))) (let ([m (regexp-match #rx"^([0-9a-f]+)\\.[0-9a-f.]+" x)]) + (eprintf "TOPx: ~a\n" x) + (eprintf "TOPm: ~a\n" m) (and m (get-results-for (second m)))))) (λ (x) - (let ([m (regexp-match #rx"^([0-9a-f]+)\\.[0-9a-f.]+" x)]) (get-results-for (if m (second m) x))))) + (let ([m (regexp-match #rx"^([0-9a-f]+)\\.[0-9a-f.]+" x)]) + (eprintf "BOTTOMx: ~a\n" x) + (eprintf "BOTTOMm: ~a\n" m) + (get-results-for (if m (second m) x))))) (define-bidi-match-expander hash-arg hash-arg/m hash-arg/m) @@ -75,6 +80,8 @@ [("results.json") generate-report])) (define (generate-page req result-hash page) + (eprintf "PAGE: ~a\n" page) + (eprintf "~a\n" req) (define path (first (string-split (url->string (request-uri req)) "/"))) (cond [(set-member? (all-pages result-hash) page) @@ -87,11 +94,21 @@ (λ (out) (with-handlers ([exn:fail? (page-error-handler result-hash page out)]) (make-page page out result-hash (*demo-output*) #f))))) - (update-report result-hash - path - (get-seed) - (build-path (*demo-output*) "results.json") - (build-path (*demo-output*) "index.html"))) + (define link (path-element->string (last (explode-path path)))) + (define data (get-table-data-from-hash result-hash link)) + (define data-file (build-path (*demo-output*) "results.json")) + (define html-file (build-path (*demo-output*) "index.html")) + (define info + (if (file-exists? data-file) + (let ([info (read-datafile data-file)]) + (struct-copy report-info info [tests (cons data (report-info-tests info))])) + (make-report-info (list data) + #:seed (get-seed) + #:note (if (*demo?*) "Web demo results" "")))) + (define tmp-file (build-path (*demo-output*) "results.tmp")) + (write-datafile tmp-file info) + (rename-file-or-directory tmp-file data-file #t) + (copy-file (web-resource "report.html") html-file #t)) (response 200 #"OK" (current-seconds) @@ -234,19 +251,6 @@ (a ([href "./index.html"]) " See what formulas other users submitted."))] [else `("all formulas submitted here are " (a ([href "./index.html"]) "logged") ".")]))))) -(define (update-report result-hash dir seed data-file html-file) - (define link (path-element->string (last (explode-path dir)))) - (define data (get-table-data-from-hash result-hash link)) - (define info - (if (file-exists? data-file) - (let ([info (read-datafile data-file)]) - (struct-copy report-info info [tests (cons data (report-info-tests info))])) - (make-report-info (list data) #:seed seed #:note (if (*demo?*) "Web demo results" "")))) - (define tmp-file (build-path (*demo-output*) "results.tmp")) - (write-datafile tmp-file info) - (rename-file-or-directory tmp-file data-file #t) - (copy-file (web-resource "report.html") html-file #t)) - (define (post-with-json-response fn) (lambda (req) (define post-body (request-post-data/raw req)) diff --git a/src/reports/pages.rkt b/src/reports/pages.rkt index 212a9f50a..30310a77b 100644 --- a/src/reports/pages.rkt +++ b/src/reports/pages.rkt @@ -31,20 +31,30 @@ (display "" out))) (define (make-page page out result-hash output? profile?) - (define test (hash-ref result-hash 'test)) - (define status (hash-ref result-hash 'status)) (match page - ["graph.html" - (match status - ['success - (define command (hash-ref result-hash 'command)) - (match command - ["improve" (make-graph result-hash out output? profile?)] - [else (dummy-graph command out)])] - ['timeout (make-traceback result-hash out)] - ['failure (make-traceback result-hash out)] - [_ (error 'make-page "unknown result type ~a" status)])] - ["timeline.html" - (make-timeline (test-name test) (hash-ref result-hash 'timeline) out #:path "..")] - ["timeline.json" (write-json (hash-ref result-hash 'timeline) out)] - ["points.json" (write-json (make-points-json result-hash) out)])) + ["graph.html" (make-graph-html out result-hash output? profile?)] + ["timeline.html" (make-timeline-html out result-hash)] + ["timeline.json" (make-timeline-json out result-hash)] + ["points.json" (make-points out result-hash)])) + +(define (make-graph-html out result-hash output? profile?) + (define status (hash-ref result-hash 'status)) + (match status + ['success + (define command (hash-ref result-hash 'command)) + (match command + ["improve" (make-graph result-hash out output? profile?)] + [else (dummy-graph command out)])] + ['timeout (make-traceback result-hash out)] + ['failure (make-traceback result-hash out)] + [_ (error 'make-page "unknown result type ~a" status)])) + +(define (make-points out result-hash) + (write-json (make-points-json result-hash) out)) + +(define (make-timeline-json out result-hash) + (write-json (hash-ref result-hash 'timeline) out)) + +(define (make-timeline-html out result-hash) + (define test (hash-ref result-hash 'test)) + (make-timeline (test-name test) (hash-ref result-hash 'timeline) out #:path "..")) From a67ec1a5b75c49f48f006775087228530773f20d Mon Sep 17 00:00:00 2001 From: zane <39070793+zaneenders@users.noreply.github.com> Date: Thu, 22 Aug 2024 10:34:20 -0600 Subject: [PATCH 2/5] Push up out. --- src/api/demo.rkt | 17 +-- src/reports/make-graph.rkt | 253 ++++++++++++++++++------------------- src/reports/pages.rkt | 32 +++-- src/reports/plot.rkt | 21 +-- src/reports/timeline.rkt | 26 ++-- src/reports/traceback.rkt | 76 ++++++----- 6 files changed, 201 insertions(+), 224 deletions(-) diff --git a/src/api/demo.rkt b/src/api/demo.rkt index 5a009bb5d..b945c38a1 100644 --- a/src/api/demo.rkt +++ b/src/api/demo.rkt @@ -18,18 +18,14 @@ "../config.rkt" "../syntax/read.rkt" "../utils/errors.rkt") -(require "../syntax/types.rkt" +(require "../syntax/sugar.rkt" - "../utils/alternative.rkt" "../core/points.rkt" - "../api/sandbox.rkt" - "../utils/float.rkt") + "../api/sandbox.rkt") (require "datafile.rkt" "../reports/pages.rkt" "../reports/common.rkt" "../reports/core2mathjs.rkt" - "../reports/history.rkt" - "../reports/plot.rkt" "server.rkt") (provide run-demo) @@ -48,14 +44,9 @@ (and (not (and (*demo-output*) ; If we've already saved to disk, skip this job (directory-exists? (build-path (*demo-output*) x)))) (let ([m (regexp-match #rx"^([0-9a-f]+)\\.[0-9a-f.]+" x)]) - (eprintf "TOPx: ~a\n" x) - (eprintf "TOPm: ~a\n" m) (and m (get-results-for (second m)))))) (λ (x) - (let ([m (regexp-match #rx"^([0-9a-f]+)\\.[0-9a-f.]+" x)]) - (eprintf "BOTTOMx: ~a\n" x) - (eprintf "BOTTOMm: ~a\n" m) - (get-results-for (if m (second m) x))))) + (let ([m (regexp-match #rx"^([0-9a-f]+)\\.[0-9a-f.]+" x)]) (get-results-for (if m (second m) x))))) (define-bidi-match-expander hash-arg hash-arg/m hash-arg/m) @@ -80,8 +71,6 @@ [("results.json") generate-report])) (define (generate-page req result-hash page) - (eprintf "PAGE: ~a\n" page) - (eprintf "~a\n" req) (define path (first (string-split (url->string (request-uri req)) "/"))) (cond [(set-member? (all-pages result-hash) page) diff --git a/src/reports/make-graph.rkt b/src/reports/make-graph.rkt index 3dcf1f373..66ccafda7 100644 --- a/src/reports/make-graph.rkt +++ b/src/reports/make-graph.rkt @@ -6,16 +6,12 @@ (require "../utils/common.rkt" "../core/points.rkt" "../utils/float.rkt" - "../core/programs.rkt" "../utils/alternative.rkt" "../syntax/types.rkt" "../syntax/read.rkt" "../core/bsearch.rkt" "../api/sandbox.rkt" - "common.rkt" - "history.rkt" - "../syntax/sugar.rkt" - "timeline.rkt") + "common.rkt") (provide make-graph dummy-graph) @@ -36,20 +32,18 @@ [(list op args ...) (ormap list? args)] [_ #f])) -(define (dummy-graph command out) - (write-html - `(html (head (meta ([charset "utf-8"])) - (title "Result page for the " ,(~a command) " command is not available right now.") - ,@js-tex-include - (script ([src "https://unpkg.com/mathjs@4.4.2/dist/math.min.js"])) - (script ([src "https://unpkg.com/d3@6.7.0/dist/d3.min.js"])) - (script ([src "https://unpkg.com/@observablehq/plot@0.4.3/dist/plot.umd.min.js"])) - (link ([rel "stylesheet"] [type "text/css"] [href "../report.css"])) - (script ([src "../report.js"]))) - (body (h2 "Result page for the " ,(~a command) " command is not available right now."))) - out)) - -(define (make-graph result-hash out output? profile?) +(define (dummy-graph command) + `(html (head (meta ([charset "utf-8"])) + (title "Result page for the " ,(~a command) " command is not available right now.") + ,@js-tex-include + (script ([src "https://unpkg.com/mathjs@4.4.2/dist/math.min.js"])) + (script ([src "https://unpkg.com/d3@6.7.0/dist/d3.min.js"])) + (script ([src "https://unpkg.com/@observablehq/plot@0.4.3/dist/plot.umd.min.js"])) + (link ([rel "stylesheet"] [type "text/css"] [href "../report.css"])) + (script ([src "../report.js"]))) + (body (h2 "Result page for the " ,(~a command) " command is not available right now.")))) + +(define (make-graph result-hash output? profile?) (define backend (hash-ref result-hash 'backend)) (define test (hash-ref result-hash 'test)) (define time (hash-ref result-hash 'time)) @@ -90,123 +84,120 @@ (define end-error (car end-errors)) - (write-html - `(html - (head (meta ([charset "utf-8"])) - (title "Result for " ,(~a (test-name test))) - ,@js-tex-include - (script ([src "https://unpkg.com/mathjs@4.4.2/dist/math.min.js"])) - (script ([src "https://unpkg.com/d3@6.7.0/dist/d3.min.js"])) - (script ([src "https://unpkg.com/@observablehq/plot@0.4.3/dist/plot.umd.min.js"])) - (link ([rel "stylesheet"] [type "text/css"] [href "../report.css"])) - (script ([src "../report.js"]))) - (body - ,(render-menu #:path ".." - (~a (test-name test)) - (if output? - (list '("Report" . "../index.html") '("Metrics" . "timeline.html")) - (list '("Metrics" . "timeline.html")))) - (div ([id "large"]) - ,(render-comparison - "Percentage Accurate" - (format-accuracy (errors-score start-error) repr-bits #:unit "%") - (format-accuracy (errors-score end-error) repr-bits #:unit "%") - #:title - (format "Minimum Accuracy: ~a → ~a" - (format-accuracy (apply max (map ulps->bits start-error)) repr-bits #:unit "%") - (format-accuracy (apply max (map ulps->bits end-error)) repr-bits #:unit "%"))) - ,(render-large "Time" (format-time time)) - ,(render-large "Alternatives" (~a (length end-exprs))) - ,(if (*pareto-mode*) - (render-large "Speedup" - (if speedup (~r speedup #:precision '(= 1)) "N/A") - "×" - #:title "Relative speed of fastest alternative that improves accuracy.") - "")) - ,(render-warnings warnings) - ,(render-specification test #:bogosity bogosity) - (figure ([id "graphs"]) - (h2 "Local Percentage Accuracy vs " - (span ([id "variables"])) - (a ((class "help-button float") [href ,(doc-url "report.html#graph")] + `(html + (head (meta ([charset "utf-8"])) + (title "Result for " ,(~a (test-name test))) + ,@js-tex-include + (script ([src "https://unpkg.com/mathjs@4.4.2/dist/math.min.js"])) + (script ([src "https://unpkg.com/d3@6.7.0/dist/d3.min.js"])) + (script ([src "https://unpkg.com/@observablehq/plot@0.4.3/dist/plot.umd.min.js"])) + (link ([rel "stylesheet"] [type "text/css"] [href "../report.css"])) + (script ([src "../report.js"]))) + (body + ,(render-menu #:path ".." + (~a (test-name test)) + (if output? + (list '("Report" . "../index.html") '("Metrics" . "timeline.html")) + (list '("Metrics" . "timeline.html")))) + (div ([id "large"]) + ,(render-comparison + "Percentage Accurate" + (format-accuracy (errors-score start-error) repr-bits #:unit "%") + (format-accuracy (errors-score end-error) repr-bits #:unit "%") + #:title + (format "Minimum Accuracy: ~a → ~a" + (format-accuracy (apply max (map ulps->bits start-error)) repr-bits #:unit "%") + (format-accuracy (apply max (map ulps->bits end-error)) repr-bits #:unit "%"))) + ,(render-large "Time" (format-time time)) + ,(render-large "Alternatives" (~a (length end-exprs))) + ,(if (*pareto-mode*) + (render-large "Speedup" + (if speedup (~r speedup #:precision '(= 1)) "N/A") + "×" + #:title "Relative speed of fastest alternative that improves accuracy.") + "")) + ,(render-warnings warnings) + ,(render-specification test #:bogosity bogosity) + (figure ([id "graphs"]) + (h2 "Local Percentage Accuracy vs " + (span ([id "variables"])) + (a ((class "help-button float") [href ,(doc-url "report.html#graph")] + [target "_blank"]) + "?")) + (svg) + (div ([id "functions"])) + (figcaption "The average percentage accuracy by input value. Horizontal axis shows " + "value of an input variable; the variable is choosen in the title. " + "Vertical axis is accuracy; higher is better. Red represent the original " + "program, while blue represents Herbie's suggestion. " + "These can be toggled with buttons below the plot. " + "The line is an average while dots represent individual samples.")) + (section ([id "cost-accuracy"] (class "section") [data-benchmark-name ,(~a (test-name test))]) + ; TODO : Show all Developer Target Accuracy + (h2 "Accuracy vs Speed" + (a ((class "help-button float") [href ,(doc-url "report.html#cost-accuracy")] [target "_blank"]) "?")) - (svg) - (div ([id "functions"])) - (figcaption "The average percentage accuracy by input value. Horizontal axis shows " - "value of an input variable; the variable is choosen in the title. " - "Vertical axis is accuracy; higher is better. Red represent the original " - "program, while blue represents Herbie's suggestion. " - "These can be toggled with buttons below the plot. " - "The line is an average while dots represent individual samples.")) - (section ([id "cost-accuracy"] (class "section") [data-benchmark-name ,(~a (test-name test))]) - ; TODO : Show all Developer Target Accuracy - (h2 "Accuracy vs Speed" - (a ((class "help-button float") [href ,(doc-url "report.html#cost-accuracy")] - [target "_blank"]) - "?")) - (div ((class "figure-row")) - (svg) - (div (p "Herbie found " ,(~a (length end-exprs)) " alternatives:") - (table (thead (tr (th "Alternative") - (th ((class "numeric")) "Accuracy") - (th ((class "numeric")) "Speedup"))) - (tbody)))) - (figcaption "The accuracy (vertical axis) and speed (horizontal axis) of each " - "alternatives. Up and to the right is better. The red square shows " - "the initial program, and each blue circle shows an alternative." - "The line shows the best available speed-accuracy tradeoffs.")) - ,(let-values ([(dropdown body) (render-program (alt-expr start-alt) ctx #:ident identifier)]) - `(section ([id "initial"] (class "programs")) - (h2 "Initial Program" + (div ((class "figure-row")) + (svg) + (div (p "Herbie found " ,(~a (length end-exprs)) " alternatives:") + (table (thead (tr (th "Alternative") + (th ((class "numeric")) "Accuracy") + (th ((class "numeric")) "Speedup"))) + (tbody)))) + (figcaption "The accuracy (vertical axis) and speed (horizontal axis) of each " + "alternatives. Up and to the right is better. The red square shows " + "the initial program, and each blue circle shows an alternative." + "The line shows the best available speed-accuracy tradeoffs.")) + ,(let-values ([(dropdown body) (render-program (alt-expr start-alt) ctx #:ident identifier)]) + `(section ([id "initial"] (class "programs")) + (h2 "Initial Program" + ": " + (span ((class "subhead")) + (data ,(format-accuracy (errors-score start-error) repr-bits #:unit "%")) + " accurate, " + (data "1.0×") + " speedup") + ,dropdown + ,(render-help "report.html#alternatives")) + ,body)) + ,@(for/list ([i (in-naturals 1)] + [expr end-exprs] + [errs end-errors] + [cost end-costs] + [history (hash-ref end 'end-histories)]) + (define-values (dropdown body) + (render-program expr ctx #:ident identifier #:instructions preprocessing)) + `(section ([id ,(format "alternative~a" i)] (class "programs")) + (h2 "Alternative " + ,(~a i) ": " (span ((class "subhead")) - (data ,(format-accuracy (errors-score start-error) repr-bits #:unit "%")) + (data ,(format-accuracy (errors-score errs) repr-bits #:unit "%")) " accurate, " - (data "1.0×") + (data ,(~r (/ (alt-cost start-alt repr) cost) #:precision '(= 1)) "×") " speedup") ,dropdown ,(render-help "report.html#alternatives")) - ,body)) - ,@(for/list ([i (in-naturals 1)] - [expr end-exprs] - [errs end-errors] - [cost end-costs] - [history (hash-ref end 'end-histories)]) - - (define-values (dropdown body) - (render-program expr ctx #:ident identifier #:instructions preprocessing)) - `(section ([id ,(format "alternative~a" i)] (class "programs")) - (h2 "Alternative " - ,(~a i) - ": " - (span ((class "subhead")) - (data ,(format-accuracy (errors-score errs) repr-bits #:unit "%")) - " accurate, " - (data ,(~r (/ (alt-cost start-alt repr) cost) #:precision '(= 1)) "×") - " speedup") - ,dropdown - ,(render-help "report.html#alternatives")) - ,body - (details (summary "Derivation") (ol ((class "history")) ,@history)))) - ,@(for/list ([i (in-naturals 1)] - [target (in-list targets)] - [target-error (in-list list-target-error)] - [target-cost (in-list list-target-cost)]) - (let-values ([(dropdown body) - (render-program (alt-expr (alt-analysis-alt target)) ctx #:ident identifier)]) - `(section - ([id ,(format "target~a" i)] (class "programs")) - (h2 "Developer Target " - ,(~a i) - ": " - (span ((class "subhead")) - (data ,(format-accuracy (errors-score target-error) repr-bits #:unit "%")) - " accurate, " - (data ,(~r (/ (alt-cost start-alt repr) target-cost) #:precision '(= 1)) "×") - " speedup") - ,dropdown - ,(render-help "report.html#target")) - ,body))) - ,(render-reproduction test))) - out)) + ,body + (details (summary "Derivation") (ol ((class "history")) ,@history)))) + ,@(for/list ([i (in-naturals 1)] + [target (in-list targets)] + [target-error (in-list list-target-error)] + [target-cost (in-list list-target-cost)]) + (let-values ([(dropdown body) + (render-program (alt-expr (alt-analysis-alt target)) ctx #:ident identifier)]) + `(section + ([id ,(format "target~a" i)] (class "programs")) + (h2 "Developer Target " + ,(~a i) + ": " + (span ((class "subhead")) + (data ,(format-accuracy (errors-score target-error) repr-bits #:unit "%")) + " accurate, " + (data ,(~r (/ (alt-cost start-alt repr) target-cost) #:precision '(= 1)) "×") + " speedup") + ,dropdown + ,(render-help "report.html#target")) + ,body))) + ,(render-reproduction test)))) diff --git a/src/reports/pages.rkt b/src/reports/pages.rkt index 30310a77b..3f9299b7d 100644 --- a/src/reports/pages.rkt +++ b/src/reports/pages.rkt @@ -5,7 +5,8 @@ "timeline.rkt" "plot.rkt" "make-graph.rkt" - "traceback.rkt") + "traceback.rkt" + "common.rkt") (provide all-pages make-page @@ -32,29 +33,26 @@ (define (make-page page out result-hash output? profile?) (match page - ["graph.html" (make-graph-html out result-hash output? profile?)] - ["timeline.html" (make-timeline-html out result-hash)] - ["timeline.json" (make-timeline-json out result-hash)] - ["points.json" (make-points out result-hash)])) + ["graph.html" (write-html (make-graph-html result-hash output? profile?) out)] + ["timeline.html" (write-html (make-timeline-html result-hash) out)] + ["timeline.json" (write-json (make-timeline-json result-hash) out)] + ["points.json" (write-json (make-points-json result-hash) out)])) -(define (make-graph-html out result-hash output? profile?) +(define (make-graph-html result-hash output? profile?) (define status (hash-ref result-hash 'status)) (match status ['success (define command (hash-ref result-hash 'command)) (match command - ["improve" (make-graph result-hash out output? profile?)] - [else (dummy-graph command out)])] - ['timeout (make-traceback result-hash out)] - ['failure (make-traceback result-hash out)] + ["improve" (make-graph result-hash output? profile?)] + [else (dummy-graph command)])] + ['timeout (make-traceback result-hash)] + ['failure (make-traceback result-hash)] [_ (error 'make-page "unknown result type ~a" status)])) -(define (make-points out result-hash) - (write-json (make-points-json result-hash) out)) +(define (make-timeline-json result-hash) + (hash-ref result-hash 'timeline)) -(define (make-timeline-json out result-hash) - (write-json (hash-ref result-hash 'timeline) out)) - -(define (make-timeline-html out result-hash) +(define (make-timeline-html result-hash) (define test (hash-ref result-hash 'test)) - (make-timeline (test-name test) (hash-ref result-hash 'timeline) out #:path "..")) + (make-timeline (test-name test) (hash-ref result-hash 'timeline) #:path "..")) diff --git a/src/reports/plot.rkt b/src/reports/plot.rkt index 928b809e9..f91bdb4fd 100644 --- a/src/reports/plot.rkt +++ b/src/reports/plot.rkt @@ -2,12 +2,11 @@ (require math/bigfloat math/flonum) -(require "../utils/common.rkt" +(require "../core/points.rkt" "../utils/float.rkt" "../core/programs.rkt" "../syntax/types.rkt" - "../syntax/syntax.rkt" "../syntax/read.rkt" "../utils/alternative.rkt" "../core/bsearch.rkt" @@ -105,12 +104,18 @@ ; bits of error for the output on each point ; ticks: array of size n where each entry is 13 or so tick values as [ordinal, string] pairs ; splitpoints: array with the ordinal splitpoints - `#hasheq((bits . ,bits) - (vars . ,(map symbol->string vars)) - (points . ,json-points) - (error . ,error-entries) - (ticks_by_varidx . ,ticks) - (splitpoints_by_varidx . ,splitpoints))) + (hasheq 'bits + bits + 'vars + (map symbol->string vars) + 'points + json-points + 'error + error-entries + 'ticks_by_varidx + ticks + 'splitpoints_by_varidx + splitpoints)) ;; Repr conversions diff --git a/src/reports/timeline.rkt b/src/reports/timeline.rkt index 63bc37b15..bf3cc3e27 100644 --- a/src/reports/timeline.rkt +++ b/src/reports/timeline.rkt @@ -15,20 +15,18 @@ ;; This first part handles timelines for a single Herbie run -(define (make-timeline name timeline out #:info [info #f] #:path [path "."]) - (write-html - `(html (head (meta ([charset "utf-8"])) - (title "Metrics for " ,(~a name)) - (link ([rel "stylesheet"] [type "text/css"] - [href ,(if info "report.css" "../report.css")])) - (script ([src ,(if info "report.js" "../report.js")]))) - (body ,(render-menu (~a name) - #:path path - (if info `(("Report" . "index.html")) `(("Details" . "graph.html")))) - ,(if info (render-about info) "") - ,(render-timeline timeline) - ,(render-profile))) - out)) +(define (make-timeline name timeline #:info [info #f] #:path [path "."]) + `(html (head (meta ([charset "utf-8"])) + (title "Metrics for " ,(~a name)) + (link ([rel "stylesheet"] [type "text/css"] + [href ,(if info "report.css" "../report.css")])) + (script ([src ,(if info "report.js" "../report.js")]))) + (body ,(render-menu (~a name) + #:path path + (if info `(("Report" . "index.html")) `(("Details" . "graph.html")))) + ,(if info (render-about info) "") + ,(render-timeline timeline) + ,(render-profile)))) (define/contract (render-timeline timeline) (-> timeline? xexpr?) diff --git a/src/reports/traceback.rkt b/src/reports/traceback.rkt index 17ccc2df5..90c174b06 100644 --- a/src/reports/traceback.rkt +++ b/src/reports/traceback.rkt @@ -7,13 +7,13 @@ (provide make-traceback) -(define (make-traceback result-hash out) +(define (make-traceback result-hash) (match (hash-ref result-hash 'status) - ['timeout (render-timeout result-hash out)] - ['failure (render-failure result-hash out)] + ['timeout (render-timeout result-hash)] + ['failure (render-failure result-hash)] [status (error 'make-traceback "unexpected status ~a" status)])) -(define (render-failure result-hash out) +(define (render-failure result-hash) (define test (hash-ref result-hash 'test)) (define warnings (hash-ref result-hash 'warnings)) (define backend (hash-ref result-hash 'backend)) @@ -21,27 +21,25 @@ ; unpack the exception (match-define (list 'exn type msg url extra traceback) backend) - (write-html - `(html - (head (meta ((charset "utf-8"))) - (title "Exception for " ,(~a (test-name test))) - (link ((rel "stylesheet") (type "text/css") (href "../report.css"))) - ,@js-tex-include - (script ([src "../report.js"]))) - (body ,(render-menu (~a (test-name test)) - (list '("Report" . "../index.html") '("Metrics" . "timeline.html"))) - ,(render-warnings warnings) - ,(render-specification test) - ,(if type - `(section ([id "user-error"] (class "error")) - (h2 ,(~a msg) " " (a ([href ,url]) "(more)")) - ,(if (eq? type 'syntax) (render-syntax-errors msg extra) "")) - "") - ,(if type - "" - `(,@(render-reproduction test #:bug? #t) - (section ([id "backtrace"]) (h2 "Backtrace") ,(render-traceback msg traceback)))))) - out)) + `(html + (head (meta ((charset "utf-8"))) + (title "Exception for " ,(~a (test-name test))) + (link ((rel "stylesheet") (type "text/css") (href "../report.css"))) + ,@js-tex-include + (script ([src "../report.js"]))) + (body ,(render-menu (~a (test-name test)) + (list '("Report" . "../index.html") '("Metrics" . "timeline.html"))) + ,(render-warnings warnings) + ,(render-specification test) + ,(if type + `(section ([id "user-error"] (class "error")) + (h2 ,(~a msg) " " (a ([href ,url]) "(more)")) + ,(if (eq? type 'syntax) (render-syntax-errors msg extra) "")) + "") + ,(if type + "" + `(,@(render-reproduction test #:bug? #t) + (section ([id "backtrace"]) (h2 "Backtrace") ,(render-traceback msg traceback))))))) (define (render-syntax-errors msg locations) `(table (thead (th ([colspan "2"]) ,msg) (th "L") (th "C")) @@ -63,22 +61,20 @@ `(tr (td ((class "procedure")) ,(~a name)) (td ,(~a file)) (td ,(~a line)) (td ,(~a col)))] [#f `(tr (td ((class "procedure")) ,(~a name)) (td ([colspan "3"]) "unknown"))]))))) -(define (render-timeout result-hash out) +(define (render-timeout result-hash) (define test (hash-ref result-hash 'test)) (define time (hash-ref result-hash 'time)) (define warnings (hash-ref result-hash 'warnings)) - (write-html - `(html (head (meta ((charset "utf-8"))) - (title "Exception for " ,(~a (test-name test))) - (link ((rel "stylesheet") (type "text/css") (href "../report.css"))) - ,@js-tex-include - (script ([src "../report.js"]))) - (body ,(render-menu (~a (test-name test)) - (list '("Report" . "../index.html") '("Metrics" . "timeline.html"))) - ,(render-warnings warnings) - ,(render-specification test) - (section ([id "user-error"] (class "error")) - (h2 "Timeout after " ,(format-time time)) - (p "Use the " (code "--timeout") " flag to change the timeout.")))) - out)) + `(html (head (meta ((charset "utf-8"))) + (title "Exception for " ,(~a (test-name test))) + (link ((rel "stylesheet") (type "text/css") (href "../report.css"))) + ,@js-tex-include + (script ([src "../report.js"]))) + (body ,(render-menu (~a (test-name test)) + (list '("Report" . "../index.html") '("Metrics" . "timeline.html"))) + ,(render-warnings warnings) + ,(render-specification test) + (section ([id "user-error"] (class "error")) + (h2 "Timeout after " ,(format-time time)) + (p "Use the " (code "--timeout") " flag to change the timeout."))))) From 5cc08c50a13c35871e75d1a34cc97c7d54cbf4ea Mon Sep 17 00:00:00 2001 From: zane <39070793+zaneenders@users.noreply.github.com> Date: Thu, 22 Aug 2024 11:14:19 -0600 Subject: [PATCH 3/5] Move generate-page to server.rkt --- src/api/demo.rkt | 41 +++------------------------------- src/api/server.rkt | 52 ++++++++++++++++++++++++++++++++++++++++++- src/reports/pages.rkt | 17 ++++++-------- src/reports/plot.rkt | 3 +-- 4 files changed, 62 insertions(+), 51 deletions(-) diff --git a/src/api/demo.rkt b/src/api/demo.rkt index b945c38a1..406e562a1 100644 --- a/src/api/demo.rkt +++ b/src/api/demo.rkt @@ -18,8 +18,7 @@ "../config.rkt" "../syntax/read.rkt" "../utils/errors.rkt") -(require - "../syntax/sugar.rkt" +(require "../syntax/sugar.rkt" "../core/points.rkt" "../api/sandbox.rkt") (require "datafile.rkt" @@ -30,9 +29,7 @@ (provide run-demo) -(define *demo?* (make-parameter false)) (define *demo-prefix* (make-parameter "/")) -(define *demo-output* (make-parameter false)) (define *demo-log* (make-parameter false)) (define (add-prefix url) @@ -71,41 +68,9 @@ [("results.json") generate-report])) (define (generate-page req result-hash page) - (define path (first (string-split (url->string (request-uri req)) "/"))) + ; TODO pass in job-id instead of job-results (cond - [(set-member? (all-pages result-hash) page) - ;; Write page contents to disk - (when (*demo-output*) - (make-directory (build-path (*demo-output*) path)) - (for ([page (all-pages result-hash)]) - (call-with-output-file - (build-path (*demo-output*) path page) - (λ (out) - (with-handlers ([exn:fail? (page-error-handler result-hash page out)]) - (make-page page out result-hash (*demo-output*) #f))))) - (define link (path-element->string (last (explode-path path)))) - (define data (get-table-data-from-hash result-hash link)) - (define data-file (build-path (*demo-output*) "results.json")) - (define html-file (build-path (*demo-output*) "index.html")) - (define info - (if (file-exists? data-file) - (let ([info (read-datafile data-file)]) - (struct-copy report-info info [tests (cons data (report-info-tests info))])) - (make-report-info (list data) - #:seed (get-seed) - #:note (if (*demo?*) "Web demo results" "")))) - (define tmp-file (build-path (*demo-output*) "results.tmp")) - (write-datafile tmp-file info) - (rename-file-or-directory tmp-file data-file #t) - (copy-file (web-resource "report.html") html-file #t)) - (response 200 - #"OK" - (current-seconds) - #"text" - (list (header #"X-Job-Count" (string->bytes/utf-8 (~a (job-count))))) - (λ (out) - (with-handlers ([exn:fail? (page-error-handler result-hash page out)]) - (make-page page out result-hash (*demo-output*) #f))))] + [(check-and-send req page)] [else (next-dispatcher)])) (define (generate-report req) diff --git a/src/api/server.rkt b/src/api/server.rkt index b0d619c15..9fdea5e34 100644 --- a/src/api/server.rkt +++ b/src/api/server.rkt @@ -3,6 +3,8 @@ (require openssl/sha1) (require (only-in xml write-xexpr) json) +(require net/url) +(require web-server/http) (require "sandbox.rkt" "../core/points.rkt" @@ -17,6 +19,8 @@ "../utils/common.rkt" "../utils/errors.rkt" "../utils/float.rkt" + "../reports/pages.rkt" + "datafile.rkt" (submod "../utils/timeline.rkt" debug)) (provide make-path @@ -29,7 +33,13 @@ create-job start-job wait-for-job - start-job-server) + start-job-server + check-and-send + *demo?* + *demo-output*) + +(define *demo?* (make-parameter false)) +(define *demo-output* (make-parameter false)) ; verbose logging for debugging (define verbose #f) ; Maybe change to log-level and use 'verbose? @@ -50,6 +60,46 @@ #:timeline-disabled? [timeline-disabled? #f]) (herbie-command command test seed pcontext profile? timeline-disabled?)) +(define (check-and-send req page) + (define path (first (string-split (url->string (request-uri req)) "/"))) + (define job-id (first (string-split path "."))) + (define result-hash (get-results-for job-id)) + (cond + [(set-member? (all-pages result-hash) page) + ;; Write page contents to disk + (when (*demo-output*) + (write-results-to-disk result-hash path)) + (response 200 + #"OK" + (current-seconds) + #"text" + (list (header #"X-Job-Count" (string->bytes/utf-8 (~a (job-count))))) + (λ (out) + (with-handlers ([exn:fail? (page-error-handler result-hash page out)]) + (make-page page out result-hash (*demo-output*) #f))))] + [else #f])) + +(define (write-results-to-disk result-hash path) + (make-directory (build-path (*demo-output*) path)) + (for ([page (all-pages result-hash)]) + (call-with-output-file (build-path (*demo-output*) path page) + (λ (out) + (with-handlers ([exn:fail? (page-error-handler result-hash page out)]) + (make-page page out result-hash (*demo-output*) #f))))) + (define link (path-element->string (last (explode-path path)))) + (define data (get-table-data-from-hash result-hash link)) + (define data-file (build-path (*demo-output*) "results.json")) + (define html-file (build-path (*demo-output*) "index.html")) + (define info + (if (file-exists? data-file) + (let ([info (read-datafile data-file)]) + (struct-copy report-info info [tests (cons data (report-info-tests info))])) + (make-report-info (list data) #:seed (get-seed) #:note (if (*demo?*) "Web demo results" "")))) + (define tmp-file (build-path (*demo-output*) "results.tmp")) + (write-datafile tmp-file info) + (rename-file-or-directory tmp-file data-file #t) + (copy-file (web-resource "report.html") html-file #t)) + ; computes the path used for server URLs (define (make-path id) (format "~a.~a" id *herbie-commit*)) diff --git a/src/reports/pages.rkt b/src/reports/pages.rkt index 3f9299b7d..5939b5bbe 100644 --- a/src/reports/pages.rkt +++ b/src/reports/pages.rkt @@ -34,8 +34,12 @@ (define (make-page page out result-hash output? profile?) (match page ["graph.html" (write-html (make-graph-html result-hash output? profile?) out)] - ["timeline.html" (write-html (make-timeline-html result-hash) out)] - ["timeline.json" (write-json (make-timeline-json result-hash) out)] + ["timeline.html" + (write-html (make-timeline (test-name (hash-ref result-hash 'test)) + (hash-ref result-hash 'timeline) + #:path "..") + out)] + ["timeline.json" (write-json (hash-ref result-hash 'timeline) out)] ["points.json" (write-json (make-points-json result-hash) out)])) (define (make-graph-html result-hash output? profile?) @@ -48,11 +52,4 @@ [else (dummy-graph command)])] ['timeout (make-traceback result-hash)] ['failure (make-traceback result-hash)] - [_ (error 'make-page "unknown result type ~a" status)])) - -(define (make-timeline-json result-hash) - (hash-ref result-hash 'timeline)) - -(define (make-timeline-html result-hash) - (define test (hash-ref result-hash 'test)) - (make-timeline (test-name test) (hash-ref result-hash 'timeline) #:path "..")) + [_ (error 'make-graph-html "unknown result type ~a" status)])) diff --git a/src/reports/plot.rkt b/src/reports/plot.rkt index f91bdb4fd..5488e88f5 100644 --- a/src/reports/plot.rkt +++ b/src/reports/plot.rkt @@ -2,8 +2,7 @@ (require math/bigfloat math/flonum) -(require - "../core/points.rkt" +(require "../core/points.rkt" "../utils/float.rkt" "../core/programs.rkt" "../syntax/types.rkt" From f7673ddec05928c52aa929a3be17c9dd47b5d131 Mon Sep 17 00:00:00 2001 From: zane <39070793+zaneenders@users.noreply.github.com> Date: Thu, 22 Aug 2024 11:26:07 -0600 Subject: [PATCH 4/5] Add server-check-on function. --- src/api/demo.rkt | 10 +++++----- src/api/server.rkt | 15 ++++++++++++--- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/api/demo.rkt b/src/api/demo.rkt index 406e562a1..4b39079e3 100644 --- a/src/api/demo.rkt +++ b/src/api/demo.rkt @@ -41,9 +41,9 @@ (and (not (and (*demo-output*) ; If we've already saved to disk, skip this job (directory-exists? (build-path (*demo-output*) x)))) (let ([m (regexp-match #rx"^([0-9a-f]+)\\.[0-9a-f.]+" x)]) - (and m (get-results-for (second m)))))) + (and m (server-check-on (second m)))))) (λ (x) - (let ([m (regexp-match #rx"^([0-9a-f]+)\\.[0-9a-f.]+" x)]) (get-results-for (if m (second m) x))))) + (let ([m (regexp-match #rx"^([0-9a-f]+)\\.[0-9a-f.]+" x)]) (server-check-on (if m (second m) x))))) (define-bidi-match-expander hash-arg hash-arg/m hash-arg/m) @@ -67,10 +67,10 @@ [((hash-arg) (string-arg)) generate-page] [("results.json") generate-report])) -(define (generate-page req result-hash page) - ; TODO pass in job-id instead of job-results +(define (generate-page req job-id page) + (define path (first (string-split (url->string (request-uri req)) "/"))) (cond - [(check-and-send req page)] + [(check-and-send path job-id page)] [else (next-dispatcher)])) (define (generate-report req) diff --git a/src/api/server.rkt b/src/api/server.rkt index 9fdea5e34..ead92475b 100644 --- a/src/api/server.rkt +++ b/src/api/server.rkt @@ -26,6 +26,7 @@ (provide make-path get-improve-table-data make-improve-result + server-check-on get-results-for get-timeline-for job-count @@ -60,9 +61,8 @@ #:timeline-disabled? [timeline-disabled? #f]) (herbie-command command test seed pcontext profile? timeline-disabled?)) -(define (check-and-send req page) - (define path (first (string-split (url->string (request-uri req)) "/"))) - (define job-id (first (string-split path "."))) +;; TODO move these side worker/manager +(define (check-and-send path job-id page) (define result-hash (get-results-for job-id)) (cond [(set-member? (all-pages result-hash) page) @@ -117,6 +117,13 @@ (log "Getting timeline for job: ~a.\n" job-id) (place-channel-get a)) +; Returns #f if there is no job returns the job-id if there is a completed job. +(define (server-check-on job-id) + (define-values (a b) (place-channel)) + (place-channel-put manager (list 'check job-id b)) + (log "Checking on: ~a.\n" job-id) + (place-channel-get a)) + (define (get-improve-table-data) (define-values (a b) (place-channel)) (place-channel-put manager (list 'improve b)) @@ -301,6 +308,8 @@ [else (log "Job complete, no timeline, send result.\n") (place-channel-put handler (hash-ref completed-work job-id #f))])] + [(list 'check job-id handler) + (place-channel-put handler (if (hash-has-key? completed-work job-id) job-id #f))] ; Returns the current count of working workers. [(list 'count handler) (place-channel-put handler (hash-count busy-workers))] ; Retreive the improve results for results.json From a5290d669d995517ffc8dbb243f619be40d869ca Mon Sep 17 00:00:00 2001 From: zane <39070793+zaneenders@users.noreply.github.com> Date: Tue, 27 Aug 2024 10:25:16 -0600 Subject: [PATCH 5/5] Fix make-timeline call sites. --- infra/merge.rkt | 6 ++++-- src/api/run.rkt | 10 ++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/infra/merge.rkt b/infra/merge.rkt index 9498e58cb..c68d93a8c 100644 --- a/infra/merge.rkt +++ b/infra/merge.rkt @@ -5,7 +5,8 @@ "../src/utils/profile.rkt" "../src/api/datafile.rkt" "../src/reports/timeline.rkt" - "../src/syntax/load-plugin.rkt") + "../src/syntax/load-plugin.rkt" + "../src/reports/common.rkt") (define (merge-timelines outdir . dirs) (define tls @@ -21,7 +22,8 @@ (curry write-json joint-tl)) (call-with-output-file (build-path outdir "timeline.html") #:exists 'replace - (λ (out) (make-timeline "Herbie run" joint-tl out #:info info)))) + (λ (out) + (write-html (make-timeline "Herbie run" joint-tl #:info info) out)))) (define (merge-profiles outdir . dirs) (define pfs diff --git a/src/api/run.rkt b/src/api/run.rkt index 7d9b6f4a0..25a0f8190 100644 --- a/src/api/run.rkt +++ b/src/api/run.rkt @@ -11,7 +11,8 @@ "../core/sampling.rkt" "../reports/pages.rkt" "thread-pool.rkt" - "../reports/timeline.rkt") + "../reports/timeline.rkt" + "../reports/common.rkt") (provide make-report rerun-report @@ -84,9 +85,10 @@ (define profile (merge-profile-jsons (read-json-files info dir "profile.json"))) (call-with-output-file (build-path dir "profile.json") (curry write-json profile) #:exists 'replace) - (call-with-output-file (build-path dir "timeline.html") - #:exists 'replace - (λ (out) (make-timeline "Herbie run" timeline out #:info info #:path "."))) + (call-with-output-file + (build-path dir "timeline.html") + #:exists 'replace + (λ (out) (write-html (make-timeline "Herbie run" timeline #:info info #:path ".") out))) ; Delete old files (let* ([expected-dirs (map string->path