5. JavaScript API Reference

The futhark-wasm, futhark-wasm-multicore, and 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:

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:

<script src="futlib.js"></script>
<script src="main.js"></script>

5.1. 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.

5.2. 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.

class FutharkModule()

A bookkeeping class representing an instance of a compiled Futhark program.

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.

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.

FutharkModule.entry

Object containing the generated entry point functions. For example, an entry point named main is available as fut.entry.main.

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.

FutharkModule.context_sync()

Wait for pending backend work associated with the context to finish.

FutharkModule.clear_caches()

Clear backend caches associated with the context.

FutharkModule.report()

Return a profiling report string.

FutharkModule.pause_profiling()

Pause profiling.

FutharkModule.unpause_profiling()

Resume profiling.

5.2.1. WASM compatibility interface

The WASM-style backend also keep the older FutharkContext interface for backwards compatibility.

newFutharkContext()

Asynchronously create a new FutharkContext object.

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.

5.3. 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.

5.4. FutharkArray

Arrays are represented by FutharkArray objects. The common array API is shared by the WASM backend and the WebGPU backend.

FutharkArray.shape()

Returns the shape of the array as a BigInt64Array.

FutharkArray.values()

Asynchronously returns a flat typed array containing the array data.

FutharkArray.free()

Frees the memory used by the FutharkArray.

The WASM backend also provides a few older convenience methods.

FutharkArray.toArray()

Returns a nested JavaScript array.

FutharkArray.toTypedArray()

Returns a flat typed array of the underlying data.

FutharkArray.shape()

Returns the shape of the FutharkArray as an array of BigInt values.

5.4.1. Array construction

Each array type used by an entry point is exposed through a generated constructor object. For example, for the type []i32:

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.

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.

5.5. 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.

FutharkOpaque.free()

Frees memory used by FutharkOpaque. Should be called when Futhark Opaque is no longer used.

5.6. 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:

const res = await fut.entry.main(in1, ..., inN);
fut.entry.<entry_point_name>(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.