Skip to content

Commit 2f5766b

Browse files
authored
Merge pull request #3 from relaypro-open/macos
Macos
2 parents 09afeda + 899ac12 commit 2f5766b

File tree

11 files changed

+115
-63
lines changed

11 files changed

+115
-63
lines changed

config/config.exs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,14 @@ config :elixir, :dbg_callback, {Macro, :dbg, []}
55

66
config :ortex,
77
add_backend_on_inspect: config_env() != :test
8+
9+
# Set the cargo feature flags required to use the matching execution provider
10+
# based on the OS we're running on
11+
ortex_features =
12+
case :os.type() do
13+
{:win32, _} -> ["directml"]
14+
{:unix, :darwin} -> ["coreml"]
15+
{:unix, _} -> ["cuda", "tensorrt"]
16+
end
17+
18+
config :ortex, Ortex.Native, features: ortex_features

lib/ortex/native.ex

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,23 @@ defmodule Ortex.Native do
44
55
Stubs for `Rustler` NIFs. These should never be called directly.
66
"""
7+
8+
# We have to compile the crate before `use Rustler` compiles the crate since
9+
# cargo downloads the onnxruntime shared libraries and they are not available
10+
# to load or copy into Elixir's during the on_load or Elixir compile steps.
11+
# In the future, this may be configurable in Rustler.
12+
Rustler.Compiler.compile_crate(__MODULE__, otp_app: :ortex, crate: :ortex)
13+
Ortex.Util.copy_ort_libs()
14+
715
use Rustler,
816
otp_app: :ortex,
917
crate: :ortex
1018

1119
# When loading a NIF module, dummy clauses for all NIF function are required.
1220
# NIF dummies usually just error out when called when the NIF is not loaded, as that should never normally happen.
13-
def init(_model_path, _execution_providers, _optimization_level), do: :erlang.nif_error(:nif_not_loaded)
21+
def init(_model_path, _execution_providers, _optimization_level),
22+
do: :erlang.nif_error(:nif_not_loaded)
23+
1424
def run(_model, _inputs), do: :erlang.nif_error(:nif_not_loaded)
1525
def from_binary(_bin, _shape, _type), do: :erlang.nif_error(:nif_not_loaded)
1626
def to_binary(_reference, _bits, _limit), do: :erlang.nif_error(:nif_not_loaded)

lib/ortex/util.ex

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
defmodule Ortex.Util do
2+
def copy_ort_libs() do
3+
rust_env =
4+
case Mix.env() do
5+
:prod -> "release"
6+
_ -> "debug"
7+
end
8+
9+
case :os.type() do
10+
{:win32, _} ->
11+
Path.wildcard(
12+
Path.join([
13+
"./_build",
14+
Mix.env() |> Atom.to_string(),
15+
"lib/ortex/native/ortex",
16+
rust_env,
17+
"libonnxruntime*.dll*"
18+
])
19+
)
20+
21+
{:unix, :darwin} ->
22+
Path.wildcard(
23+
Path.join([
24+
"./_build/",
25+
Mix.env() |> Atom.to_string(),
26+
"lib/ortex/native/ortex",
27+
rust_env,
28+
"libonnxruntime*.dylib*"
29+
])
30+
)
31+
32+
{:unix, _} ->
33+
Path.wildcard(
34+
Path.join([
35+
"./_build/",
36+
Mix.env() |> Atom.to_string(),
37+
"lib/ortex/native/ortex",
38+
rust_env,
39+
"libonnxruntime*.so*"
40+
])
41+
)
42+
end
43+
|> Enum.map(fn x ->
44+
File.cp!(
45+
x,
46+
Path.join([
47+
"./_build",
48+
Mix.env() |> Atom.to_string(),
49+
"lib/ortex/priv/native/",
50+
Path.basename(x)
51+
])
52+
)
53+
end)
54+
end
55+
end

mix.exs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ defmodule Ortex.MixProject do
1717
main: "readme",
1818
extras: ["README.md"]
1919
],
20-
2120
package: package()
2221
]
2322
end
@@ -34,7 +33,6 @@ defmodule Ortex.MixProject do
3433
[
3534
{:rustler, "~> 0.26.0"},
3635
{:nx, "~>0.5.3"},
37-
# {:dialyxir, "~>1.3.0", only: [:dev], runtime: false},
3836
{:tokenizers, "~> 0.3.0", only: :dev},
3937
{:ex_doc, "0.29.4", only: :dev, runtime: false},
4038
{:axon_onnx, "~>0.4.0", only: :dev},
@@ -51,5 +49,5 @@ defmodule Ortex.MixProject do
5149
links: %{"GitHub" => "https://github.com/relaypro-open/ortex"},
5250
description: "ONNX Runtime bindings for Elixir"
5351
]
54-
end
52+
end
5553
end

native/ortex/.cargo/config.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ rpath=true
88
rustflags = [
99
"-C", "link-arg=-undefined",
1010
"-C", "link-arg=dynamic_lookup",
11+
"-C", "link-args=-Wl,-rpath,@loader_path",
1112
]
1213
[target.x86_64-unknown-linux-gnu]
1314
rustflags = [ "-Clink-args=-Wl,-rpath,$ORIGIN" ]

native/ortex/Cargo.lock

Lines changed: 8 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

native/ortex/Cargo.toml

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,19 @@ crate-type = ["cdylib"]
1111

1212
[dependencies]
1313
rustler = "0.26.0"
14-
ort = {version = "1.14.6", features = ["cuda", "tensorrt"]}
14+
ort = {version = "1.14.6", default-features = false, features = ["half", "copy-dylibs"]}
1515
ndarray = "0.15.6"
1616
half = "2.2.1"
1717
tracing-subscriber = { version = "0.3", features = [ "env-filter", "fmt" ] }
1818
num-traits = "0.2.15"
19+
20+
[features]
21+
default = ["download-binaries"]
22+
23+
download-binaries = ["ort/download-binaries"]
24+
25+
# ONNXRuntime Execution providers
26+
directml = ["ort/directml"]
27+
coreml = ["ort/coreml"]
28+
cuda = ["ort/cuda"]
29+
tensorrt = ["ort/tensorrt"]

native/ortex/src/lib.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,17 @@ use rustler::types::Binary;
1717
use rustler::{Atom, Env, NifResult, Term};
1818

1919
#[rustler::nif(schedule = "DirtyIo")]
20-
fn init(env: Env, model_path: String, eps: Vec<Atom>, opt: i32) -> NifResult<ResourceArc<model::OrtexModel>> {
20+
fn init(
21+
env: Env,
22+
model_path: String,
23+
eps: Vec<Atom>,
24+
opt: i32,
25+
) -> NifResult<ResourceArc<model::OrtexModel>> {
2126
let eps = utils::map_eps(env, eps);
22-
Ok(ResourceArc::new(model::init(model_path, eps, opt).map_err(
23-
|e| rustler::Error::Term(Box::new(e.to_string())),
24-
)?))
27+
Ok(ResourceArc::new(
28+
model::init(model_path, eps, opt)
29+
.map_err(|e| rustler::Error::Term(Box::new(e.to_string())))?,
30+
))
2531
}
2632

2733
#[rustler::nif]

native/ortex/src/model.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ use std::sync::Arc;
1717
use ort::{
1818
environment, execution_providers::ExecutionProvider, session::SessionBuilder,
1919
tensor::InputTensor, LoggingLevel, OrtError,
20-
2120
};
2221
use rustler::resource::ResourceArc;
2322
use rustler::Atom;
@@ -37,7 +36,11 @@ unsafe impl Sync for OrtexModel {}
3736

3837
/// Creates a model given the path to the model and vector of execution providers.
3938
/// The execution providers are Atoms from Erlang/Elixir.
40-
pub fn init(model_path: String, eps: Vec<ExecutionProvider>, opt: i32) -> Result<OrtexModel, OrtError> {
39+
pub fn init(
40+
model_path: String,
41+
eps: Vec<ExecutionProvider>,
42+
opt: i32,
43+
) -> Result<OrtexModel, OrtError> {
4144
// TODO: send tracing logs to erlang/elixir _somehow_
4245
// tracing_subscriber::fmt::init();
4346
let environment = environment::Environment::builder()

python/export_resnet.py

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -16,47 +16,3 @@
1616
dynamic_axes={"input": {0: "batch_size"}, "output": {0: "batch_size"}},
1717
export_params=True,
1818
)
19-
20-
"""
21-
onnx.load("./resnet50.onnx")
22-
...
23-
input {
24-
name: "input"
25-
type {
26-
tensor_type {
27-
elem_type: 1
28-
shape {
29-
dim {
30-
dim_value: -1
31-
}
32-
dim {
33-
dim_value: 3
34-
}
35-
dim {
36-
dim_value: 224
37-
}
38-
dim {
39-
dim_value: 224
40-
}
41-
}
42-
}
43-
}
44-
}
45-
output {
46-
name: "output"
47-
type {
48-
tensor_type {
49-
elem_type: 1
50-
shape {
51-
dim {
52-
dim_value: -1
53-
}
54-
dim {
55-
dim_value: 1000
56-
}
57-
}
58-
}
59-
}
60-
}
61-
}
62-
"""

0 commit comments

Comments
 (0)