defmodule Evision.Zoo do @moduledoc """ Evision Model Zoo """ @type smartcell_option :: %{ value: Strung.t(), label: Strung.t() } @type smartcell_param :: %{ field: String.t(), label: String.t(), type: atom(), default: term(), is_option: boolean() | nil, options: [smartcell_option()] } @type smartcell_param_map :: %{ name: String.t(), params: [smartcell_param()] } @type smartcell_params :: [smartcell_param_map()] @type variant :: %{ id: String.t(), name: String.t(), docs_url: String.t(), params: smartcell_params(), docs: String.t() } @type smartcell_tasks :: [variant()] def download(file_url, filename, opts \\ []) when is_binary(file_url) and is_binary(filename) and is_list(opts) do cache_dir = opts[:cache_dir] || cache_dir() filepath = Path.join([cache_dir, filename]) if File.exists?(filepath) do {:ok, filepath} else case Evision.Zoo.Utils.HTTP.download(file_url, filepath) do :ok -> {:ok, filepath} err -> err end end end def cache_dir do cache_opts = if System.get_env("MIX_XDG"), do: %{os: :linux}, else: %{} cache_dir = Path.expand(:filename.basedir(:user_cache, "", cache_opts)) File.mkdir_p!(cache_dir) cache_dir end def backends do %{ "opencv" => {Evision.cv_DNN_BACKEND_OPENCV(), "OpenCV", quote do Evision.cv_DNN_BACKEND_OPENCV() end}, "cuda" => {Evision.cv_DNN_BACKEND_CUDA(), "CUDA", quote do Evision.cv_DNN_BACKEND_CUDA() end}, "halide" => {Evision.cv_DNN_BACKEND_HALIDE(), "Halide", quote do Evision.cv_DNN_BACKEND_HALIDE() end}, "inference_engine" => {Evision.cv_DNN_BACKEND_INFERENCE_ENGINE(), "Inference Engine", quote do Evision.cv_DNN_BACKEND_INFERENCE_ENGINE() end}, "timvx" => {Evision.cv_DNN_BACKEND_TIMVX(), "TIMVX", quote do Evision.cv_DNN_BACKEND_TIMVX() end}, "vkcom" => {Evision.cv_DNN_BACKEND_VKCOM(), "VKCOM", quote do Evision.cv_DNN_BACKEND_VKCOM() end}, } end def targets do %{ Evision.cv_DNN_TARGET_CPU() => %{value: "cpu", label: "CPU"}, Evision.cv_DNN_TARGET_CUDA() => %{value: "cuda", label: "CUDA"}, Evision.cv_DNN_TARGET_CUDA_FP16() => %{value: "cuda_fp16", label: "CUDA FP16"}, Evision.cv_DNN_TARGET_FPGA() => %{value: "fpga", label: "FPGA"}, Evision.cv_DNN_TARGET_HDDL() => %{value: "hddl", label: "HDDL"}, Evision.cv_DNN_TARGET_MYRIAD() => %{value: "myriad", label: "Myriad"}, Evision.cv_DNN_TARGET_NPU() => %{value: "npu", label: "NPU"}, Evision.cv_DNN_TARGET_OPENCL() => %{value: "opencl", label: "OpenCL"}, Evision.cv_DNN_TARGET_OPENCL_FP16() => %{value: "opencl_fp16", label: "OpenCL FP16"}, Evision.cv_DNN_TARGET_VULKAN() => %{value: "vulkan", label: "Vulkan"}, } end def targets_reverse_lookup do %{ "cpu" => quote do Evision.cv_DNN_TARGET_CPU() end, "cuda" => quote do Evision.cv_DNN_TARGET_CUDA() end, "cuda_fp16" => quote do Evision.cv_DNN_TARGET_CUDA_FP16() end, "fpga" => quote do Evision.cv_DNN_TARGET_FPGA() end, "hddl" => quote do Evision.cv_DNN_TARGET_HDDL() end, "myriad" => quote do Evision.cv_DNN_TARGET_MYRIAD() end, "npu" => quote do Evision.cv_DNN_TARGET_NPU() end, "opencl" => quote do Evision.cv_DNN_TARGET_OPENCL() end, "opencl_fp16" => quote do Evision.cv_DNN_TARGET_OPENCL_FP16() end, "vulkan" => quote do Evision.cv_DNN_TARGET_VULKAN() end, } end def available_backend_and_target do backends = backends() targets = targets() {backend_options, target_options} = Enum.reduce(Map.to_list(backends), {[], []}, fn {backend_value, {backend_id, backend_label, _}}, {backend_options, target_options} -> available_targets = Evision.DNN.getAvailableTargets(backend_id) if Enum.count(available_targets) == 0 do {backend_options, target_options} else target_options = Enum.reduce(available_targets, target_options, fn t, target_options -> target = Map.get(targets, t) if target do [target | target_options] else target_options end end) backend_options = [%{value: backend_value, label: backend_label} | backend_options] {backend_options, target_options} end end) {Enum.reverse(backend_options), Enum.reverse(target_options)} end def to_quoted_backend_and_target(attrs) do backend = attrs["backend"] backends = backends() selected_backend = Map.get(backends, backend) backend = if selected_backend do elem(selected_backend, 2) else quote do Evision.cv_DNN_BACKEND_OPENCV() end end targets_reverse_lookup = targets_reverse_lookup() target = attrs["target"] selected_target = Map.get(targets_reverse_lookup, target) target = if selected_target do selected_target else quote do Evision.cv_DNN_TARGET_CPU() end end {backend, target} end end