Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modularize compiler around the idea of a "standard library" using functors #1182

Draft
wants to merge 42 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
7779be0
Start refactor
WardBrian Apr 27, 2022
1383260
Start parameterizing modules
WardBrian Apr 27, 2022
a913d4f
Finish modularizing
WardBrian Apr 27, 2022
5f0ac98
Trivially make stan math signatures comply to the new api
WardBrian Apr 27, 2022
1a3757f
Parametrize optimizer, unit tests passing
WardBrian Apr 27, 2022
c7f1b14
Variadic typechecking, details. Tests passing
WardBrian Apr 27, 2022
29d0bf7
Rename to avoid ambiguity with Core.Stdlib
WardBrian Apr 28, 2022
79acb81
Update Stancjs to use functors
WardBrian Apr 28, 2022
72a10fe
Cleanup, move some signatures to _intf files, capitalize module types
WardBrian Apr 28, 2022
0b69551
Clean up Stan_math_library, document
WardBrian Apr 28, 2022
d3db3e0
Comments
WardBrian Apr 28, 2022
30e6e13
Merge branch 'master' into modular-library-experiment
WardBrian May 12, 2022
dd4772f
Cleanups ported from virtual library attempt
WardBrian May 12, 2022
dad6788
Dune promote
WardBrian May 12, 2022
4ad727d
Merge branch 'master' into modular-library-experiment
WardBrian May 17, 2022
d2341ca
Merge branch 'master' into modular-library-experiment
WardBrian May 24, 2022
c89fa55
Merge branch 'master' into modular-library-experiment
WardBrian May 25, 2022
2efa144
Merge branch 'master' into modular-library-experiment
WardBrian May 26, 2022
9067d01
Merge branch 'master' into modular-library-experiment
WardBrian Jun 1, 2022
839103a
Merge branch 'master' into modular-library-experiment
WardBrian Jun 3, 2022
21e265d
Merge branch 'master' into modular-library-experiment
WardBrian Jun 13, 2022
f52a6f9
Merge branch 'master' into modular-library-experiment
WardBrian Jun 15, 2022
0dc4dfd
Merge branch 'master' into modular-library-experiment
WardBrian Jul 11, 2022
8ea3fd3
Merge branch 'master' into modular-library-experiment
WardBrian Jul 26, 2022
047704b
Merge branch 'master' into modular-library-experiment
WardBrian Sep 22, 2022
9d684d9
Empty commit
WardBrian Sep 23, 2022
87c4328
Merge branch 'master' into modular-library-experiment
WardBrian Oct 12, 2022
ef3079d
Merge branch 'master'
WardBrian Oct 14, 2022
e4d6872
Merge branch 'master' into refactor/library-functors
WardBrian Oct 24, 2022
32a66f0
Merge branch 'master' into refactor/library-functors
WardBrian Oct 24, 2022
7cbfd80
Merge branch 'master' into refactor/library-functors
WardBrian Nov 2, 2022
c88ea99
Merge branch 'master' into refactor/library-functors
WardBrian Nov 2, 2022
ee29f62
Merge branch 'master' into refactor/library-functors
WardBrian Nov 8, 2022
3d09b6c
Merge branch 'master' into refactor/library-functors
WardBrian Dec 12, 2022
7d26f5e
Merge branch 'master' into refactor/library-functors
WardBrian Dec 20, 2022
bdfd77e
Merge branch 'master' into refactor/library-functors
WardBrian Jan 18, 2023
bf3b302
Merge branch 'master' into refactor/library-functors
WardBrian Feb 16, 2023
a9af831
Merge branch 'master' into refactor/library-functors
WardBrian Mar 10, 2023
b4c9d4a
Merge branch 'master' into refactor/library-functors
WardBrian Mar 17, 2023
6ff32d1
Merge branch 'master' into refactor/library-functors
WardBrian Mar 29, 2023
0ec6964
Merge branch 'master' into refactor/library-functors
WardBrian Apr 12, 2023
3823560
Merge branch 'master' into refactor/library-functors
WardBrian May 9, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions docs/core_ideas.mld
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,31 @@ This takes some getting used to, and also can lead to some unhelpful type signat
VSCode, because abbreviations are not always used in hover-over text. For example, [Expr.Typed.t], the MIR's typed
expression type, actually has a signature of [Expr.Typed.Meta.t Expr.Fixed.t].

{1 The [Library] interface and functors}

Many modules of stanc are modeled as OCaml {{:https://ocaml.org/learn/tutorials/functors.html}functors},
which take in another module as input and produce a module as output. For the most part,
these functors expect an instance of the [Library] interface defined in
[src/frontend/Std_library_utils.ml].

This module primarily contains signatures for the Stan standard library. For most users,
you can assume this will be filled in with [src/stan_math_backend/Stan_math_library.ml],
the object representing the {{:https://github.com/stan-dev/math}stan-dev/math} C++ library.

Usages of these functors are rather simple, e.g. in the core stanc driver the line

{[
module Typechecker = Typechecking.Make (Stan_math_library)
]}

defines a module [Typechecker] by supplying the functor [Typechecking.Make] with
the Stan C++ library module. After this, [Typechecker.check_program] will typecheck
an AST against those specific functions.

As noted in the above tutorial link, the syntax of functors is often the hardest part
of using and understanding them. The functors which accept [Library] are all relatively
simple, and should serve as good examples to beginners with the concept.

{1 The [Fmt] library and pretty-printing}

We extensively use the {{:https://erratique.ch/software/fmt}Fmt} library for our pretty-printing and code
Expand Down
9 changes: 4 additions & 5 deletions docs/exposing_new_functions.mld
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
For a function to be built into Stan, it has to be included in the Stan Math library and its signature has to be
exposed to the compiler.

To do the latter, we have to add a corresponding line in [src/middle/Stan_math_signatures.ml].
To do the latter, we have to add a corresponding line in [src/stan_math_backend/Stan_math_library.ml].
The compiler uses the signatures defined there to do type checking.


Expand Down Expand Up @@ -127,15 +127,14 @@ For example, the following line defines the signature [add(real, matrix) => matr

{1 Higher-Order Variadic functions}

Functions such as the ODE integrators or [reduce_sum], which take in user-functions and a variable-length
list of arguments, are {b NOT} added to this list.

"Nice" variadic functions are added to the hashtable [Stan_math_signatures.stan_math_variadic_signatures].
"Nice" variadic functions are added to the hashtable [StdLibrary.variadic_signatures].
This is probably sufficient for most variadic functions, e.g. all the ODE solvers and DAE solvers are done
via this method.
[reduce_sum] is not "nice", since it is both variadic and {e polymorphic}, requiring certain arguments to have the same
(but {e not predetermined}) type. Therefore, [reduce_sum] is treated as special case in the [Typechecker]
module in the frontend folder.
module in the frontend folder. These are instead handled by special functions like [is_special_function_name]. They
must also be given custom typechecking rules in the private sub-module [Special_typechecking].

Note that higher-order functions also usually require changes to the C++ code generation to work properly.
It is best to consult an existing example of how these are done before proceeding.
Expand Down
9 changes: 6 additions & 3 deletions src/analysis_and_optimization/Debug_data_generation.ml
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
open Core_kernel
open Middle

module Partial_evaluator =
Partial_evaluation.Make (Frontend.Std_library_utils.NullLibrary)

let rec transpose = function
| [] :: _ -> []
| rows ->
let hd = List.map ~f:List.hd_exn rows in
let tl = List.map ~f:List.tl_exn rows in
hd :: transpose tl

let reject loc msg = raise (Partial_evaluator.Rejected (loc, msg))
let reject loc msg = raise (Partial_evaluation.Rejected (loc, msg))

let dotproduct xs ys =
List.fold2_exn xs ys ~init:0. ~f:(fun accum x y -> accum +. (x *. y))
Expand All @@ -32,7 +35,7 @@ let rec vect_to_mat l m =

let eval_expr m e =
let e = Mir_utils.subst_expr m e in
let e = Partial_evaluator.eval_expr e in
let e = Partial_evaluator.try_eval_expr e in
let rec strip_promotions (e : Middle.Expr.Typed.t) =
match e.pattern with Promotion (e, _, _) -> strip_promotions e | _ -> e
in
Expand Down Expand Up @@ -361,4 +364,4 @@ let gen_values_json_exn ?(new_only = false) ?(context = Map.Poly.empty) decls =

let gen_values_json ?(new_only = false) ?(context = Map.Poly.empty) decls =
try Ok (gen_values_json_exn ~new_only ~context decls)
with Partial_evaluator.Rejected (loc, msg) -> Error (loc, msg)
with Partial_evaluation.Rejected (loc, msg) -> Error (loc, msg)
7 changes: 3 additions & 4 deletions src/analysis_and_optimization/Dependence_analysis.ml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ open Middle
open Dataflow_types
open Mir_utils
open Dataflow_utils
open Monotone_framework_sigs
open Monotone_framework_intf
open Monotone_framework

(***********************************)
Expand Down Expand Up @@ -119,9 +119,8 @@ let mir_reaching_definitions (mir : Program.Typed.t) (stmt : Stmt.Located.t) :
Map.Poly.map rd_map ~f:(fun {entry; exit} ->
{entry= to_rd_set entry; exit= to_rd_set exit} )

let all_labels
(module Flowgraph : Monotone_framework_sigs.FLOWGRAPH with type labels = int)
: int Set.Poly.t =
let all_labels (module Flowgraph : FLOWGRAPH with type labels = int) :
int Set.Poly.t =
let step set =
Set.Poly.union set
(union_map set ~f:(fun l -> Map.Poly.find_exn Flowgraph.successors l))
Expand Down
Loading