Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 4 additions & 19 deletions .github/workflows/workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ jobs:
- ubuntu-20.04
- windows-latest
ocaml-version:
- 4.10.1
- 4.11.1
- 4.10.x
- 4.13.x

env:
OCAML_VERSION: ${{ matrix.ocaml-version }}
Expand All @@ -23,25 +23,10 @@ jobs:

steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v3

- name: Cached Infra
uses: actions/cache@v2
env:
cache-name: cached-opam
with:
path: |
~/.opam
_build
C:\cygwin
D:/a/eigen/eigen
key: ${{ matrix.os }}-${{ matrix.ocaml-version }}-${{ env.cache-name }}-${{ hashFiles('**/*.opam*') }}
restore-keys: |
${{ matrix.os }}-${{ matrix.ocaml-version }}-${{ env.cache-name }}-
${{ matrix.os }}-${{ matrix.ocaml-version }}-
${{ matrix.os }}-
- name: Use OCaml ${{ matrix.ocaml-version }}
uses: avsm/setup-ocaml@v1
uses: avsm/setup-ocaml@v2
with:
ocaml-version: ${{ matrix.ocaml-version }}

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ If you have questions or suggestions, please contact me via [Email](liang.wang@c

## Optional configuration

You can customise the optimization flags used to compile the C++ libeigen by setting `EIGENCPP_OPTFLAGS`, the default value is
You can customise the optimization flags used to compile the C++ libeigen by setting `EIGENCPP_OPTFLAGS`, the default value for `x86_64` is
```
EIGENCPP_OPTFLAGS = -Ofast -march=native -funroll-loops -ffast-math
```

Similarly you can customise the optimization flags used to compile the eigen library by setting `EIGEN_FLAGS`, the default value is
Similarly you can customise the optimization flags used to compile the eigen library by setting `EIGEN_FLAGS`, the default value for `x86_64` is
```
EIGEN_FLAGS = -O3 -Ofast -march=native -funroll-loops -ffast-math
```
Expand Down
1 change: 1 addition & 0 deletions eigen.opam
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ depends: [
"ocaml" {>= "4.02"}
"ctypes" {>= "0.14.0"}
"dune" {>= "2.0.0"}
"dune-configurator"
]
synopsis: "Owl's OCaml interface to Eigen3 C++ library"
description:
Expand Down
106 changes: 106 additions & 0 deletions eigen/configure/configure.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
(*
* OWL - OCaml Scientific and Engineering Computing
* Copyright (c) 2016-2022 Liang Wang <[email protected]>
*)

module C = Configurator.V1

let detect_system_header =
{|
#if __APPLE__
#include <TargetConditionals.h>
#if TARGET_OS_IPHONE
#define PLATFORM_NAME "ios"
#else
#define PLATFORM_NAME "mac"
#endif
#elif __linux__
#if __ANDROID__
#define PLATFORM_NAME "android"
#else
#define PLATFORM_NAME "linux"
#endif
#elif WIN32
#define PLATFORM_NAME "windows"
#endif
|}

let detect_system_arch =
{|
#if __x86_64__
#define PLATFORM_ARCH "x86_64"
#elif __i386__
#define PLATFORM_ARCH "x86"
#elif __aarch64__
#define PLATFORM_ARCH "arm64"
#elif __arm__
#define PLATFORM_ARCH "arm"
#else
#define PLATFORM_ARCH "unknown"
#endif
|}

let default_cflags c =
try
Sys.getenv "EIGEN_FLAGS"
|> String.split_on_char ' '
|> List.filter (fun s -> String.trim s <> "")
with
| Not_found ->
let os =
let header =
let file = Filename.temp_file "discover" "os.h" in
let fd = open_out file in
output_string fd detect_system_header;
close_out fd;
file
in
let platform =
C.C_define.import c ~includes:[ header ] [ "PLATFORM_NAME", String ]
in
match List.map snd platform with
| [ String "android" ] -> `android
| [ String "ios" ] -> `ios
| [ String "linux" ] -> `linux
| [ String "mac" ] -> `mac
| [ String "windows" ] -> `windows
| _ -> `unknown
in
let arch =
let header =
let file = Filename.temp_file "discover" "arch.h" in
let fd = open_out file in
output_string fd detect_system_arch;
close_out fd;
file
in
let arch =
C.C_define.import c ~includes:[ header ] [ "PLATFORM_ARCH", String ]
in
match List.map snd arch with
| [ String "x86_64" ] -> `x86_64
| [ String "x86" ] -> `x86
| [ String "arm64" ] -> `arm64
| [ String "arm" ] -> `arm
| _ -> `unknown
in
[ (* Basic optimisation *) "-g"; "-O3"; "-Ofast" ]
@ (match arch, os with
| `arm64, `mac -> [ "-mcpu=apple-m1" ]
| `arm64, _ -> [ "-march=native" ]
| `x86_64, _ -> [ "-march=native"; "-mfpmath=sse"; "-msse2" ]
| _ -> [])
@ [ (* Experimental switches, -ffast-math may break IEEE754 semantics*)
"-funroll-loops"
; "-ffast-math"
]

let () =
C.main ~name:"eigen" (fun c ->
(* configure compile options *)
let libs = [] in
let cflags = default_cflags c in
(* configure ocaml options *)
(* assemble default config *)
let conf : C.Pkg_config.package_conf = { cflags; libs } in
C.Flags.write_sexp "c_flags.sexp" conf.cflags)
3 changes: 3 additions & 0 deletions eigen/configure/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
(executable
(name configure)
(libraries dune.configurator))
36 changes: 14 additions & 22 deletions eigen/dune
Original file line number Diff line number Diff line change
@@ -1,32 +1,25 @@
(* -*- tuareg -*- *)

let eigen_flags =
match Sys.getenv "EIGEN_FLAGS" with
| s -> String.trim s
| exception Not_found -> "-O3 -Ofast -march=native -funroll-loops -ffast-math"

let () = Printf.ksprintf Jbuild_plugin.V1.send {|
(rule
(targets ffi_eigen_generated.ml)
(deps ../bindings/ffi_eigen_stubgen.exe)
(action
(with-stdout-to
%%{targets}
(run %%{deps} -ml)
)
)
)
%{targets}
(run %{deps} -ml))))

(rule
(targets ffi_eigen_generated_stub.c)
(deps ../bindings/ffi_eigen_stubgen.exe)
(action
(with-stdout-to
%%{targets}
(run %%{deps} -c)
)
)
)
%{targets}
(run %{deps} -c))))

(rule
(targets c_flags.sexp)
(deps
(:deps-conf configure/configure.exe))
(action
(run %{deps-conf})))

(library
(name eigen)
Expand All @@ -38,7 +31,6 @@ let () = Printf.ksprintf Jbuild_plugin.V1.send {|
(language c)
(names eigen_utils_stubs ffi_eigen_generated_stub)
(include_dirs ../eigen_cpp/lib)
(flags :standard %s)
)
)
|} eigen_flags
(flags
:standard
(:include c_flags.sexp))))
111 changes: 111 additions & 0 deletions eigen_cpp/configure/configure.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
(*
* OWL - OCaml Scientific and Engineering Computing
* Copyright (c) 2016-2022 Liang Wang <[email protected]>
*)

module C = Configurator.V1

let detect_system_header =
{|
#if __APPLE__
#include <TargetConditionals.h>
#if TARGET_OS_IPHONE
#define PLATFORM_NAME "ios"
#else
#define PLATFORM_NAME "mac"
#endif
#elif __linux__
#if __ANDROID__
#define PLATFORM_NAME "android"
#else
#define PLATFORM_NAME "linux"
#endif
#elif WIN32
#define PLATFORM_NAME "windows"
#endif
|}

let detect_system_arch =
{|
#if __x86_64__
#define PLATFORM_ARCH "x86_64"
#elif __i386__
#define PLATFORM_ARCH "x86"
#elif __aarch64__
#define PLATFORM_ARCH "arm64"
#elif __arm__
#define PLATFORM_ARCH "arm"
#else
#define PLATFORM_ARCH "unknown"
#endif
|}

let default_cppflags c =
try
String.trim (Sys.getenv "EIGEN_OPTFLAGS")
|> String.split_on_char ' '
|> List.filter (fun s -> String.trim s <> "")
with
| Not_found ->
let os =
let header =
let file = Filename.temp_file "discover" "os.h" in
let fd = open_out file in
output_string fd detect_system_header;
close_out fd;
file
in
let platform =
C.C_define.import c ~includes:[ header ] [ "PLATFORM_NAME", String ]
in
match List.map snd platform with
| [ String "android" ] -> `android
| [ String "ios" ] -> `ios
| [ String "linux" ] -> `linux
| [ String "mac" ] -> `mac
| [ String "windows" ] -> `windows
| _ -> `unknown
in
let arch =
let header =
let file = Filename.temp_file "discover" "arch.h" in
let fd = open_out file in
output_string fd detect_system_arch;
close_out fd;
file
in
let arch =
C.C_define.import c ~includes:[ header ] [ "PLATFORM_ARCH", String ]
in
match List.map snd arch with
| [ String "x86_64" ] -> `x86_64
| [ String "x86" ] -> `x86
| [ String "arm64" ] -> `arm64
| [ String "arm" ] -> `arm
| _ -> `unknown
in
[
"-fPIC"
; "-ansi"
; "-pedantic"
; "-O3"
; "-std=c++11"
; "-lstdc++"
] @ (match arch, os with
| `arm64, `mac -> [ "-mcpu=apple-m1" ]
| `arm64, _ -> [ "-march=native" ]
| `x86_64, _ -> [ "-march=native"; "-mfpmath=sse"; "-msse2" ]
| _ -> [])
@ [ (* Experimental switches, -ffast-math may break IEEE754 semantics*)
"-funroll-loops"
; "-ffast-math"
]

let () =
C.main ~name:"eigen_cpp" (fun c ->
(* configure compile options *)
let libs = [] in
let cflags = default_cppflags c in
(* assemble default config *)
let conf : C.Pkg_config.package_conf = { cflags; libs } in
C.Flags.write_sexp "cpp_flags.sexp" conf.cflags)
5 changes: 5 additions & 0 deletions eigen_cpp/configure/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
(include_subdirs no)

(executable
(name configure)
(libraries dune.configurator))
38 changes: 9 additions & 29 deletions eigen_cpp/dune
Original file line number Diff line number Diff line change
@@ -1,37 +1,17 @@
(* -*- tuareg -*- *)

let optflags =
match Sys.getenv "EIGENCPP_OPTFLAGS" with
| s ->
s
| exception Not_found ->
"-Ofast -march=native -funroll-loops -ffast-math"

let devflags =
match Sys.getenv "EIGENCPP_DIAGNOSTIC" with
| s -> "-Wall -Wno-invalid-partial-specialization -Wno-extern-c-compat -Wno-c++11-long-long -Wno-ignored-attributes "^s
| exception Not_found -> "-w -Wno-invalid-partial-specialization"

let () = Printf.ksprintf Jbuild_plugin.V1.send {|

(include_subdirs unqualified)

(rule
(targets cpp_flags.sexp)
(deps
(:deps-conf configure/configure.exe))
(action
(run %{deps-conf})))

(foreign_library
(archive_name eigen_cpp_stubs)
(language cxx)
(names eigen_tensor eigen_dsmat eigen_spmat)
(include_dirs lib lib/unsupported)
(flags
:standard
-fPIC
-ansi
-pedantic
-O3
-std=c++11
-lstdc++
%s
%s
)
)

|} devflags optflags
:standard
(:include cpp_flags.sexp)))
Loading