Skip to content

intel-mkl-tool executable #20

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 9 commits into from
Nov 30, 2019
Merged
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
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Generated by Cargo
# will have compiled files and executables
/target/
target/

# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock
31 changes: 5 additions & 26 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,26 +1,5 @@
[package]
name = "intel-mkl-src"
version = "0.4.1"
authors = ["Toshiki Teramura <[email protected]>"]
edition = "2018"

description = "Redistribution of Intel(R) MKL as a crate"
repository = "https://github.com/termoshtt/rust-intel-mkl"
keywords = ["fft", "blas", "lapack"]
license-file = "License.txt"
readme = "README.md"

build = "build.rs"
links = "mkl_intel_lp64"

exclude = ["mkl_lib/mkl.tar.xz"]

[build-dependencies]
pkg-config = "0.3.16"
failure = "0.1.6"
xz2 = "0.1.6"
tar = "0.4.26"
curl = "0.4.25"

[dev-dependencies]
libc = "0.2.65"
[workspace]
members = [
"intel-mkl-src",
"intel-mkl-tool",
]
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -21,6 +21,12 @@ Be sure to set `PKG_CONFIG_PATH` and `LD_LIBRARY_PATH` correctly.
For debian and ubuntu users, [ci/Dockerfile](ci/Dockerfile) may be helpful.
Windows is not supported yet.

## `use-shared` feature

(Optional, Experimental) This feature uses `$XDG_DATA_HOME/intel-mkl-tool` directory for downloading Intel-MKL.
You can share this directory among several projects using `intel-mkl-src` crate.
This will reduce disk occupancy and downloading time.

## License
MKL is distributed under the Intel Simplified Software License for Intel(R) Math Kernel Library, See [License.txt](License.txt).
Some wrapper codes are licensed by MIT License (see the header of each file).
92 changes: 0 additions & 92 deletions build.rs

This file was deleted.

31 changes: 31 additions & 0 deletions intel-mkl-src/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
[package]
name = "intel-mkl-src"
version = "0.4.1"
authors = ["Toshiki Teramura <[email protected]>"]
edition = "2018"

description = "Redistribution of Intel(R) MKL as a crate"
repository = "https://github.com/termoshtt/rust-intel-mkl"
keywords = ["fft", "blas", "lapack"]
license-file = "License.txt"
readme = "README.md"

build = "build.rs"
links = "mkl_intel_lp64"

exclude = ["mkl_lib/mkl.tar.xz"]

[features]
default = []
use-shared = []

[build-dependencies]
failure = "0.1"

[build-dependencies.intel-mkl-tool]
version = "0.1.0"
path = "../intel-mkl-tool"
default-features = false

[dev-dependencies]
libc = "0.2.65"
44 changes: 44 additions & 0 deletions intel-mkl-src/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// MIT License
//
// Copyright (c) 2017 Toshiki Teramura
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

use failure::*;
use std::{env, path::*};

fn main() -> Fallible<()> {
let out_dir = if let Some(path) = intel_mkl_tool::seek_pkg_config() {
path
} else {
let out_dir = if cfg!(feature = "use-shared") {
intel_mkl_tool::home_library_path()
} else {
PathBuf::from(env::var("OUT_DIR").unwrap())
};

intel_mkl_tool::download(&out_dir)?;
out_dir
};
println!("cargo:rustc-link-search={}", out_dir.display());
println!("cargo:rustc-link-lib=mkl_intel_lp64");
println!("cargo:rustc-link-lib=mkl_sequential");
println!("cargo:rustc-link-lib=mkl_core");
Ok(())
}
File renamed without changes.
File renamed without changes.
27 changes: 27 additions & 0 deletions intel-mkl-tool/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
[package]
name = "intel-mkl-tool"
version = "0.1.0"
authors = ["Toshiki Teramura <[email protected]>"]
edition = "2018"

[features]
default = ["cli"]
cli = ["structopt", "env_logger"]

[dependencies]
curl = "0.4.25"
failure = "0.1.6"
pkg-config = "0.3.17"
tar = "0.4.26"
xz2 = "0.1.6"
log = "0.4.8"
dirs = "*"

# CLI
structopt = { version = "0.3.4", optional = true }
env_logger = { version = "0.7.1", optional = true }

