Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Arm64 (and apple M1) #609

Merged
merged 24 commits into from
May 1, 2024
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
b9d1ccd
Progress towards ARM64 support
mseri Apr 10, 2022
8044bb5
Re-introduce Ofast flag
mseri Apr 11, 2022
b5db632
unit_signal: fix test
mseri Apr 11, 2022
ac2e0d7
Update architecture detection
mseri Apr 11, 2022
7a3c434
ocamlformat
mseri Apr 11, 2022
efc51a1
fixup! Update architecture detection
mseri Apr 11, 2022
48a8b0e
Improve architecture and os detection
mseri Apr 12, 2022
ab17a40
config: cleanup unused open
mseri Apr 12, 2022
7f4cc77
reintroduce -mfpmath=sse on x86_64
mseri Apr 12, 2022
69c7e38
owl_macros.h: remove empty if
mseri Apr 14, 2022
0b64902
owl/configure: remove devmode cflags
mseri Apr 14, 2022
729cf00
owl_core_utils: Fix empty elif
mseri Apr 28, 2022
2537f1b
Cleanup arch detection code
mseri Apr 29, 2022
c9a67a4
configure: update to support new lapacke packages
mseri May 11, 2022
7924c34
ocamlformat the code
mseri May 11, 2022
f9b875a
Workaround configurator problem with windows
mseri May 14, 2022
c575988
configurator: make more robust wrt not officially supported platforms…
mseri Jun 2, 2022
954f498
Update src/owl/config/configure.ml
mseri Oct 8, 2022
00e9d33
configurator: drop unnecessary dependency on stdio
mseri Jan 9, 2023
9420a4c
Merge remote-tracking branch 'upstream/main' into arm64
mseri Jan 9, 2023
fac5927
add @jcreinhold patch for nonstandard setups
mseri Oct 27, 2023
8820211
Update src/aeos/config/configure.ml
mseri Oct 31, 2023
d3b5390
Update src/owl/config/configure.ml
mseri Oct 31, 2023
efc7508
Merge remote-tracking branch 'upstream/main' into arm64
mseri Mar 5, 2024
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
8 changes: 4 additions & 4 deletions INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,18 @@ before compilation:
- `OWL_CFLAGS` allows to change the default flags passed to the C targets,
it defaults to
```
OWL_CFLAGS="-g -O3 -Ofast -march=native -mfpmath=sse -funroll-loops -ffast-math -DSFMT_MEXP=19937 -msse2 -fno-strict-aliasing -Wno-tautological-constant-out-of-range-compare"`
OWL_CFLAGS="-g -O3 -Ofast -funroll-loops -ffast-math -DSFMT_MEXP=19937 -msse2 -fno-strict-aliasing"`
```

- `OWL_AEOS_CFLAGS` allows to change the default flags passed to the C targets
when compiling AEOS. It defaults to
```
OWL_AEOS_CFLAGS="-g -O3 -Ofast -march=native -funroll-loops -ffast-math -DSFMT_MEXP=19937 -fno-strict-aliasing"
OWL_AEOS_CFLAGS="-g -O3 -Ofast -funroll-loops -ffast-math -DSFMT_MEXP=19937 -fno-strict-aliasing"
```

- `OWL_DISABLE_LAPACKE_LINKING_FLAG=1` disables the `-llapacke` flag in the
linking options. This is useful when you have lapacke installed on
non-standard location.
linking options. This may be useful when you have certain unusual lapacke
setups, do not use it unless you know what you are doing.

If you are not using `opam`, you should run `make clean` before recompiling
the library after having changed any of those environment variables.
Expand Down
89 changes: 73 additions & 16 deletions src/aeos/config/configure.ml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,45 @@

module C = Configurator.V1

let detect_system_os =
{|
#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"
#else
#define PLATFORM_NAME "unknown"
#endif
mseri marked this conversation as resolved.
Show resolved Hide resolved
|}


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 bgetenv v =
let v' =
try Sys.getenv v |> int_of_string with
Expand All @@ -24,23 +63,43 @@ let get_os_type c =
| None -> ""


