Packages

High-performance numerical computing with Eigen backend

Current section

2 Versions

Jump to

Compare versions

8 files changed
+170 additions
-36 deletions
  @@ -6,6 +6,8 @@ project(nx_eigen_nif LANGUAGES CXX)
6 6 set(ERL_INCLUDE_DIR "" CACHE PATH "Path to Erlang/ERTS include directory (contains erl_nif.h)")
7 7 set(EIGEN_DIR "" CACHE PATH "Path to Eigen include directory (contains Eigen/)")
8 8 set(FINE_INCLUDE "" CACHE PATH "Path to Fine C include directory (contains fine.hpp)")
9 + # Output directory for the NIF .so (passed as MIX_APP_PATH/priv by elixir_make)
10 + set(APP_PRIV "" CACHE PATH "Output priv directory (set by elixir_make via MIX_APP_PATH)")
9 11
10 12 set(CMAKE_CXX_STANDARD 17)
11 13 set(CMAKE_CXX_STANDARD_REQUIRED ON)
  @@ -24,9 +26,16 @@ set_target_properties(nx_eigen PROPERTIES
24 26 SUFFIX ".so" # Erlang loads NIFs as .so even on macOS
25 27 )
26 28
27 - # Always place the built NIF exactly where :code.priv_dir expects it.
29 + # Place the built NIF where elixir_make/cc_precompiler expect it.
30 + # APP_PRIV is passed by the Makefile when MIX_APP_PATH is set (elixir_make sets it).
31 + # Fall back to ${CMAKE_SOURCE_DIR}/priv for standalone cmake invocations.
32 + if(NOT APP_PRIV STREQUAL "")
33 + set(NIF_OUTPUT_DIR "${APP_PRIV}")
34 + else()
35 + set(NIF_OUTPUT_DIR "${CMAKE_SOURCE_DIR}/priv")
36 + endif()
28 37 set_target_properties(nx_eigen PROPERTIES
29 - LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/priv"
38 + LIBRARY_OUTPUT_DIRECTORY "${NIF_OUTPUT_DIR}"
30 39 )
31 40
32 41 target_compile_options(nx_eigen PRIVATE -O3)
  @@ -15,7 +15,7 @@ endif
15 15 EIGEN_VERSION = 3.4.0
16 16 EIGEN_DIR ?= $(CURDIR)/eigen-$(EIGEN_VERSION)
17 17 EIGEN_INCLUDE = $(EIGEN_DIR)
18 - FINE_INCLUDE = $(CURDIR)/deps/fine/c_include
18 + FINE_INCLUDE ?= $(error FINE_INCLUDE is not set. Use mix compile instead of bare make.)
19 19
20 20 # FFT library choice
21 21 # The NIF calls a pluggable C interface (see c_src/nx_eigen_fft.h).
  @@ -32,7 +32,7 @@ NX_EIGEN_FFT_LIB ?= fftw
32 32 NX_EIGEN_FFT_SO ?=
33 33
34 34 CFLAGS = -fPIC -I$(ERL_INCLUDE_DIR) -I$(EIGEN_INCLUDE) -I$(FINE_INCLUDE) -Ic_src -O3 -std=c++17
35 - LDFLAGS = -shared
35 + LDFLAGS = -shared -fvisibility=hidden
36 36
37 37 # Resolve FFT sources and link flags
38 38 FFT_SRCS =
  @@ -88,7 +88,11 @@ else
88 88 LDFLAGS += -Wl,-rpath,'$$ORIGIN' -Wl,-rpath,'$$ORIGIN/../lib'
89 89 endif
90 90
91 - LIB_NAME = priv/libnx_eigen.so
91 + # When invoked by elixir_make, MIX_APP_PATH points to _build/env/lib/app.
92 + # Writing the .so there (rather than project-root priv/) is required so that
93 + # cc_precompiler can find the artifact when building the release tarball.
94 + PRIV_DIR = $(if $(MIX_APP_PATH),$(MIX_APP_PATH)/priv,priv)
95 + LIB_NAME = $(PRIV_DIR)/libnx_eigen.so
92 96
93 97 # Optional CMake build (useful for cross-compilation via toolchain files)
94 98 USE_CMAKE ?= 0
  @@ -99,7 +103,7 @@ CMAKE_TOOLCHAIN_FILE ?=
