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

Reduce loading time #116

Merged
merged 14 commits into from
Aug 28, 2023
Merged

Reduce loading time #116

merged 14 commits into from
Aug 28, 2023

Conversation

mitschabaude
Copy link
Collaborator

@mitschabaude mitschabaude commented Aug 16, 2023

@mitschabaude mitschabaude marked this pull request as ready for review August 18, 2023 01:25
@mitschabaude mitschabaude requested a review from a team as a code owner August 18, 2023 01:25
Copy link
Collaborator Author

@mitschabaude mitschabaude left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some explanations for reviewers!

};

// this is put in a global variable so that ../kimchi/js/bindings.js finds it
(globalThis as any).__snarkyTsBindings = tsBindings;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is the new TS bindings file, explained here

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Depending how you feel on comments, you could argue the explanation could be added here, mostly just elaborating on the inline comment you have already. Could be helpful for others look at this file and wondering more, wdyt?

"17890046087060600378523962727948914890955845280331606421027576706277370812052",
"2013454333407534591106411126192774509000627947643864003868625362325108814274",
"11843535353803037930790320689348405921362689396018494249827525941843824404081"
],
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hard-coded hashes exposed to jsoo via the new TS bindings. we hard-code them to avoid computing them at the top level

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: If we could throw some inline comments when this (or similar) file(s) is generated that point to the OCaml file, it would really help context for other developers if debugging or adding features in this area.

Comment on lines +7 to +14
// Provides: tsBindings
var tsBindings = globalThis.__snarkyTsBindings;

// Provides: getTsBindings
// Requires: tsBindings
function getTsBindings() {
return tsBindings;
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

expose new bindings file to jsoo

Comment on lines +38 to +43
let prefix_hashes =
let open Hash_prefixes in
`Assoc
(List.map ~f:(prefix_hash_entry Kimchi)
[ (receipt_chain_user_command :> string)
; (receipt_chain_zkapp :> string)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these changes are about computing some hashes at compile time and put them in the constants.ts file

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A great addition! Just wondering, is there any documentation that links these constants to this file? Going through some READMEs and I don't see an explicit mention of this. I think it would really help with we could point to a piece of documentation that establishes this sort of generation. Doesn't have to be in this PR but even inline comments would help. Wdyt?


async function initSnarkyJS() {
const memory = allocateWasmMemoryForUserAgent(navigator.userAgent);
await init(undefined, memory);

let module = init.__wbindgen_wasm_module;
let numWorkers = await getEfficientNumWorkers();
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

change 1 to this file: we don't call getEfficientNumWorkers() right away, because it's very expensive (inspects the device GPU via WebGL). Instead, we call it before we need workers the first time, which is likely a slow operation anyway

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great optimization! Great for cases where we only need constants since that can all be done in JS, right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes!


worker = inlineWorker(srcFromFunctionModule(mainWorker));
await workerCall(worker, 'start', { memory, module, numWorkers });
globalThis.plonk_wasm = overrideBindings(wasm, worker);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

change 2 to this file: creating the main worker and waiting for its promise to return (which is after all its child workers are started) is very slow. Therefore, we do this in a way that is not blocking our top-level await. This is fine, the main worker will only be needed when we do our first expensive operation and we await the promise at that time

Account_update.Graphql_repr.deriver @@ Fields_derivers_zkapps.Derivers.o ()
lazy
( Account_update.Graphql_repr.deriver
@@ Fields_derivers_zkapps.Derivers.o () )
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we compute a bunch of stuff lazily in consistency_test.ml and local_ledger.ml which was computed at the top level before

Sponge.Params.(
map pasta_p_kimchi
~f:(Fn.compose Impl.Field.constant Impl.Field.Constant.of_string))
let sponge_params = Kimchi_pasta_basic.poseidon_params_fp
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't recompute stuff that is computed in elsewhere already

Copy link
Contributor

@MartinMinkov MartinMinkov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great use of lazy and compiling prefixes ahead of time instead of hitting runtime cost!

I mostly just had comments about documentation, feel free to address or make issues for later

Comment on lines +38 to +43
let prefix_hashes =
let open Hash_prefixes in
`Assoc
(List.map ~f:(prefix_hash_entry Kimchi)
[ (receipt_chain_user_command :> string)
; (receipt_chain_zkapp :> string)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A great addition! Just wondering, is there any documentation that links these constants to this file? Going through some READMEs and I don't see an explicit mention of this. I think it would really help with we could point to a piece of documentation that establishes this sort of generation. Doesn't have to be in this PR but even inline comments would help. Wdyt?


async function initSnarkyJS() {
const memory = allocateWasmMemoryForUserAgent(navigator.userAgent);
await init(undefined, memory);

let module = init.__wbindgen_wasm_module;
let numWorkers = await getEfficientNumWorkers();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great optimization! Great for cases where we only need constants since that can all be done in JS, right?

"17890046087060600378523962727948914890955845280331606421027576706277370812052",
"2013454333407534591106411126192774509000627947643864003868625362325108814274",
"11843535353803037930790320689348405921362689396018494249827525941843824404081"
],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: If we could throw some inline comments when this (or similar) file(s) is generated that point to the OCaml file, it would really help context for other developers if debugging or adding features in this area.

};

// this is put in a global variable so that ../kimchi/js/bindings.js finds it
(globalThis as any).__snarkyTsBindings = tsBindings;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Depending how you feel on comments, you could argue the explanation could be added here, mostly just elaborating on the inline comment you have already. Could be helpful for others look at this file and wondering more, wdyt?

@@ -72,6 +72,7 @@
(libraries
mina_base
core_kernel
base
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you know how much base impacts the size? is it a lot? 🤔 i wonder how smart JSOO handles these things

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general terms, jsoo does proper tree-shaking, but often OCaml modules contain methods that aren't used and those (I believe) can't be compiled away, similar to if you'd populate a JS class with an unused method.

Concretely, this new import only affects the snarky_js_constants.exe executable which we don't even compile to JS. It's an OCaml script, which is run to print out the constants.ts file

@@ -58,6 +58,7 @@
;; js-specific overrides ;;
cache_dir.fake
digestif.ocaml
hash_prefix_create.js
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh you can just import js file like that :o

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no that's an ocaml library which is suffixed with .js lol

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh i was confused for a second! lol

@mitschabaude mitschabaude merged commit 549fd78 into main Aug 28, 2023
@mitschabaude mitschabaude deleted the perf/loading-time branch August 28, 2023 19:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants