diff --git a/c_src/modules/evision_mat.h b/c_src/modules/evision_mat.h index 178b079d..831944fa 100644 --- a/c_src/modules/evision_mat.h +++ b/c_src/modules/evision_mat.h @@ -5,6 +5,7 @@ #include #include #include +#include #include #if defined(_WIN32) || defined(WINRT) || defined(_WIN32_WCE) || defined(__WIN32__) || defined(_MSC_VER) #include @@ -34,6 +35,58 @@ static ERL_NIF_TERM evision_cv_mat_empty(ErlNifEnv *env, int argc, const ERL_NIF return _evision_make_mat_resource_into_map(env, *res->val, ret); } +// @evision c: mat_to_pointer,evision_cv_mat_to_pointer,2 +// @evision nif: def mat_to_pointer(_self,_opts \\ []), do: :erlang.nif_error("Mat::to_pointer not loaded") +static ERL_NIF_TERM evision_cv_mat_to_pointer(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { + using namespace cv; + ERL_NIF_TERM error_term = 0; + std::map erl_terms; + int nif_opts_index = 1; + evision::nif::parse_arg(env, nif_opts_index, argv, erl_terms); + + { + std::string pointer_kind; + + if (!evision_to_safe(env, evision_get_kw(env, erl_terms, "mode"), pointer_kind, ArgInfo("mode", 1))) { + return enif_make_badarg(env); + } + + ERL_NIF_TERM self = argv[0]; + Ptr * self1 = 0; + if (evision_cuda_GpuMat_getp(env, self, self1)) { + Ptr _self_ = *(self1); + std::vector pointer_vec; + if (pointer_kind == "local") { + std::uintptr_t ptr = (std::uintptr_t)_self_->cudaPtr(); + unsigned char* bytePtr = reinterpret_cast(&ptr); + for (size_t i = 0; i < sizeof(void*); i++) { + pointer_vec.push_back(bytePtr[i]); + } + } + // else if (pointer_kind == "cuda_ipc") { + // auto result = get_cuda_ipc_handle(ptr); + // if (result.second) { + // return exla::nif::error(env, "Unable to get cuda IPC handle"); + // } + // pointer_vec = result.first; + // } + if (pointer_vec.size() == 0) { + return enif_make_badarg(env); + } + std::vector handle_list(pointer_vec.size()); + for (uint64_t i = 0; i < pointer_vec.size(); i++) { + handle_list[i] = enif_make_uint(env, pointer_vec[i]); + } + + ERL_NIF_TERM handle_list_term = enif_make_list_from_array(env, handle_list.data(), pointer_vec.size()); + return evision::nif::ok(env, handle_list_term); + } + } + + if (error_term != 0) return error_term; + else return enif_make_badarg(env); +} + // @evision c: mat_type,evision_cv_mat_type,1 // @evision nif: def mat_type(_opts \\ []), do: :erlang.nif_error("Mat::type not loaded") static ERL_NIF_TERM evision_cv_mat_type(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { diff --git a/lib/evision_mat.ex b/lib/evision_mat.ex index 53f63a8b..42a526b5 100644 --- a/lib/evision_mat.ex +++ b/lib/evision_mat.ex @@ -834,6 +834,15 @@ defmodule Evision.Mat do {:ok, nil} end + @doc """ + Get raw pointers + + Currently only supports `Evision.CUDA.GpuMat.t()` and `mode` is `:local` + """ + def to_pointer(%{ref: ref}, mode) do + :evision_nif.mat_to_pointer(ref, mode: mode) + end + @impl Access @doc """ Access.get_and_update/3 implementation for Evision.Mat diff --git a/mix.exs b/mix.exs index bd7fd1fb..5ef08c1a 100644 --- a/mix.exs +++ b/mix.exs @@ -1193,7 +1193,7 @@ defmodule Evision.MixProject do {:castore, "~> 0.1 or ~> 1.0"}, # runtime - {:nx, "~> 0.4"}, + {:nx, "~> 0.7"}, # optional ## kino: for smart cells and better output in livebook diff --git a/mix.lock b/mix.lock index 5bbc615a..5567d856 100644 --- a/mix.lock +++ b/mix.lock @@ -13,7 +13,7 @@ "makeup_erlang": {:hex, :makeup_erlang, "0.1.4", "29563475afa9b8a2add1b7a9c8fb68d06ca7737648f28398e04461f008b69521", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "f4ed47ecda66de70dd817698a703f8816daa91272e7e45812469498614ae8b29"}, "nimble_csv": {:hex, :nimble_csv, "1.2.0", "4e26385d260c61eba9d4412c71cea34421f296d5353f914afe3f2e71cce97722", [:mix], [], "hexpm", "d0628117fcc2148178b034044c55359b26966c6eaa8e2ce15777be3bbc91b12a"}, "nimble_parsec": {:hex, :nimble_parsec, "1.4.0", "51f9b613ea62cfa97b25ccc2c1b4216e81df970acd8e16e8d1bdc58fef21370d", [:mix], [], "hexpm", "9c565862810fb383e9838c1dd2d7d2c437b3d13b267414ba6af33e50d2d1cf28"}, - "nx": {:hex, :nx, "0.6.4", "948d9f42f81e63fc901d243ac0a985c8bb87358be62e27826cfd67f58bc640af", [:mix], [{:complex, "~> 0.5", [hex: :complex, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "bb9c2e2e3545b5eb4739d69046a988daaa212d127dba7d97801c291616aff6d6"}, + "nx": {:hex, :nx, "0.7.2", "7f6f6584585e49ffbf81769e7ccc2d01c5639074e399c1f94adc2b509869673e", [:mix], [{:complex, "~> 0.5", [hex: :complex, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "e2c0680066eec5af8b8ef00c99e9bf40a0d08d8b2bbba77f59f801ec54a3f90e"}, "progress_bar": {:hex, :progress_bar, "3.0.0", "f54ff038c2ac540cfbb4c2bfe97c75e7116ead044f3c2b10c9f212452194b5cd", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm", "6981c2b25ab24aecc91a2dc46623658e1399c21a2ae24db986b90d678530f2b7"}, "scidata": {:hex, :scidata, "0.1.11", "fe3358bac7d740374b4f2a7eff6a1cb02e5ee7f87f7cdb1e8648ad93c533165f", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.1", [hex: :nimble_csv, repo: "hexpm", optional: false]}, {:stb_image, "~> 0.4", [hex: :stb_image, repo: "hexpm", optional: true]}], "hexpm", "90873337a9d5fe880d640517efa93d3c07e46c8ba436de44117f581800549f93"}, "table": {:hex, :table, "0.1.2", "87ad1125f5b70c5dea0307aa633194083eb5182ec537efc94e96af08937e14a8", [:mix], [], "hexpm", "7e99bc7efef806315c7e65640724bf165c3061cdc5d854060f74468367065029"},