.. _js-api:
JavaScript API Reference
========================
The :ref:`futhark-wasm(1)`, :ref:`futhark-wasm-multicore(1)`, and
:ref:`futhark-webgpu(1)` compilers can generate JavaScript wrapper code
when used with ``--library``. This chapter describes the API exposed by
those wrappers.
The exact generated files and the top-level JavaScript interface differ
somewhat between the WASM backend and the WebGPU backend, so the
relevant differences are described below.
First a warning: **the JavaScript API is experimental**. It may
change incompatibly even in minor versions of the compiler.
A Futhark program ``futlib.fut`` compiled with ``--library`` produces
generated C code as well as JavaScript-facing runtime files. Some of
these files are backend-specific.
For the WASM backend, a build typically produces:
* ``futlib.c``, ``futlib.h``: implementation and header C files
generated by the compiler, similar to ``futhark c``.
* ``futlib.class.js``: an intermediate JavaScript build artifact.
* ``futlib.wasm``: the compiled WebAssembly module, which must be
present at runtime.
* ``futlib.mjs``: an ES module that exports the JavaScript wrapper API.
For the WebGPU backend, a build typically produces:
* ``futlib.c``, ``futlib.h``: implementation and header C files
generated by the compiler.
* ``futlib.js``: the generated backend runtime module.
* ``futlib.wrapper.js``: the JavaScript wrapper that exposes the
Futhark-facing API.
* ``futlib.json``: manifest data used by the generated wrapper.
* ``futlib.wasm``: a generated WebAssembly artifact used by the runtime.
The exact file set is backend-dependent and may change over time.
The generated JavaScript wrapper exposes a ``FutharkModule`` class,
which is the preferred top-level interface for using a compiled Futhark
program from JavaScript. The module is initialised with the generated
backend runtime module.
The initialisation pattern is the same for the WASM-style backend and
the WebGPU backend. The only difference is how ``Module`` is made available.
For the WASM-style backend, the generated ``.mjs`` file exports it as the
default export, so it is imported together with ``FutharkModule``:
.. code-block:: javascript
import Module, { FutharkModule } from './futlib.mjs';
const module = await Module();
const fut = new FutharkModule();
await fut.init(module);
For the WebGPU backend, the generated runtime module is usually loaded
before the application code, for example:
.. code-block:: html
General concerns
----------------
Memory management is completely manual, as JavaScript does not support
finalizers that could let Futhark hook into the garbage collector.
You are responsible for eventually freeing all objects produced by the
API, using the appropriate methods.
Top-level wrapper objects
-------------------------
The preferred top-level JavaScript interface is ``FutharkModule``. A
``FutharkModule`` object represents an instance of a compiled Futhark
program. It owns the underlying Futhark context and is used to construct
arrays, call entry points, and free resources.
.. js:class:: FutharkModule()
A bookkeeping class representing an instance of a compiled Futhark
program.
.. js:function:: FutharkModule.init(module)
Asynchronously initialise the ``FutharkModule`` object.
For the WASM-style backend, the ``module`` argument is optional. If
omitted, the generated wrapper loads the WebAssembly module itself.
For the WebGPU backend, ``module`` must be the generated backend
runtime module.
.. js:function:: FutharkModule.free()
Frees the Futhark context and configuration associated with the
module. It is an error to use a ``FutharkArray`` or ``FutharkOpaque``
after the ``FutharkModule`` on which it was created has been freed.
.. js:attribute:: FutharkModule.entry
Object containing the generated entry point functions. For example,
an entry point named ``main`` is available as ``fut.entry.main``.
.. js:attribute:: FutharkModule.types
Object containing generated type information and array constructor
objects for the array types used by the program.
The backends also provides utility methods for synchronisation,
cache management, and profiling.
.. js:function:: FutharkModule.context_sync()
Wait for pending backend work associated with the context to finish.
.. js:function:: FutharkModule.clear_caches()
Clear backend caches associated with the context.
.. js:function:: FutharkModule.report()
Return a profiling report string.
.. js:function:: FutharkModule.pause_profiling()
Pause profiling.
.. js:function:: FutharkModule.unpause_profiling()
Resume profiling.
WASM compatibility interface
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The WASM-style backend also keep the older ``FutharkContext`` interface
for backwards compatibility.
.. js:function:: newFutharkContext()
Asynchronously create a new ``FutharkContext`` object.
.. js:class:: FutharkContext()
Backwards-compatible wrapper class for WASM-style backend.
``FutharkContext`` supports the same main interface as
``FutharkModule``, including ``entry``, ``types``, array constructors,
and ``free``.
New code should prefer ``FutharkModule``.
Values
------
Numeric types ``u8``, ``u16``, ``u32``, ``i8``, ``i16``, ``i32``, ``f16``,
``f32``, and ``f64`` are mapped to JavaScript's standard number type.
64-bit integers ``u64`` and ``i64`` are mapped to ``BigInt``. ``bool``
is mapped to JavaScript's ``boolean`` type. Arrays are represented by
``FutharkArray`` objects. Complex types (records, nested tuples, etc.)
are represented by ``FutharkOpaque`` objects.
FutharkArray
------------
Arrays are represented by ``FutharkArray`` objects. The common array API is
shared by the WASM backend and the WebGPU backend.
.. js:function:: FutharkArray.shape()
Returns the shape of the array as a ``BigInt64Array``.
.. js:function:: FutharkArray.values()
Asynchronously returns a flat typed array containing the array data.
.. js:function:: FutharkArray.free()
Frees the memory used by the ``FutharkArray``.
The WASM backend also provides a few older convenience methods.
.. js:function:: FutharkArray.toArray()
Returns a nested JavaScript array.
.. js:function:: FutharkArray.toTypedArray()
Returns a flat typed array of the underlying data.
.. js:function:: FutharkArray.shape()
Returns the shape of the ``FutharkArray`` as an array of ``BigInt`` values.
Array construction
~~~~~~~~~~~~~~~~~~
Each array type used by an entry point is exposed through a generated
constructor object. For example, for the type ``[]i32``:
.. js:function:: fut.i32_1d.from_data(data, dim0)
Creates and returns a one-dimensional ``i32`` ``FutharkArray`` from
a JavaScript ``Array`` or the corresponding typed array, with the
given shape.
For the WASM backend, the generated constructor object also
provides a convenience method for nested JavaScript arrays.
.. js:function:: fut.i32_1d.from_jsarray(jsarray)
Creates and returns a one-dimensional ``i32`` ``FutharkArray`` from
a JavaScript array. For higher-dimensional arrays, the JavaScript
array is expected to be nested according to the array rank.
FutharkOpaque
-------------
Complex types (records, nested tuples, etc) are represented by
``FutharkOpaque``. It has no use outside of being accepted and
returned by entry point functions. For this reason the method only has
one function for freeing the memory when ``FutharkOpaque`` is no
longer used.
.. js:function:: FutharkOpaque.free()
Frees memory used by FutharkOpaque. Should be called when Futhark
Opaque is no longer used.
Entry Points
------------
Each entry point in the compiled Futhark program is exposed through the
``entry`` field of the top-level wrapper object. For example, an entry
point named ``main`` can be called as:
.. code-block:: javascript
const res = await fut.entry.main(in1, ..., inN);
.. js:function:: fut.entry.(in1, ..., inN)
The entry point function takes the JavaScript representations of the
Futhark entry point arguments and returns the result.
If the entry point has multiple outputs, the return value is an array
containing the outputs in order.