From 3642fd69714d67428295747142f390f2a4621621 Mon Sep 17 00:00:00 2001 From: iambrj Date: Wed, 6 Sep 2023 22:59:36 +0530 Subject: [PATCH] Add RAP chapters 1-2 --- rap/2.ml | 15 ++++++++++++ rap/README.md | 59 +++++++++++++++++++++++++++++++++++++++++++++++ rap/power_rts.ml | 6 +++++ rap/square.cmi | Bin 0 -> 331 bytes rap/square.cmo | Bin 0 -> 228 bytes rap/square.ml | 2 ++ 6 files changed, 82 insertions(+) create mode 100644 rap/2.ml create mode 100644 rap/README.md create mode 100644 rap/power_rts.ml create mode 100644 rap/square.cmi create mode 100644 rap/square.cmo create mode 100644 rap/square.ml diff --git a/rap/2.ml b/rap/2.ml new file mode 100644 index 0000000..0d3c2d8 --- /dev/null +++ b/rap/2.ml @@ -0,0 +1,15 @@ +let c = .<1 + 2>.;; + +let rec power n x = + if n == 0 then 1 + else if n mod 2 == 0 + then square (power (n / 2) x) + else x * (power (n - 1) x);; + +let rec spower n x = + if n == 0 then .<1>. + else if n mod 2 == 0 + then .. + else .<.~x * .~(spower (n - 1) x)>.;; + +let spowern = fun n -> . .~(spower n ..)>.;; diff --git a/rap/README.md b/rap/README.md new file mode 100644 index 0000000..30d401a --- /dev/null +++ b/rap/README.md @@ -0,0 +1,59 @@ +--- +fontfamily: mathpazo +title: "Notes on Oleg's Reconciling Abstraction with High Performance" +author: 'iambrj' +date: '06-09-2023' +header-includes: + - \hypersetup{colorlinks=true, urlcolor=blue} +--- +- The promise: we can have high performance code AND still write it using + high-level abstractions; i.e. abstraction without guilt. +- MetaOCaml is purely generative: it can generate code, but not break apart and + examine it. + +# First Steps +- Wrapping OCaml code in brackets, `.< code >.`, produces a *code value*. It is + just like any other value -- it can be bound to variables, passed as + arguments, and returned from functions. +- Wrapping OCaml code in brackets quotes the code, annotating it as computed + later. +- As a first approximation, a code value can be thought of as an OCaml AST that + other OCaml code can work with. +- An expression `e` of type `t` when quoted using brackets produces a code value + of type `t code`. +- The other annotation MetaOCaml introduces is *escape* `.~`, which can only be + used inside brackets. Escape an expression `.~e` unquotes `e`. +- `.~e` says that `e` is computed now but produces the code to run later ("now" + meaning the point where the escape is used and "later" meaning the surrounding + brackets). +- We can abstract over the escape expression: +``` +let genTimes10 x = .<.~x * 10>.;; +=> val genTimes10 : int code -> int code = +``` +i.e. `genTimes10` is a function that produces a code value, i.e. `genTimes10` is +a *code generator*. `genTimes10` takes a code value as an argument too. +- The code inside brackets is also type checked. The type-checker rejects code + that *may* produce ill-typed code. A well-typed generator generates only + well-typed code. +- Computation is divided into (any number of) *stages*. A *now stage*, for + values which are known and can be computed and a *later stage*, for values + which are not known and computation involving them is deferred to the future. +- CSP: Cross-stage Persistence. Functions that persist across changes, i.e. + functions that are defined now and can always be used in the future. +- `Runcode.run: x code -> x` can be used to run any generated code. It invokes + the compiler, performs linking, runs the resulting program, and returns the + value of the program. It must be emphasized that *run invokes the compiler at + runtime*. +- Two key takeaways: + 1. A code value can represent open code. + 2. MetaOCaml can be used for both runtime specialization (i.e. specializing + a function for frequently used inputs for example) and offline + generation of specialized library code. +TODO: try to re-read the recap section and meditate on it to understand better +what is being said. + +# Misc +``` +eval $(opam env --switch=4.14.1+BER) +``` diff --git a/rap/power_rts.ml b/rap/power_rts.ml new file mode 100644 index 0000000..8d9da8e --- /dev/null +++ b/rap/power_rts.ml @@ -0,0 +1,6 @@ +let perf : (unit -> a) -> a = fun th -> + let start_time = Sys.time() in + let r = th () in + let elapsed_time = Sys.time() - start_time in + Printf.printf "\nit took %g secs\n" elapsed_time; + r diff --git a/rap/square.cmi b/rap/square.cmi new file mode 100644 index 0000000000000000000000000000000000000000..d288330ca98097d60e220cc496c71da40afae192 GIT binary patch literal 331 zcmZ=x%*`>hw6ydzFg9$Nx@;c<1H)_}RtMrvAZ}iu7F<}GSd_Y8!veKpFpH6q@4|tD z4hJ?*Sgf3xSK{a}!GVeO>q7zi1?3rF)GKcvzl}Mf}~1Pax#-97*uX}d3oFS ze;4XDpV8VqO?u*j1s2Xg7XW>eT9lWVhw6yd$Fg9dhUkL69>o`wcx_i#G=#y2A2g3CQV{tWpHpxC^xahDX};+xp;y>e}A%TL}lL-j{7zNOM_>NI)DKH0+&B4 literal 0 HcmV?d00001 diff --git a/rap/square.ml b/rap/square.ml new file mode 100644 index 0000000..ea426c4 --- /dev/null +++ b/rap/square.ml @@ -0,0 +1,2 @@ +let square x = x * x;; +