ExTorch.Native.Macros (extorch v0.1.0-pre0)
General purpose macros to automatically generate binding declarations and calls for both ExTorch callable functions and Rustler signature calls to the NIF library.
Link to this section Summary
Functions
Automatic binding generation.
Link to this section Functions
Automatic binding generation.
This macro allows to define a bindings block under a given doc_section
for a given set of function bindings. All binding declarations should be
signaled using the defbinding
function, which recieves the function
signature, alongside an optional keyword list of parameter transformations
that must be done before calling the native function
(defined in ExTorch.Native
).
Each defbinding
declaration must declare its @spec
and optionally its
docstring @doc
before the call. Additionally, the function binding
signature can declare optional arguments. For example:
# All function docstrings will be collected under :doc_section_name
defbindings(:doc_section_name) do
@doc """
The docstring for func goes here
"""
@spec func(type_1(), type_2(), type_3()) :: ret_type()
defbinding(
func(
arg1, # Positional argument
arg2 \\ optional_value, # Optional argument
arg3 \\ optional_value # Optional argument
)
)
@doc """
The docstring for func2 goes here
"""
@spec func2(type_1(), type_2(), type_3(), type_4()) :: ret_type()
defbinding(
func2(
arg1 \\ optional_value, # Positional argument with optional value
arg2, # Positional argument
arg3 \\ optional_value, # Optional argument
arg4 \\ optional_value # Optional argument
)
)
@doc """
The docstring for func3 goes here
"""
@spec func3(type_1(), type_2(), type_3(), type_4()) :: ret_type()
defbinding(
func3(
arg1, # Positional argument
arg2, # Positional argument
arg3 \\ optional_value, # Optional argument
arg4 \\ optional_value # Optional argument
),
arg1: arg1[:value],
arg3: call_to_some_transform(arg3, arg2),
)
end
In case optional arguments are defined, the macro will expand the declaration
to allow optional arguments to be passed as a keyword list. For example, the
function func
will be expanded to the following function calls: func(arg1)
,
func(arg1, kwargs)
, func(arg1, arg2)
, func(arg1, arg2, kwargs)
and
func(arg1, arg2, arg3)
, where kwargs correspond to arg2: value, arg3: value2
and arg3: value
, respectively.
When the first argument is declared as optional, the macro will
generate function calls that begin with the first argument as well as the
second argument. In case there are multiple calls with the same arity, the
macro will try to disambiguate them by computing the corresponding guards
that distinguish each call from the others. In the case of func2
, the
expanded definitions would correspond to func2(arg2)
func2(arg2, kwargs)
,
func2(arg2, arg3, kwargs)
, func2(arg2, arg3, arg4)
,
func2(arg1, arg2)
, func2(arg1, arg2, kwargs)
,
func2(arg1, arg2, arg3)
, etc.
Finally, if transforms are defined (like func3
), they will be assigned to
the specified arguments before calling the native function.