diff --git a/c_src/Tensorflex.c b/c_src/Tensorflex.c index 725de81..a67af22 100644 --- a/c_src/Tensorflex.c +++ b/c_src/Tensorflex.c @@ -852,6 +852,167 @@ static ERL_NIF_TERM load_csv_as_matrix(ErlNifEnv *env, int argc, const ERL_NIF_T return mat_ret; } +static ERL_NIF_TERM add_scalar_to_matrix(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) +{ + ERL_NIF_TERM ret; + unsigned i, j; + mx_t mx, mx_ret; + mx.p = NULL; + mx_ret.p = NULL; + + if (!enif_get_resource(env, argv[0], resource_type, &mx.vp)) { + return enif_make_badarg(env); + } + + double scalar = 0.0; + if (!enif_get_double(env, argv[1], &scalar)) { + return enif_make_badarg(env); + } + + mx_ret.p = alloc_matrix(env, mx.p->nrows, mx.p->ncols); + for (i = 0; i < mx.p->nrows; i++) { + for (j = 0; j < mx.p->ncols; j++) { + POS(mx_ret.p, i, j) = POS(mx.p, i, j) + scalar; + } + } + + ret = enif_make_resource(env, mx_ret.p); + enif_release_resource(mx_ret.p); + return ret; +} + +static ERL_NIF_TERM subtract_scalar_from_matrix(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) +{ + ERL_NIF_TERM ret; + unsigned i, j; + mx_t mx, mx_ret; + mx.p = NULL; + mx_ret.p = NULL; + + if (!enif_get_resource(env, argv[0], resource_type, &mx.vp)) { + return enif_make_badarg(env); + } + + double scalar = 0.0; + if (!enif_get_double(env, argv[1], &scalar)) { + return enif_make_badarg(env); + } + + mx_ret.p = alloc_matrix(env, mx.p->nrows, mx.p->ncols); + for (i = 0; i < mx.p->nrows; i++) { + for (j = 0; j < mx.p->ncols; j++) { + POS(mx_ret.p, i, j) = POS(mx.p, i, j) - scalar; + } + } + + ret = enif_make_resource(env, mx_ret.p); + enif_release_resource(mx_ret.p); + return ret; +} + +static ERL_NIF_TERM multiply_matrix_with_scalar(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) +{ + ERL_NIF_TERM ret; + unsigned i, j; + mx_t mx, mx_ret; + mx.p = NULL; + mx_ret.p = NULL; + + if (!enif_get_resource(env, argv[0], resource_type, &mx.vp)) { + return enif_make_badarg(env); + } + + double scalar = 1.0; + if (!enif_get_double(env, argv[1], &scalar)) { + return enif_make_badarg(env); + } + + mx_ret.p = alloc_matrix(env, mx.p->nrows, mx.p->ncols); + for (i = 0; i < mx.p->nrows; i++) { + for (j = 0; j < mx.p->ncols; j++) { + POS(mx_ret.p, i, j) = POS(mx.p, i, j) * scalar; + } + } + + ret = enif_make_resource(env, mx_ret.p); + enif_release_resource(mx_ret.p); + return ret; +} + +static ERL_NIF_TERM divide_matrix_by_scalar(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) +{ + ERL_NIF_TERM ret; + unsigned i, j; + mx_t mx, mx_ret; + mx.p = NULL; + mx_ret.p = NULL; + + if (!enif_get_resource(env, argv[0], resource_type, &mx.vp)) { + return enif_make_badarg(env); + } + + double scalar = 1.0;; + if ((!enif_get_double(env, argv[1], &scalar)) || (scalar == 0.0)) { + return enif_make_badarg(env); + } + + mx_ret.p = alloc_matrix(env, mx.p->nrows, mx.p->ncols); + for (i = 0; i < mx.p->nrows; i++) { + for (j = 0; j < mx.p->ncols; j++) { + POS(mx_ret.p, i, j) = POS(mx.p, i, j) / scalar; + } + } + + ret = enif_make_resource(env, mx_ret.p); + enif_release_resource(mx_ret.p); + return ret; +} + +static ERL_NIF_TERM add_matrices(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{ + unsigned i, j; + ERL_NIF_TERM ret; + mx_t mx1, mx2, mx; + mx1.p = NULL; + mx2.p = NULL; + mx.p = NULL; + + if (!enif_get_resource(env, argv[0], resource_type, &mx1.vp) || !enif_get_resource(env, argv[1], resource_type, &mx2.vp) || mx1.p->nrows != mx2.p->nrows || mx1.p->ncols != mx2.p->ncols) { + return enif_make_badarg(env); + } + mx.p = alloc_matrix(env, mx1.p->nrows, mx2.p->ncols); + for (i = 0; i < mx1.p->nrows; i++) { + for (j = 0; j < mx2.p->ncols; j++) { + POS(mx.p, i, j) = POS(mx1.p, i, j) + POS(mx2.p, i, j); + } + } + ret = enif_make_resource(env, mx.p); + enif_release_resource(mx.p); + return ret; +} + +static ERL_NIF_TERM subtract_matrices(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{ + unsigned i, j; + ERL_NIF_TERM ret; + mx_t mx1, mx2, mx; + mx1.p = NULL; + mx2.p = NULL; + mx.p = NULL; + + if (!enif_get_resource(env, argv[0], resource_type, &mx1.vp) || !enif_get_resource(env, argv[1], resource_type, &mx2.vp) || mx1.p->nrows != mx2.p->nrows || mx1.p->ncols != mx2.p->ncols) { + return enif_make_badarg(env); + } + mx.p = alloc_matrix(env, mx1.p->nrows, mx2.p->ncols); + for (i = 0; i < mx1.p->nrows; i++) { + for (j = 0; j < mx2.p->ncols; j++) { + POS(mx.p, i, j) = POS(mx1.p, i, j) - POS(mx2.p, i, j); + } + } + ret = enif_make_resource(env, mx.p); + enif_release_resource(mx.p); + return ret; +} static ErlNifFunc nif_funcs[] = { @@ -877,6 +1038,12 @@ static ErlNifFunc nif_funcs[] = { "run_session", 5, run_session }, { "load_image_as_tensor", 1, load_image_as_tensor }, { "load_csv_as_matrix", 3, load_csv_as_matrix }, + { "add_scalar_to_matrix", 2, add_scalar_to_matrix }, + { "subtract_scalar_from_matrix", 2, subtract_scalar_from_matrix }, + { "multiply_matrix_with_scalar", 2, multiply_matrix_with_scalar }, + { "divide_matrix_by_scalar", 2, divide_matrix_by_scalar }, + { "add_matrices", 2, add_matrices }, + { "subtract_matrices", 2, subtract_matrices }, }; ERL_NIF_INIT(Elixir.Tensorflex.NIFs, nif_funcs, res_loader, NULL, NULL, NULL) diff --git a/lib/nifs.ex b/lib/nifs.ex index ce72f73..5a13c67 100644 --- a/lib/nifs.ex +++ b/lib/nifs.ex @@ -4,7 +4,7 @@ defmodule Tensorflex.NIFs do @on_load :load_nifs def load_nifs do - :erlang.load_nif("priv/Tensorflex", 0) + :erlang.load_nif(Application.app_dir(:tensorflex, "priv/Tensorflex"), 0) end def create_matrix(_nrows,_ncolumns, _list) do @@ -95,4 +95,28 @@ defmodule Tensorflex.NIFs do raise "NIF run_session/5 not implemented" end + def add_scalar_to_matrix(_mat, _scalar) do + raise "NIF add_scalar_to_matrix/2 not implemented" + end + + def subtract_scalar_from_matrix(_mat, _scalar) do + raise "NIF subtract_scalar_from_matrix/2 not implemented" + end + + def multiply_matrix_with_scalar(_mat, _scalar) do + raise "NIF multiply_matrix_with_scalar/2 not implemented" + end + + def divide_matrix_by_scalar(_mat, _scalar) do + raise "NIF divide_matrix_by_scalar/2 not implemented" + end + + def add_matrices(_mat1, _mat2) do + raise "NIF add_matrices/2 not implemented" + end + + def subtract_matrices(_mat1, _mat2) do + raise "NIF subtract_matrices/2 not implemented" + end + end diff --git a/lib/tensorflex.ex b/lib/tensorflex.ex index 229f322..4aa8775 100644 --- a/lib/tensorflex.ex +++ b/lib/tensorflex.ex @@ -1187,5 +1187,225 @@ defmodule Tensorflex do def run_session(%Graph{def: graphdef, name: _filepath}, %Tensor{datatype: _input_datatype, tensor: input_ref}, %Tensor{datatype: _output_datatype, tensor: output_ref}, input_opname, output_opname) do NIFs.run_session(graphdef, input_ref, output_ref, input_opname, output_opname) end + + @doc """ + Adds scalar value to matrix. + + Takes two arguments: `%Matrix` matrix and scalar value (int or float) + + Returns a `%Matrix` modified matrix. + + ## Examples + + ```elixir + iex(1)> m = Tensorflex.create_matrix(2,3,[[1,2,3],[4,5,6]]) + %Tensorflex.Matrix{ + data: #Reference<0.2262135929.2234908676.182623>, + ncols: 3, + nrows: 2 + } + + iex(2)> m = Tensorflex.add_scalar_to_matrix(m, 5) + %Tensorflex.Matrix{ + data: #Reference<0.2262135929.2234908673.182139>, + ncols: 3, + nrows: 2 + } + + iex(3)> Tensorflex.matrix_to_lists m + [[6.0, 7.0, 8.0], [9.0, 10.0, 11.0]] + ``` + """ + + def add_scalar_to_matrix(%Matrix{nrows: nrows, ncols: ncols, data: ref}, scalar) do + new_ref = NIFs.add_scalar_to_matrix(ref, scalar/1) + %Matrix{nrows: nrows, ncols: ncols, data: new_ref} + end + + @doc """ + Subtracts scalar value from matrix. + + Takes two arguments: `%Matrix` matrix and scalar value (int or float) + + Returns a `%Matrix` modified matrix. + + ## Examples + + ```elixir + iex(1)> m = Tensorflex.create_matrix(2,3,[[1,2,3],[4,5,6]]) + %Tensorflex.Matrix{ + data: #Reference<0.2262135929.2234908676.182623>, + ncols: 3, + nrows: 2 + } + + iex(2)> m = Tensorflex.subtract_scalar_from_matrix m,5 + %Tensorflex.Matrix{ + data: #Reference<0.11868180.3310747649.147467>, + ncols: 3, + nrows: 2 + } + + iex(3)> Tensorflex.matrix_to_lists m + [[-4.0, -3.0, -2.0], [-1.0, 0.0, 1.0]] + ``` + """ + + def subtract_scalar_from_matrix(%Matrix{nrows: nrows, ncols: ncols, data: ref}, scalar) do + new_ref = NIFs.subtract_scalar_from_matrix(ref, scalar/1) + %Matrix{nrows: nrows, ncols: ncols, data: new_ref} + end + + @doc """ + Multiplies scalar value with matrix. + + Takes two arguments: `%Matrix` matrix and scalar value (int or float) + + Returns a `%Matrix` modified matrix. + + ## Examples + + ```elixir + iex(1)> m = Tensorflex.create_matrix(2,3,[[1,2,3],[4,5,6]]) + %Tensorflex.Matrix{ + data: #Reference<0.2262135929.2234908676.182623>, + ncols: 3, + nrows: 2 + } + + iex(2)> m = Tensorflex.multiply_matrix_with_scalar m,5 + %Tensorflex.Matrix{ + data: #Reference<0.2093133110.1968832513.7094>, + ncols: 3, + nrows: 2 + } + + iex(3)> Tensorflex.matrix_to_lists m + [[5.0, 10.0, 15.0], [20.0, 25.0, 30.0]] + ``` + """ + + def multiply_matrix_with_scalar(%Matrix{nrows: nrows, ncols: ncols, data: ref}, scalar) do + new_ref = NIFs.multiply_matrix_with_scalar(ref, scalar/1) + %Matrix{nrows: nrows, ncols: ncols, data: new_ref} + end + + @doc """ + Divides matrix values by scalar. + + Takes two arguments: `%Matrix` matrix and scalar value (int or float) + + Returns a `%Matrix` modified matrix. + + ## Examples + + ```elixir + iex(1)> m = Tensorflex.create_matrix(2,3,[[1,2,3],[4,5,6]]) + %Tensorflex.Matrix{ + data: #Reference<0.2262135929.2234908676.182623>, + ncols: 3, + nrows: 2 + } + + iex(2)> m = Tensorflex.divide_matrix_by_scalar m,5 + %Tensorflex.Matrix{ + data: #Reference<0.3723154058.2507014148.17262>, + ncols: 3, + nrows: 2 + } + + iex(3)> Tensorflex.matrix_to_lists m + [[0.2, 0.4, 0.6], [0.8, 1.0, 1.2]] + + ``` + """ + + def divide_matrix_by_scalar(%Matrix{nrows: nrows, ncols: ncols, data: ref}, scalar) do + new_ref = NIFs.divide_matrix_by_scalar(ref, scalar/1) + %Matrix{nrows: nrows, ncols: ncols, data: new_ref} + end + + @doc """ + Adds two matrices of same dimensions together. + + Takes in two `%Matrix` matrices as arguments. + + Returns the resultant `%Matrix` matrix. + + ## Examples + + ```elixir + iex(1)> m1 = Tensorflex.create_matrix(2,3,[[1,2,3],[4,5,6]]) + %Tensorflex.Matrix{ + data: #Reference<0.3124708718.3046244353.117555>, + ncols: 3, + nrows: 2 + } + + iex(2)> m2 = Tensorflex.create_matrix(2,3,[[4,5,6],[1,2,3]]) + %Tensorflex.Matrix{ + data: #Reference<0.3124708718.3046244354.115855>, + ncols: 3, + nrows: 2 + } + + iex(3)> m_added = Tensorflex.add_matrices m1,m2 + %Tensorflex.Matrix{ + data: #Reference<0.3124708718.3046244353.118873>, + ncols: 3, + nrows: 2 + } + + iex(4)> Tensorflex.matrix_to_lists m_added + [[5.0, 7.0, 9.0], [5.0, 7.0, 9.0]] + + ``` + """ + def add_matrices(%Matrix{nrows: nrows1, ncols: _ncols1, data: ref1}, %Matrix{nrows: _nrows2, ncols: ncols2, data: ref2}) do + new_ref = NIFs.add_matrices(ref1, ref2) + %Matrix{nrows: nrows1, ncols: ncols2, data: new_ref} + end + + @doc """ + Subtracts `matrix2` from `matrix1`. + + Takes in two `%Matrix` matrices as arguments. + + Returns the resultant `%Matrix` matrix. + + ## Examples + + ```elixir + iex(1)> m1 = Tensorflex.create_matrix(2,3,[[1,2,3],[4,5,6]]) + %Tensorflex.Matrix{ + data: #Reference<0.3124708718.3046244353.117555>, + ncols: 3, + nrows: 2 + } + + iex(2)> m2 = Tensorflex.create_matrix(2,3,[[4,5,6],[1,2,3]]) + %Tensorflex.Matrix{ + data: #Reference<0.3124708718.3046244354.115855>, + ncols: 3, + nrows: 2 + } + + iex(3)> m_subtracted = Tensorflex.subtract_matrices m1,m2 + %Tensorflex.Matrix{ + data: #Reference<0.3124708718.3046244353.120058>, + ncols: 3, + nrows: 2 + } + + iex(4)> Tensorflex.matrix_to_lists m_subtracted + [[-3.0, -3.0, -3.0], [3.0, 3.0, 3.0]] + + ``` + """ + + def subtract_matrices(%Matrix{nrows: nrows1, ncols: _ncols1, data: ref1}, %Matrix{nrows: _nrows2, ncols: ncols2, data: ref2}) do + new_ref = NIFs.subtract_matrices(ref1, ref2) + %Matrix{nrows: nrows1, ncols: ncols2, data: new_ref} + end end diff --git a/test/tensorflex_test.exs b/test/tensorflex_test.exs index 4188d9c..152fff4 100644 --- a/test/tensorflex_test.exs +++ b/test/tensorflex_test.exs @@ -1,73 +1,193 @@ defmodule TensorflexTest do use ExUnit.Case - describe "core functionalities" do - - test "basic matrix functions check" do - mat = Tensorflex.create_matrix(4,4,[[123,431,23,1],[1,2,3,4],[5,6,7,8],[768,564,44,5]]) - assert {4,4} = Tensorflex.size_of_matrix mat - assert 44.0 = Tensorflex.matrix_pos(mat,4,3) - assert [[123.0, 431.0, 23.0, 1.0],[1.0, 2.0, 3.0, 4.0],[5.0, 6.0, 7.0, 8.0],[768.0, 564.0, 44.0, 5.0]] = Tensorflex.matrix_to_lists mat + describe "matrix functionalities" do + test "matrix creation check" do + assert [[2.2,1.3,44.5],[5.5,6.1,3.333]] = Tensorflex.create_matrix(2,3, [[2.2,1.3,44.5],[5.5,6.1,3.333]]) |> Tensorflex.matrix_to_lists end - test "running session/graph loading check" do - {:ok, graph} = Tensorflex.read_graph("./test/graphdef_toy.pb") - assert ["input", "weights", "weights/read", "biases", "biases/read", "MatMul", "add", "output"] = Tensorflex.get_graph_ops graph - in_vals = Tensorflex.create_matrix(3,3,[[1.0,1.0,1.0],[2.0,2.0,2.0],[3.0,3.0,3.0]]) - in_dims = Tensorflex.create_matrix(1,2,[[3,3]]) - {:ok, input_tensor} = Tensorflex.float32_tensor(in_vals, in_dims) - out_dims = Tensorflex.create_matrix(1,2,[[3,2]]) - {:ok, output_tensor} = Tensorflex.float32_tensor_alloc(out_dims) - assert [[56.349998474121094, 39.26000213623047], [109.69999694824219, 75.52000427246094], [163.04998779296875, 111.77999877929688]] = Tensorflex.run_session(graph, input_tensor, output_tensor, "input", "output") + test "matrix to lists conversion check" do + mat = Tensorflex.create_matrix(5,4,[[123,431,23,1],[1,2,3,4],[5,6,7,8],[768,564,44,5],[1,2,3,4]]) + assert [[123.0, 431.0, 23.0, 1.0],[1.0, 2.0, 3.0, 4.0],[5.0, 6.0, 7.0, 8.0],[768.0, 564.0, 44.0, 5.0],[1.0, 2.0, 3.0, 4.0]] = Tensorflex.matrix_to_lists mat end - test "CSV loading function check" do - m_header = Tensorflex.load_csv_as_matrix("./test/sample2.csv", header: :true, delimiter: "-") - assert [[1.0, 2.0, 3.0, 4.0], [5.0, 6.0, 7.0, 8.0], [9.0, 10.0, 11.0, 12.0]] = Tensorflex.matrix_to_lists m_header - m_no_header = Tensorflex.load_csv_as_matrix("./test/sample1.csv", header: :false) - assert [[1.0, 2.0, 3.0, 4.0, 5.0],[6.0, 7.0, 8.0, 9.0, 10.0],[11.0, 12.0, 13.0, 14.0, 15.0]] = Tensorflex.matrix_to_lists m_no_header + test "matrix access function check" do + mat = Tensorflex.create_matrix(2,3, [[2.2,1.3,44.5],[5.5,6.1,3.333]]) + assert 5.5 = Tensorflex.matrix_pos(mat,2,1) + assert 3.333 = Tensorflex.matrix_pos(mat,2,3) + end - assert_raise ArgumentError, fn -> - _m = Tensorflex.load_csv_as_matrix("./test/sample1.csv", header: :no_header, delimiter: ",") - end + test "get size of matrix" do + assert {3,3} = Tensorflex.create_matrix(3,3, [[3.9,62,122],[2.2,1.3,44.5],[5.5,6.1,3.333]]) |> Tensorflex.size_of_matrix + end + + test "append new row to matrix function check" do + mat = Tensorflex.create_matrix(4,4,[[123,431,23,1],[1,2,3,4],[5,6,7,8],[768,564,44,5]]) + mat = Tensorflex.append_to_matrix(mat, [[4.4,2,7,9.9]]) + assert {5,4} = Tensorflex.size_of_matrix mat + assert 7.0 = Tensorflex.matrix_pos(mat,5,3) end + end - test "float32 tensor functions check" do + describe "float32 tensor functionalities" do + test "float32_tensor/2 tensor creation check" do dims = Tensorflex.create_matrix(1,2,[[1,3]]) vals = Tensorflex.create_matrix(1,3,[[245,202,9]]) {:ok, tensor} = Tensorflex.float32_tensor vals,dims {:ok, :tf_float} = Tensorflex.tensor_datatype(tensor) - {:ok, ftensor} = Tensorflex.float32_tensor 1234.1234 - {:ok, :tf_float} = Tensorflex.tensor_datatype(ftensor) - {:ok, tensor_alloc} = Tensorflex.float32_tensor_alloc dims - {:ok, :tf_float} = Tensorflex.tensor_datatype(tensor_alloc) + end + + test "float32_tensor/1 tensor creation check" do + {:ok, tensor} = Tensorflex.float32_tensor 1234.1234 + {:ok, :tf_float} = Tensorflex.tensor_datatype(tensor) + end + test "float32_tensor_alloc/1 tensor creation check" do + dims = Tensorflex.create_matrix(1,2,[[1,3]]) + {:ok, tensor} = Tensorflex.float32_tensor_alloc dims + {:ok, :tf_float} = Tensorflex.tensor_datatype(tensor) + end + + test "incorrect usage check" do assert_raise FunctionClauseError, fn -> Tensorflex.float32_tensor("123.123") end - + assert_raise FunctionClauseError, fn -> Tensorflex.float32_tensor(123) end end + end - test "int32 tensor functions check" do + describe "float64 tensor functionalities" do + test "float64_tensor/2 tensor creation check" do + dims = Tensorflex.create_matrix(1,2,[[1,3]]) + vals = Tensorflex.create_matrix(1,3,[[245,202,9]]) + {:ok, tensor} = Tensorflex.float64_tensor vals,dims + {:ok, :tf_double} = Tensorflex.tensor_datatype(tensor) + end + + test "float64_tensor/1 tensor creation check" do + {:ok, tensor} = Tensorflex.float64_tensor 1234.1234 + {:ok, :tf_double} = Tensorflex.tensor_datatype(tensor) + end + + test "float64_tensor_alloc/1 tensor creation check" do + dims = Tensorflex.create_matrix(1,2,[[1,3]]) + {:ok, tensor} = Tensorflex.float64_tensor_alloc dims + {:ok, :tf_double} = Tensorflex.tensor_datatype(tensor) + end + + test "incorrect usage check" do + assert_raise FunctionClauseError, fn -> + Tensorflex.float64_tensor("123.123") + end + + assert_raise FunctionClauseError, fn -> + Tensorflex.float64_tensor(123) + end + end + end + + describe "int32 tensor functionalities" do + test "int32_tensor/2 tensor creation check" do dims = Tensorflex.create_matrix(1,2,[[1,3]]) vals = Tensorflex.create_matrix(1,3,[[245,202,9]]) {:ok, tensor} = Tensorflex.int32_tensor vals,dims {:ok, :tf_int32} = Tensorflex.tensor_datatype(tensor) - {:ok, ftensor} = Tensorflex.int32_tensor 1234 - {:ok, :tf_int32} = Tensorflex.tensor_datatype(ftensor) - {:ok, tensor_alloc} = Tensorflex.int32_tensor_alloc dims - {:ok, :tf_int32} = Tensorflex.tensor_datatype(tensor_alloc) + end + + test "int32_tensor/1 tensor creation check" do + {:ok, tensor} = Tensorflex.int32_tensor 1234 + {:ok, :tf_int32} = Tensorflex.tensor_datatype(tensor) + end + test "int32_tensor_alloc/1 tensor creation check" do + dims = Tensorflex.create_matrix(1,2,[[1,3]]) + {:ok, tensor} = Tensorflex.int32_tensor_alloc dims + {:ok, :tf_int32} = Tensorflex.tensor_datatype(tensor) + end + + test "incorrect usage check" do assert_raise FunctionClauseError, fn -> Tensorflex.int32_tensor("123.123") end - + assert_raise FunctionClauseError, fn -> Tensorflex.int32_tensor(123.123) end - end + end + end + + describe "string tensor functionality" do + test "string tensor creation check" do + {:ok, tensor} = Tensorflex.string_tensor "123.123" + {:ok, :tf_string} = Tensorflex.tensor_datatype tensor + end + + test "incorrect usage check" do + assert_raise FunctionClauseError, fn -> + Tensorflex.string_tensor(123.123) + end + + assert_raise FunctionClauseError, fn -> + Tensorflex.string_tensor(123) + end + end + end + + describe "graph loading and reading functionalities" do + test "graph loading check" do + {:ok, _graph_toy} = Tensorflex.read_graph "./test/graphdef_toy.pb" + {:ok, _graph_iris} = Tensorflex.read_graph "./test/graphdef_iris.pb" + end + + test "get all graph ops" do + {:ok, graph_toy} = Tensorflex.read_graph "./test/graphdef_toy.pb" + {:ok, graph_iris} = Tensorflex.read_graph "./test/graphdef_iris.pb" + assert ["input", "weights", "weights/read", "biases", "biases/read", "MatMul", "add", "output"] = Tensorflex.get_graph_ops graph_toy + assert ["input", "weights1", "weights1/read", "biases1", "biases1/read", "weights2", "weights2/read", "biases2", "biases2/read", "MatMul", "Add", "Relu", "MatMul_1", "Add_1", "output"] = Tensorflex.get_graph_ops graph_iris + end + + test "incorrect usage check" do + assert_raise ArgumentError, fn -> + {:ok, _graph} = Tensorflex.read_graph "Makefile" + end + + assert_raise ArgumentError, fn -> + {:ok, _graph} = Tensorflex.read_graph "Makefile.pb" + end + end + end + + describe "session functionality" do + test "running session check" do + {:ok, graph} = Tensorflex.read_graph("./test/graphdef_toy.pb") + in_vals = Tensorflex.create_matrix(3,3,[[1.0,1.0,1.0],[2.0,2.0,2.0],[3.0,3.0,3.0]]) + in_dims = Tensorflex.create_matrix(1,2,[[3,3]]) + {:ok, input_tensor} = Tensorflex.float32_tensor(in_vals, in_dims) + out_dims = Tensorflex.create_matrix(1,2,[[3,2]]) + {:ok, output_tensor} = Tensorflex.float32_tensor_alloc(out_dims) + assert [[56.349998474121094, 39.26000213623047], [109.69999694824219, 75.52000427246094], [163.04998779296875, 111.77999877929688]] = Tensorflex.run_session(graph, input_tensor, output_tensor, "input", "output") + end + end + + describe "miscellaneous functionalities" do + test "CSV-with-header loading function check" do + m = Tensorflex.load_csv_as_matrix("./test/sample2.csv", header: :true, delimiter: "-") + assert [[1.0, 2.0, 3.0, 4.0], [5.0, 6.0, 7.0, 8.0], [9.0, 10.0, 11.0, 12.0]] = Tensorflex.matrix_to_lists m + end + + test "CSV-without-header loading function check" do + m = Tensorflex.load_csv_as_matrix("./test/sample1.csv", header: :false) + assert [[1.0, 2.0, 3.0, 4.0, 5.0],[6.0, 7.0, 8.0, 9.0, 10.0],[11.0, 12.0, 13.0, 14.0, 15.0]] = Tensorflex.matrix_to_lists m + end + + test "CSV-to-matrix function incorrect usage check" do + assert_raise ArgumentError, fn -> + _m = Tensorflex.load_csv_as_matrix("./test/sample1.csv", header: :no_header, delimiter: ",") + end + end end + end