[[bin]]
name = "intel-mkl-tool"
path = "src/cli.rs"
required-features = ["cli"]
49 changes: 49 additions & 0 deletions intel-mkl-tool/src/cli.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
use failure::*;
use std::{env, path::PathBuf};
use structopt::StructOpt;

/// CLI tool for intel-mkl crate
#[derive(Debug, StructOpt)]
enum Opt {
/// Download Intel-MKL library
Download {
/// Install destination. Default is `$XDG_DATA_HOME/intel-mkl-tool`
path: Option<PathBuf>,
},
/// Seek Intel-MKL library
///
/// 1. pkg-config
/// 2. `$XDG_DATA_HOME/intel-mkl-tool`
/// will be sought.
Seek {},
}

fn main() -> Fallible<()> {
env::set_var("RUST_LOG", "info");
env_logger::init();

let opt = Opt::from_args();

match opt {
Opt::Download { path } => {
let path = if let Some(path) = path {
path
} else {
intel_mkl_tool::home_library_path()
};
intel_mkl_tool::download(&path)?;
}
Opt::Seek {} => {
if let Some(path) = intel_mkl_tool::seek_pkg_config() {
println!("{}", path.display());
return Ok(());
}
if let Some(path) = intel_mkl_tool::seek_home() {
println!("{}", path.display());
return Ok(());
}
bail!("Intel-MKL not found.");
}
}
Ok(())
}
89 changes: 89 additions & 0 deletions intel-mkl-tool/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
use curl::easy::Easy;
use failure::*;
use log::*;
use std::{
fs,
io::{self, Write},
path::*,
};

const S3_ADDR: &'static str = "https://s3-ap-northeast-1.amazonaws.com/rust-intel-mkl";

#[cfg(target_os = "linux")]
mod mkl {
pub const ARCHIVE: &'static str = "mkl_linux.tar.xz";
pub const EXT: &'static str = "so";
pub const PREFIX: &'static str = "lib";
}

#[cfg(target_os = "macos")]
mod mkl {
pub const ARCHIVE: &'static str = "mkl_osx.tar.xz";
pub const EXT: &'static str = "dylib";
pub const PREFIX: &'static str = "lib";
}

#[cfg(target_os = "windows")]
mod mkl {
pub const ARCHIVE: &'static str = "mkl_windows64.tar.xz";
pub const EXT: &'static str = "lib";
pub const PREFIX: &'static str = "";
}

pub fn home_library_path() -> PathBuf {
dirs::data_local_dir().unwrap().join("intel-mkl-tool")
}

pub fn seek_pkg_config() -> Option<PathBuf> {
if let Ok(lib) = pkg_config::probe_library("mkl-dynamic-lp64-iomp") {
if lib.libs.len() > 1 {
warn!("Found {} MKL libraries. Use first found.", lib.libs.len())
}
return Some(PathBuf::from(lib.libs[0].clone()));
}
None
}

pub fn seek_home() -> Option<PathBuf> {
let home_lib = home_library_path();
if home_lib.is_dir() {
return Some(home_lib);
}
None
}

pub fn download(out_dir: &Path) -> Fallible<()> {
if !out_dir.exists() {
info!("Create output directory: {}", out_dir.display());
fs::create_dir_all(out_dir)?;
}
if !out_dir.is_dir() {
bail!("Not a directory: {}", out_dir.display());
}

let archive = out_dir.join(mkl::ARCHIVE);
if !archive.exists() {
info!("Download archive from AWS S3: {}/{}", S3_ADDR, mkl::ARCHIVE);
let f = fs::File::create(&archive)?;
let mut buf = io::BufWriter::new(f);
let mut easy = Easy::new();
easy.url(&format!("{}/{}", S3_ADDR, mkl::ARCHIVE))?;
easy.write_function(move |data| Ok(buf.write(data).unwrap()))?;
easy.perform()?;
assert!(archive.exists());
} else {
info!("Archive already exists: {}", archive.display());
}

let core = out_dir.join(format!("{}mkl_core.{}", mkl::PREFIX, mkl::EXT));
if !core.exists() {
let f = fs::File::open(&archive)?;
let de = xz2::read::XzDecoder::new(f);
let mut arc = tar::Archive::new(de);
arc.unpack(&out_dir)?;
assert!(core.exists());
} else {
info!("Archive has already been extracted");
}
Ok(())
}