let get_default_cflags =
let get_default_cflags c =
try
Sys.getenv "OWL_AEOS_CFLAGS"
|> String.trim
|> String.split_on_char ' '
|> List.filter (fun s -> String.trim s <> "")
with
| Not_found ->
[ "-g"
; "-O3"
; "-Ofast"
; "-march=native"
; "-funroll-loops"
; "-ffast-math"
; "-DSFMT_MEXP=19937"
; "-fno-strict-aliasing"
]
let os =
let platform =
C.C_define.import c ~includes:[ ] ~prelude:detect_system_os [ "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 arch =
C.C_define.import c ~includes:[ ] ~prelude:detect_system_arch [ "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
[ "-g"; "-O3"; "-Ofast" ]
@ (match arch, os with
| `arm64, `mac -> [ "-mcpu=apple-m1" ]
mseri marked this conversation as resolved.
Show resolved Hide resolved
| `x86_64, _ -> [ "-march=native"; "-msse2" ]
| _ -> [])
@ [ "-funroll-loops"; "-ffast-math"; "-DSFMT_MEXP=19937"; "-fno-strict-aliasing" ]


let get_openmp_cflags c =
Expand All @@ -49,11 +108,9 @@ let get_openmp_cflags c =
then []
else (
match get_os_type c with
| "linux" -> [ "-fopenmp" ]
| "linux_elf" -> [ "-fopenmp" ]
| "macosx" -> [ "-Xpreprocessor"; "-fopenmp" ]
| "mingw64" -> [ "-fopenmp" ]
| _ -> [])
| "mingw64" | "linux" | "linux_elf" -> [ "-fopenmp" ]
| "macosx" -> [ "-Xpreprocessor"; "-fopenmp" ]
| _ -> [])


let get_default_libs () = [ "-lm" ]
Expand All @@ -76,7 +133,7 @@ let () =
(* configure link options *)
let libs = [] @ get_default_libs () @ get_openmp_libs c in
(* configure compile options *)
let cflags = [] @ get_default_cflags @ get_openmp_cflags c in
let cflags = [] @ get_default_cflags c @ get_openmp_cflags c in
(* assemble default config *)
let conf : C.Pkg_config.package_conf = { cflags; libs } in
C.Flags.write_sexp "aeos_c_flags.sexp" conf.cflags;
Expand Down
146 changes: 104 additions & 42 deletions src/owl/config/configure.ml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,45 @@

module C = Configurator.V1

let detect_system_os =
{|
#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"
#else
#define PLATFORM_NAME "unknown"
#endif
mseri marked this conversation as resolved.
Show resolved Hide resolved
|}


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 bgetenv v =
let v' =
try Sys.getenv v |> int_of_string with
Expand Down Expand Up @@ -76,31 +115,53 @@ let get_ocaml_devmode_flags _c =
if not enable_devmode then [] else [ "-w"; "-32-27-6-37-3" ]


let default_cflags =
try
Sys.getenv "OWL_CFLAGS"
|> String.trim
|> String.split_on_char ' '
|> List.filter (fun s -> String.trim s <> "")
with
| Not_found ->
[ (* Basic optimisation *)
"-g"
; "-O3"
; "-Ofast"
; (* FIXME: experimental switches *)
(* "-mavx2"; "-mfma"; "-ffp-contract=fast"; *)
(* Experimental switches, -ffast-math may break IEEE754 semantics*)
"-march=native"
; "-mfpmath=sse"
; "-funroll-loops"
; "-ffast-math"
; (* Configure Mersenne Twister RNG *)
"-DSFMT_MEXP=19937"
; "-msse2"
; "-fno-strict-aliasing"
]

let default_config c =
let os =
let platform = C.C_define.import c ~includes:[ ] ~prelude:detect_system_os [ "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 arch = C.C_define.import c ~includes:[ ] ~prelude:detect_system_arch [ "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
let cflags =
try
Sys.getenv "OWL_CFLAGS"
|> String.trim
|> String.split_on_char ' '
|> List.filter (fun s -> String.trim s <> "")
with
| Not_found ->
[ (* Basic optimisation *) "-g"; "-O3"; "-Ofast" ]
@ (match arch, os with
| `arm64, `mac -> [ "-mcpu=apple-m1" ]
mseri marked this conversation as resolved.
Show resolved Hide resolved
| `x86_64, _ -> [ "-march=native"; "-mfpmath=sse"; "-msse2" ]
| _ -> [])
@ [ (* Experimental switches, -ffast-math may break IEEE754 semantics*)
"-funroll-loops"
; "-ffast-math"
; (* Configure Mersenne Twister RNG *)
"-DSFMT_MEXP=19937"
; "-fno-strict-aliasing"
]
in
(* homebrew M1 issue workaround, works only if users use the default homebrew path *)
let libs =
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@samoht something like this one here

let p0 = "/opt/homebrew/opt/gcc/lib/gcc/11/" in
mseri marked this conversation as resolved.
Show resolved Hide resolved
if os = `mac && arch = `arm64 && Sys.file_exists p0 then [ "-L" ^ p0 ] else []
in
C.Pkg_config.{ cflags; libs }

let default_libs = [ "-lm" ]

Expand All @@ -109,13 +170,6 @@ let get_expmode_cflags _c =
if not enable_expmode then [] else [ "-flto" ]


let get_devmode_cflags _c =
let enable_devmode = bgetenv "OWL_ENABLE_DEVMODE" in
if not enable_devmode
then [ "-Wno-logical-op-parentheses" ]
else [ "-Wall"; "-pedantic"; "-Wextra"; "-Wunused" ]


let default_gcc_path =
let p0 = "/usr/local/lib/gcc/7" in
if Sys.file_exists p0 then [ "-L" ^ p0 ] else []
Expand Down Expand Up @@ -184,11 +238,12 @@ the output of `src/owl/config/configure.exe --verbose`.

let () =
C.main ~name:"owl" (fun c ->
let default_config = default_config c in
let default_pkg_config = { C.Pkg_config.cflags = []; libs = [] } in
let cblas_conf =
let default = { C.Pkg_config.cflags = []; libs = [] } in
let open Base.Option.Monad_infix in
Base.Option.value
~default
~default:default_pkg_config
(C.Pkg_config.get c >>= C.Pkg_config.query ~package:"cblas")
in
let openblas_conf =
Expand All @@ -202,7 +257,7 @@ let () =
c
test_linking
~c_flags:openblas_conf.cflags
~link_flags:openblas_conf.libs
~link_flags:(default_config.libs @ openblas_conf.libs)
then (
Printf.printf
{|
Expand All @@ -221,7 +276,7 @@ some details on how your openblas has been installed and the output of
Base.(Sexp.to_string @@ sexp_of_list sexp_of_string openblas_conf.cflags)
Base.(Sexp.to_string @@ sexp_of_list sexp_of_string openblas_conf.libs);
failwith "Unable to link against openblas.");
let lapacke_lib =
let lapacke_conf =
let disable_linking_flag = bgetenv "OWL_DISABLE_LAPACKE_LINKING_FLAG" in
let needs_lapacke_flag =
if disable_linking_flag
Expand All @@ -231,16 +286,23 @@ some details on how your openblas has been installed and the output of
c
test_lapacke_working_code
~c_flags:openblas_conf.cflags
~link_flags:(openblas_conf.libs @ [ "-lm" ])
~link_flags:(default_config.libs @ openblas_conf.libs @ [ "-lm" ])
|> not
in
if needs_lapacke_flag then [ "-llapacke" ] else []
if needs_lapacke_flag
then
let open Base.Option.Monad_infix in
Base.Option.value
~default:C.Pkg_config.{ cflags = []; libs = [ "-llapacke" ] }
(C.Pkg_config.get c >>= C.Pkg_config.query ~package:"llapacke")
else default_pkg_config
in
let openmp_config = get_openmp_config c in
(* configure link options *)
let libs =
[]
@ lapacke_lib
@ default_config.libs
@ lapacke_conf.libs
@ openblas_conf.libs
@ cblas_conf.libs
@ default_libs
Expand All @@ -250,11 +312,11 @@ some details on how your openblas has been installed and the output of
in
(* configure compile options *)
let cflags =
[]
[ "-Wall"; "-pedantic"; "-Wextra"; "-Wunused" ]
@ lapacke_conf.cflags
@ openblas_conf.cflags
@ cblas_conf.cflags
@ default_cflags
@ get_devmode_cflags c
@ default_config.cflags
@ get_expmode_cflags c
@ openmp_config.cflags
in
Expand Down
9 changes: 8 additions & 1 deletion src/owl/core/owl_core_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,13 @@ void c_slicing_offset (struct caml_ba_array *X, int64_t *slice, int64_t *offset)
* Code heavily inspired by Eigen (http://eigen.tuxfamily.org/).
*/


#if defined(__arm__) || defined(__aarch64__)
void query_cache_sizes(int* l1p, int* l2p, int* l3p) {
*l1p = 16 * 1024;
*l2p = 512 * 1024;
*l3p = 512 * 1024;
}
#else
OWL_INLINE void query_cache_sizes_intel(int* l1p, int* l2p, int* l3p) {
int cpuinfo[4];
int l1 = 0, l2 = 0, l3 = 0;
Expand Down Expand Up @@ -295,3 +301,4 @@ void query_cache_sizes(int* l1p, int* l2p, int* l3p) {
*l3p = 512 * 1024;
}
}
#endif
Loading