99 103 CMAKE_ARGS ?=
100 104 SKIP_DOWNLOADS ?= 0
101 105
102 - all: check-deps priv $(LIB_NAME)
106 + all: check-deps $(PRIV_DIR) $(LIB_NAME)
103 107
104 108 # Check dependencies without rebuilding
105 109 check-deps:
  @@ -109,17 +113,19 @@ check-deps:
109 113 (echo "Failed to download Eigen. Please install manually or set EIGEN_DIR=/path/to/eigen"; exit 1); \
110 114 fi
111 115
112 - priv:
116 + $(PRIV_DIR):
113 117 @mkdir -p priv
118 + @mkdir -p "$(PRIV_DIR)"
114 119
115 - $(LIB_NAME): c_src/nx_eigen_nif.cpp c_src/nx_eigen_fft.h $(FFT_SRCS) | check-deps priv
120 + $(LIB_NAME): c_src/nx_eigen_nif.cpp c_src/nx_eigen_fft.h $(FFT_SRCS) | check-deps $(PRIV_DIR)
116 121 ifeq ($(USE_CMAKE),1)
117 122 $(CMAKE) -S $(CURDIR) -B $(CMAKE_BUILD_DIR) -DCMAKE_BUILD_TYPE=$(CMAKE_BUILD_TYPE) \
118 123 $(if $(CMAKE_TOOLCHAIN_FILE),-DCMAKE_TOOLCHAIN_FILE=$(CMAKE_TOOLCHAIN_FILE),) \
119 124 $(CMAKE_ARGS) \
120 125 -DERL_INCLUDE_DIR=$(ERL_INCLUDE_DIR) -DEIGEN_DIR=$(EIGEN_DIR) -DFINE_INCLUDE=$(FINE_INCLUDE) \
121 126 -DNX_EIGEN_FFT_LIB=$(NX_EIGEN_FFT_LIB) \
122 - $(if $(NX_EIGEN_FFT_SO),-DNX_EIGEN_FFT_SO=$(NX_EIGEN_FFT_SO),)
127 + $(if $(NX_EIGEN_FFT_SO),-DNX_EIGEN_FFT_SO=$(NX_EIGEN_FFT_SO),) \
128 + $(if $(MIX_APP_PATH),-DAPP_PRIV=$(MIX_APP_PATH)/priv,)
123 129 $(CMAKE) --build $(CMAKE_BUILD_DIR) --config $(CMAKE_BUILD_TYPE) --parallel
124 130 else
125 131 $(CXX) $(CFLAGS) $(FFT_CFLAGS) c_src/nx_eigen_nif.cpp $(FFT_SRCS) $(LDFLAGS) $(FFT_LDFLAGS) -o $(LIB_NAME)
  @@ -1,6 +1,22 @@
