-
Notifications
You must be signed in to change notification settings - Fork 7
Nerlnet NIF Implementation
Erlang NIF and Nifpp are the building blocks of Nerlnet NIF implementation. Nerlnet NIF is based on nifpp wraper that wraps Erlang NIF.
This is a short explanation of important functions that form the core of Nerlnet NIF implementation:
Example:
static ErlNifFunc nif_funcs[] = {
// Structure of each cell:
{"<name of function in erlang>", Arity, <name of implemented function in C/Cpp>},
// Examples from Nerlnet code:
{"train_predict_create", 5, train_predict_create_nif},
{"create_module", 6, train_predict_create_nif},
{"get_weights", 1, get_weights_nif},
{"set_weights", 3, set_weights_nif}
};
Example of an implemented function:
static ERL_NIF_TERM train_predict_create_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
// Here implementing using NIF or nifpp API to get arguments from argv
// argc equals to arity
// Each argument of argv array has a corresponding argument in NIF API called from Erlang code.
}
static int load(ErlNifEnv* env, void** priv, ERL_NIF_TERM load_info)
.
This function is not in use.
load_info is the second argument to erlang:load_nif/2.
*priv_data can be set to point to some private data if the library needs to keep a state between NIF calls.
enif_priv_data returns this pointer. *priv_data is initialized to NULL when load is called.
The library fails to load if load returns anything other than 0. load can be NULL if initialization is not needed.
int enif_thread_create(char *name, ErlNifTid *tid, void * (*func)(void *), void *args, ErlNifThreadOpts *opts)
Start a thread with trainFun function to train the model in a separate thread
name - A string (array of chars) that identifies the created thread.
It is used to identify the thread in planned future debug functionality.
tid - A pointer to a thread identifier variable.
func - A pointer to a function to execute in the created thread.
arg - A pointer to argument to the func function.
opts - A pointer to thread options to use or NULL.
Returns 0 on success, otherwise an errno value is returned to indicate the error.
The newly created thread begins executing in the function pointed to by func, and func is passed arg as argument.
When erl_drv_thread_create returns, the thread identifier of the newly created thread is available in *tid.
opts can be either a NULL pointer, or a pointer to an ErlDrvThreadOpts structure.
If opts is a NULL pointer (0), default options are used, otherwise the passed options are used.
ERL_NIF_INIT(erlModule, nif_funcs, load, NULL, NULL, NULL)
.
This is the magic macro to initialize a NIF library. It is to be evaluated in global file scope.
ERL_NIF_INIT(MODULE, ErlNifFunc funcs[], load, NULL, upgrade, unload)
MODULE - The first argument must be the name of the Erlang module as a C-identifier. It will be stringified by the macro.
ErlNifFunc - The second argument is the array of ErlNifFunc structures containing name, arity, and function pointer of each NIF.
load - is called when the NIF library is loaded and no previously loaded library exists for this module.
NULL - The fourth argument NULL is ignored. It was earlier used for the deprecated reload callback which is no longer supported since OTP 20.
The remaining arguments are pointers to callback functions that can be used to initialize the library.
They are not used in this simple example, hence they are all set to NULL.
TODO
TODO
TODO
TODO
The script of NerlnetBuild.sh generates a shared library (.so) of Nerlnet NIF implementation. The shared library contains the infrastructure code (E.g., OpenNN), and the bridge that connects it with Nerlnet distributed ML application. The shared library is loaded in application and adds Nerlnet NIF functionality to Erlang VM.