LoginSignup
8
1

More than 3 years have passed since last update.

NIFsの初歩的な使い方

Last updated at Posted at 2019-11-29

はじめに

NIFsの使い方がわからないでいたのですが、この度、教わりつつ初歩的なコードが動きましたので書き記します。

NIFsとは

native implemented functionsの略であり、ElixirからCで書かれたコードを呼び出す仕組みです。

トラブル

私の環境ははWindows上でWSLによるUbuntu18.04です。erl_nif.hというヘッダファイルが必要なのですが、これが見つからないとしてCコンパイラがエラーを出してきました。どこにそのファイルが収録されているのかが、わからずに頓挫していました。この度Elixirフォーラムに質問をしたところ解決しました。

回答は次の処理をすればいいよ、というものでした。https://elixirforum.com/t/where-is-erl-nif-h-header-file-required-for-nif/27142

sudo apt install erlang-dev

これにより必要なヘッダファイルが準備され、コンパイル可能となりました。

Cのコード

下記のブログがとてもよく説明しています。そのコードがそのまま動きました。
https://andrealeopardi.com/posts/using-c-from-elixir-with-nifs/


#include "erl_nif.h"


static ERL_NIF_TERM
fast_compare(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
  int a, b;
  enif_get_int(env, argv[0], &a);
  enif_get_int(env, argv[1], &b);

  int result = a == b ? 0 : (a > b ? 1 : -1);
  return enif_make_int(env, result);
}

// Let's define the array of ErlNifFunc beforehand:
static ErlNifFunc nif_funcs[] = {
  // {erl_function_name, erl_function_arity, c_function}
  {"fast_compare", 2, fast_compare}
};

ERL_NIF_INIT(Elixir.FastCompare, nif_funcs, NULL, NULL, NULL, NULL)


コンパイル

動的リンク可能なオブジェクトを生成します。GCCを使いました。次のようにコンパイルします。

gcc -shared -fPIC -o nif.so nif.c

Elixirからの呼び出し

上述のブログのコードから引用します。オブジェクトファイルの名前だけを変更しています。


defmodule FastCompare do
  @on_load :load_nifs

  def load_nifs do
    :erlang.load_nif('./nif', 0)
  end

  def fast_compare(_a, _b) do
    raise "NIF fast_compare/2 not implemented"
  end
end

起動

iex(1)>  FastCompare.fast_compare(99, 100)
-1
iex(2)>  FastCompare.fast_compare(101, 100)
1
iex(3)>


上手くいきました。

プロジェクト

NIFsを利用してGPUによるCUDA、cuBLASライブラリを呼び出すことにトライしています。DeepLearningでは高速な行列計算が必要とされます。cuBLASをElixirから利用できればElixirによるAI,DLに有用ではないかと思っています。

8
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
1