1 1 # NxEigen
2 2
3 - An Elixir Nx backend that binds the [Eigen C++ library](https://eigen.tuxfamily.org) for efficient numerical computing on embedded systems, specifically targeting the Arduino Uno Q.
3 + [![CI](https://github.com/polvalente/nx_eigen/actions/workflows/ci.yml/badge.svg)](https://github.com/polvalente/nx_eigen/actions/workflows/ci.yml)
4 + [![Hex.pm](https://img.shields.io/hexpm/v/nx_eigen.svg)](https://hex.pm/packages/nx_eigen)
5 + [![Hexdocs.pm](https://img.shields.io/badge/hex-docs-lightgreen.svg)](https://hexdocs.pm/nx_eigen)
6 +
7 + **High-performance numerical computing for Elixir on embedded systems.**
8 +
9 + NxEigen is an [Nx](https://github.com/elixir-nx/nx) backend that binds the [Eigen C++ library](https://eigen.tuxfamily.org) to provide efficient linear algebra and tensor operations. It's specifically optimized for embedded Linux systems like the Arduino Uno Q, bringing BLAS-like performance without external dependencies.
10 +
11 + ## Why NxEigen?
12 +
13 + - **Native performance**: C++ implementation with Eigen's optimized matrix operations
14 + - **Embedded-ready**: Designed for resource-constrained devices; no heavy dependencies
15 + - **Complete Nx integration**: Drop-in replacement for other Nx backends
16 + - **Hardware acceleration**: Optimized builds for ARM platforms (NEON, crypto extensions)
17 + - **Zero-dependency math**: Includes static-linked FFTW3 in precompiled binaries
18 +
19 + Perfect for running machine learning inference, signal processing, and control algorithms on edge devices.
4 20
5 21 ## Features
6 22
  @@ -384,29 +400,20 @@ Check you have the optimized binary:
384 400 ls ~/.cache/elixir_make/nx_eigen-nif-*
385 401 ```
386 402
387 - ### Documentation
388 -
389 - - **[ARDUINO_UNO_Q_QUICKSTART.md](ARDUINO_UNO_Q_QUICKSTART.md)** - TL;DR setup guide
390 - - **[ARDUINO_UNO_Q.md](ARDUINO_UNO_Q.md)** - Complete deployment guide with examples
391 - - **[TARGET_DETECTION_ISSUE.md](TARGET_DETECTION_ISSUE.md)** - Technical details on target detection
392 -
393 403 ## License
394 404
395 405 Copyright (c) 2025
396 406
397 407 ## Documentation
398 408
399 - ### Quick Links
409 + Full API documentation is available on [HexDocs](https://hexdocs.pm/nx_eigen).
400 410
401 - - **[Arduino Uno Q Setup](ARDUINO_UNO_Q_QUICKSTART.md)** - Arduino Uno Q quick start guide
402 - - **[Precompilation Guide](PRECOMPILATION.md)** - Building precompiled binaries
403 - - **[Testing Precompiled Binaries](TESTING_PRECOMPILED.md)** - Testing precompiled binaries
404 - - **[Documentation Index](DOCUMENTATION_INDEX.md)** - Complete documentation overview
405 -
406 - ### API Documentation
407 -
408 - Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc):
411 + You can also generate documentation locally:
409 412
410 413 ```bash
411 414 mix docs
412 415 ```
416 +
417 + ### Additional Guides
418 +
419 + - **[Precompilation Guide](PRECOMPILATION.md)** - Building precompiled binaries for different platforms
  @@ -1,7 +1,4 @@
1 1 %{
2 - "nx_eigen-nif-2.17-aarch64-apple-darwin-0.1.0.tar.gz" => "sha256:19b2434ada585bdd8625a6a6efe51356155bc669a02f23d40228fc170c1c2c58",
3 - "nx_eigen-nif-2.17-aarch64-arduino-uno-q-linux-gnu-0.1.0.tar.gz" => "sha256:bf7297d3e55001a334aa49b39774a4f7619ba4155d1f8e1be90154e7e3f728b6",
4 - "nx_eigen-nif-2.17-aarch64-linux-gnu-0.1.0.tar.gz" => "sha256:d8d276ed2e8f5b18d2f91fbcf763faa0f9a998bded7095e973d786efced9255d",
5 - "nx_eigen-nif-2.17-x86_64-apple-darwin-0.1.0.tar.gz" => "sha256:1384fd7e53f322014ff3d5fbe69e2c696cd388f93fd8979bed8d698eb220e507",
6 - "nx_eigen-nif-2.17-x86_64-linux-gnu-0.1.0.tar.gz" => "sha256:e464b27433774f3e677d8fde15c570878d394b6b10e2098198271a621fbb2885",
2 + "nx_eigen-nif-2.17-aarch64-apple-darwin-0.1.1.tar.gz" => "sha256:786d066780e6db1570c047b7d3d0770a28387d1bfed34f62febf376d7a785b50",
3 + "nx_eigen-nif-2.17-aarch64-linux-gnu-0.1.1.tar.gz" => "sha256:6e735ff76220f83433bc02f382a91d4c21ff4ff581ede39f917c5430d5d785ac",
7 4 }
  @@ -1,6 +1,6 @@
1 1 {<<"links">>,[{<<"GitHub">>,<<"https://github.com/polvalente/nx_eigen">>}]}.
2 2 {<<"name">>,<<"nx_eigen">>}.
3 - {<<"version">>,<<"0.1.0">>}.
3 + {<<"version">>,<<"0.1.1">>}.
4 4 {<<"description">>,
5 5 <<"High-performance numerical computing with Eigen backend">>}.
6 6 {<<"elixir">>,<<"~> 1.18">>}.
Loading more files…