Skip to content

Updated for Julia 1.0, added (limited) auto detection of libraries and avx support #17

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

Merged
merged 30 commits into from
Nov 26, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
3fe449c
MVP workable for Julia 1.2
Crown421 Aug 28, 2019
e7aa947
Made import work
Crown421 Aug 28, 2019
07c9f92
Refactor and automatic library detection
Crown421 Sep 3, 2019
4553f96
Updated Readme
Crown421 Sep 3, 2019
679f45d
Updated Readme again
Crown421 Sep 3, 2019
1217b7a
Apply suggestions from code review
Crown421 Sep 4, 2019
79f1295
Fixed atan with two arguments
Crown421 Sep 6, 2019
b8bde8f
Updated and ran tests
Crown421 Oct 28, 2019
c6265a6
Changed library detection and loading
Crown421 Oct 28, 2019
35d0ef4
Updated Readme
Crown421 Oct 28, 2019
baef2d0
Added library names on windows
Crown421 Nov 13, 2019
127a980
Adding MKL path to Libdl on Mac/Linux
Crown421 Nov 20, 2019
a41c695
first pass, remove Base., simple overload macro
Nov 13, 2019
de1b2fe
more, still untested
Nov 13, 2019
647862a
tests pass
Nov 13, 2019
5767813
tests for overload macro
Nov 13, 2019
b00b360
docstring about matrix exp
Nov 20, 2019
b09949b
spelling
mcabbott Nov 20, 2019
828eafc
Alternative solution, that should actually work
Crown421 Nov 21, 2019
76c6242
Merge pull request #1 from mcabbott/nopiracy
Crown421 Nov 21, 2019
6b2b85a
Made MKL detection more robust
Crown421 Nov 21, 2019
51ea8fb
Updated readme
Crown421 Nov 21, 2019
240d96a
Added test dependency and modified tests
Crown421 Nov 21, 2019
06589c1
First travis file
Crown421 Nov 21, 2019
4b5f6dd
Add AppVeyor and badges
Crown421 Nov 21, 2019
4acb855
Added cis
Crown421 Nov 22, 2019
9b9bac9
Update Readme, fix bug, user-friendly warning in init
Crown421 Nov 22, 2019
1a5450c
Fixed bug
Crown421 Nov 22, 2019
0094836
Fixed loading from intel MKL without MKL.jl
Crown421 Nov 24, 2019
16b0763
Updating Benchmark (#2)
aminya Nov 25, 2019
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
29 changes: 29 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
language: julia

os:
- linux
- osx

julia:
- 1.0
- nightly

branches:
only:
- master
- TravisTesting

before_script:
# Every 30 seconds, look for the build log file. If it exists, then
# start watching its contents and printing them to stdout as they
# change. This has two effects:
# 1. it avoids Travis timing out because the build outputs nothing
# 2. it makes it more obvious what part of the build, if any, gets stuck
# - while sleep 30; do tail ./deps/build.log -f ; done &
- julia --project --color=yes --check-bounds=yes -e 'using Pkg; Pkg.add(PackageSpec(url="https://github.com/JuliaComputing/MKL.jl"));'

script:
#
- export JL_PKG=VML
- julia --color=yes -e "if VERSION < v\"0.7.0-DEV.5183\"; Pkg.clone(pwd()); Pkg.build(\"VML\"); else using Pkg; if VERSION >= v\"1.1.0-rc1\"; Pkg.build(\"VML\"; verbose=true); else Pkg.build(\"VML\"); end; end"
- julia --check-bounds=yes --color=yes -e "if VERSION < v\"0.7.0-DEV.5183\"; Pkg.test(\"VML\", coverage=true); else using Pkg; Pkg.test(coverage=true); end"
17 changes: 17 additions & 0 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name = "VML"
uuid = "c8ce9da6-5d36-5c03-b118-5a70151be7bc"

[deps]
CpuId = "adafc99b-e345-5852-983c-f28acb93d879"
Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb"
SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b"

[compat]
julia = "≥ 0.7 1.0"

[extras]
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
MKL = "33e6dc65-8f57-5167-99aa-e5a354878fb2"

[targets]
test = ["Test", "MKL"]
116 changes: 86 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,60 @@
# VML
# VML
[![Build Status](https://travis-ci.com/Crown421/VML.jl.svg?branch=master)](https://travis-ci.com/Crown421/VML.jl)
[![Build status](https://ci.appveyor.com/api/projects/status/btdduqfsxux8fhsr?svg=true)](https://ci.appveyor.com/project/Crown421/vml-jl)

This package provides bindings to the Intel Vector Math Library for
arithmetic and transcendental functions. It is often substantially
faster than using Julia's built-in functions.

## Using VML.jl

To use VML.jl, you must have the Intel Vector Math Library installed.
This is included in [MKL](http://software.intel.com/en-us/intel-mkl),
which is free for non-commercial use. You must also copy/symlink the
appropriate shared library to a directory known to the linker (e.g.
`/usr/local/lib`) or you must modify the path to `lib` in `src/VML.jl`.

Currently, VML.jl is configured to use `libmkl_vml_avx`, which requires
AVX support. If your system does not have AVX (e.g., most pre-Sandy
Bridge systems), you will need to modify the `const lib` declaration at
the top of `src/VML.jl`. Future versions of VML.jl may automatically
detect CPU architecture.

After loading VML.jl, vector calls to functions listed below will
automatically use VML instead of openlibm when possible.
arithmetic and transcendental functions. Especially for large vectors it is often substantially faster than broadcasting Julia's built-in functions.

## Basic install

To use VML.jl, you must have the shared libraries of the Intel Vector Math Library avilable on your system.
The easiest option is to use [MKL.jl](https://github.com/JuliaComputing/MKL.jl) via
```
julia> ] add https://github.com/JuliaComputing/MKL.jl.git
```
Alternatively you can install MKL directly [from intel](https://software.intel.com/en-us/mkl/choose-download).

Note that intel MKL has a separate license, which you may want to check for commercial projects (see [FAQ]( https://software.intel.com/en-us/mkl/license-faq)).

To install VML.jl run
```
julia> ] add https://github.com/Crown421/VML.jl
```

## Using VML
After loading `VML`, you have the supported function listed below available to call, i.e. `VML.sin(rand(100))`. This should provide a significant speed-up over broadcasting the Base functions.
```
julia> using VML
julia> a = rand(10000);
julia>@time sin.(a);
0.159878 seconds (583.25 k allocations: 30.720 MiB, 2.78% gc time)
julia> @time VML.sin(a);
0.000465 seconds (6 allocations: 781.484 KiB)
```

Most function do currently (julia 1.x) not have a vectorized form, meaning that i.e. `sin(rand(10))` will not work. If you would like to extend the Base function with this functionality you can overload them with the `@overload` macro:
```
julia> @overload sin
julia> @time sin(a);
0.000485 seconds (6 allocations: 781.484 KiB)
```
Note the lack of the broadcasting dot`.` Now calling i.e. `sin` with an array as input will call the VML functions.

#### Note:
Some functions like `exp` and `log` do operate on matrices from Base and refer to the [matrix exponential](https://en.wikipedia.org/wiki/Matrix_exponential) and logarithm. Using `@overload exp` will overwrite this behaviour with element-wise exponentiation/ logarithm.
```
julia> exp([1 1; 1 1.0])
2×2 Array{Float64,2}:
4.19453 3.19453
3.19453 4.19453

julia> VML.exp([1 1; 1 1.0])
2×2 Array{Float64,2}:
2.71828 2.71828
2.71828 2.71828
```

### Accuracy

By default, VML uses `VML_HA` mode, which corresponds to an accuracy of
<1 ulp, matching the accuracy of Julia's built-in openlibm
Expand All @@ -30,7 +65,7 @@ regarding these options is available on
[Intel's website](http://software.intel.com/sites/products/documentation/hpc/mkl/vml/vmldata.htm).

## Performance

(These results are currently outdated and will be updated in due course)
![VML Performance Comparison](/benchmark/performance.png)

![VML Complex Performance Comparison](/benchmark/performance_complex.png)
Expand All @@ -43,14 +78,13 @@ VML use only a single core when performing these benchmarks.

## Supported functions

VML.jl supports the following functions, currently for Float32 and
Float64 only. While VML also offers operators for complex numbers,
these are not yet implemented in VML.jl.
VML.jl supports the following functions, most for Float32 and
Float64, while some also take complex numbers.

### Unary functions

Allocating forms have signature `f(A)`. Mutating forms have signatures
`f!(A)` (in place) and `f!(out, A)` (out of place).
`f!(A)` (in place) and `f!(out, A)` (out of place). The last 9 functions have been moved from Base to `SpecialFunctions.jl` or have no Base equivalent.

Allocating | Mutating
-----------|---------
Expand Down Expand Up @@ -82,6 +116,8 @@ Allocating | Mutating
`erfc` | `erfc!`
`erfinv` | `erfinv!`
`efcinv` | `efcinv!`
`gamma` | `gamma!`
`lgamma` | `lgamma!`
`inv_cbrt` | `inv_cbrt!`
`inv_sqrt` | `inv_sqrt!`
`pow2o3` | `pow2o3!`
Expand All @@ -90,12 +126,32 @@ Allocating | Mutating
### Binary functions

Allocating forms have signature `f(A, B)`. Mutating forms have
signature `f!(out, A, B)`. These functions fall back on broadcasting
when
signature `f!(out, A, B)`.

Allocating | Mutating
-----------|---------
`atan2` | `atan2!`
`atan` | `atan!`
`hypot` | `hypot!`
`.^` | `pow!`
`./` | `divide!`
`pow` | `pow!`
`divide` | `divide!`


## Next steps
Next steps for this package
* [x] Windows support
* [x] Basic Testing
* [x] Avoiding overloading base and optional overload function
* [ ] Updating Benchmarks
* [x] Travis and AppVeyor testing
* [x] Adding CIS function
* [ ] Add tests for mutating functions



## Advanced
VML.jl works via Libdl which loads the relevant shared libraries. Libdl automatically finds the relevant libraries if the location of the binaries has been added to the system search paths.
This already taken care of if you use MKL.jl, but the stand-alone may require you to source `mklvars.sh`. The default command on Mac and Ubuntu is `source /opt/intel/mkl/bin/mklvars.sh intel64`. You may want to add this to your `.bashrc`.
Adding a new `*.conf` file in `/etc/ld.so.conf.d` also works, as the `intel-mkl-slim` package in the AUR does automatically.

Further, VML.jl uses [CpuId.jl](https://github.com/m-j-w/CpuId.jl) to detect if your processor supports the newer `avx2` instructions, and if not defaults to `libmkl_vml_avx`. If your system does not have AVX this package will currently not work for you.
If the CPU feature detection does not work for you, please open an issue.
1 change: 0 additions & 1 deletion REQUIRE

This file was deleted.

45 changes: 45 additions & 0 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@

environment:
matrix:
- julia_version: 1
- julia_version: nightly

platform:
# - x86 # 32-bit
- x64 # 64-bit

# # Uncomment the following lines to allow failures on nightly julia
# # (tests will run but not make your overall status red)
matrix:
allow_failures:
- julia_version: nightly

branches:
only:
- master
# - AppVeyor

notifications:
- provider: Email
on_build_success: false
on_build_failure: false
on_build_status_changed: false

install:
- ps: iex ((new-object net.webclient).DownloadString("https://raw.githubusercontent.com/JuliaCI/Appveyor.jl/version-1/bin/install.ps1"))

build_script:
- C:\julia\bin\julia -e "using Pkg; Pkg.add(PackageSpec(url=\"https://github.com/JuliaComputing/MKL.jl\"));"
- echo "%JL_BUILD_SCRIPT%"
- C:\julia\bin\julia -e "%JL_BUILD_SCRIPT%"

test_script:
- echo "%JL_TEST_SCRIPT%"
- C:\julia\bin\julia -e "%JL_TEST_SCRIPT%"

# # Uncomment to support code coverage upload. Should only be enabled for packages
# # which would have coverage gaps without running on Windows
# on_success:
# - echo "%JL_CODECOV_SCRIPT%"
# - C:\julia\bin\julia -e "%JL_CODECOV_SCRIPT%"

1 change: 1 addition & 0 deletions benchmark/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.jld2
Loading