Skip to content
Closed
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
21 changes: 19 additions & 2 deletions intel-mkl-src/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,36 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

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

fn main() {
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()
intel_mkl_tool::xdg_home_path()
} else {
PathBuf::from(env::var("OUT_DIR").expect("Failed to get OUT_DIR"))
};

intel_mkl_tool::download(&out_dir).expect("Failed to downalod Intel-MKL archive");
if cfg!(feature = "static") {
download(
&out_dir,
mkl::ARCHIVE_STATIC,
mkl::VERSION_YEAR,
mkl::VERSION_UPDATE,
)
.expect("Failed to downalod Intel-MKL archive");
} else {
download(
&out_dir,
mkl::ARCHIVE_SHARED,
mkl::VERSION_YEAR,
mkl::VERSION_UPDATE,
)
.expect("Failed to downalod Intel-MKL archive");
}
out_dir
};
println!("cargo:rustc-link-search={}", out_dir.display());
Expand Down
6 changes: 1 addition & 5 deletions intel-mkl-tool/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ cli = ["structopt", "env_logger"]
[dependencies]
anyhow = "1.0.31"
curl = "0.4.25"
derive_more = "0.99.7"
dirs = "2.0.2"
glob = "0.3.0"
log = "0.4.8"
Expand All @@ -26,8 +27,3 @@ zstd = "0.5.1"
# CLI
structopt = { version = "0.3.5", optional = true }
env_logger = { version = "0.7.1", optional = true }

[[bin]]
name = "intel-mkl-tool"
path = "src/cli.rs"
required-features = ["cli"]
71 changes: 71 additions & 0 deletions intel-mkl-tool/src/bin/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
use anyhow::*;
use intel_mkl_tool::*;
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>,
/// Version of Intel MKL
year: Option<u32>,
/// Version of Intel MKL
update: Option<u32>,
},

/// Seek Intel-MKL library
///
/// 1. pkg-config
/// 2. `$XDG_DATA_HOME/intel-mkl-tool`
/// will be sought.
Seek {},

/// Package Intel MKL libraries into an archive
Package { path: PathBuf },
}

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

let opt = Opt::from_args();

match opt {
Opt::Download { path, year, update } => {
let path = path.unwrap_or(xdg_home_path());
let year = year.unwrap_or(mkl::VERSION_YEAR);
let update = update.unwrap_or(intel_mkl_tool::mkl::VERSION_UPDATE);
download(&path, mkl::ARCHIVE_SHARED, year, update)?;
download(&path, mkl::ARCHIVE_STATIC, year, update)?;
}

Opt::Seek {} => {
println!("pkg-config");
println!("-----------");
for (name, _lib) in intel_mkl_tool::seek_pkg_config() {
println!("- {}", name);
}

let title = format!(
"xdg-data-home (base = {})",
intel_mkl_tool::xdg_home_path().display()
);
println!(
"\n{}\n{}",
title,
std::str::from_utf8(vec!('-' as u8; title.len() + 1).as_slice()).unwrap()
);
for (name, _path) in intel_mkl_tool::seek_xdg_home() {
println!("- {}", name);
}
}

Opt::Package { path } => {
let _out = intel_mkl_tool::package(&path)?;
}
}
Ok(())
}
58 changes: 0 additions & 58 deletions intel-mkl-tool/src/cli.rs

This file was deleted.

195 changes: 195 additions & 0 deletions intel-mkl-tool/src/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
use anyhow::*;
use derive_more::Display;
use std::path::*;

#[derive(Debug, Clone, Copy, PartialEq, Display)]
pub enum Link {
#[display(fmt = "static")]
Static,
#[display(fmt = "dynamic")]
Shared,
}

#[derive(Debug, Clone, Copy, PartialEq, Display)]
pub enum IndexSize {
#[display(fmt = "lp64")]
LP64,
#[display(fmt = "ilp64")]
ILP64,
}

#[derive(Debug, Clone, Copy, PartialEq, Display)]
pub enum Parallel {
#[display(fmt = "iomp")]
OpenMP,
#[display(fmt = "seq")]
Sequential,
}

#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Config {
link: Link,
index_size: IndexSize,
parallel: Parallel,
}

impl Config {
pub fn from_str(name: &str) -> Result<Self> {
let parts: Vec<_> = name.split("-").collect();
if parts.len() != 4 {
bail!("Invalid name: {}", name);
}

if parts[0] != "mkl" {
bail!("Name must start with 'mkl': {}", name);
}

let link = match parts[1] {
"static" => Link::Static,
"dynamic" => Link::Shared,
another => bail!("Invalid link spec: {}", another),
};

let index_size = match parts[2] {
"lp64" => IndexSize::LP64,
"ilp64" => IndexSize::ILP64,
another => bail!("Invalid index spec: {}", another),
};

let parallel = match parts[3] {
"iomp" => Parallel::OpenMP,
"seq" => Parallel::Sequential,
another => bail!("Invalid parallel spec: {}", another),
};

Ok(Config {
link,
index_size,
parallel,
})
}

/// identifier used in pkg-config
pub fn name(&self) -> String {
format!("mkl-{}-{}-{}", self.link, self.index_size, self.parallel)
}

fn base_dir(&self) -> PathBuf {
todo!()
}

/// Static and shared library lists to be linked
pub fn libs(
&self,
) -> (
Vec<PathBuf>, /* static */
Vec<String>, /* shared */
) {
// FIXME this implementation is for Linux, fix for Windows and macOS
let mut static_libs = Vec::new();
let mut shared_libs = vec!["pthread".into(), "m".into(), "dl".into()];

let mut add = |name: &str| match self.link {
Link::Static => {
let base_dir: PathBuf = self.base_dir();
let path = base_dir.join(format!("lib{}.a", name));
assert!(path.exists());
static_libs.push(path);
}
Link::Shared => {
shared_libs.push(name.to_string());
}
};

add("mkl_core");
match self.index_size {
IndexSize::LP64 => {
add("mkl_intel_lp64");
}
IndexSize::ILP64 => {
add("mkl_intel_ilp64");
}
};
match self.parallel {
Parallel::OpenMP => {
add("iomp5");
add("mkl_intel_thread");
}
Parallel::Sequential => {
add("mkl_sequential");
}
};
(static_libs, shared_libs)
}

/// Check if pkg-config has a corresponding setting
pub fn pkg_config(&self) -> Option<pkg_config::Library> {
pkg_config::Config::new()
.cargo_metadata(false)
.probe(&self.name())
.ok()
}

/// Check if archive is cached in $XDG_DATA_HOME
pub fn exists(&self) -> bool {
todo!()
}

/// Download MKL archive and cache into $XDG_DATA_HOME
pub fn download(&self) -> PathBuf {
todo!()
}

pub fn print_cargo_metadata(&self) {
todo!()
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn name_to_config() -> Result<()> {
let cfg = Config::from_str("mkl-static-lp64-iomp")?;
assert_eq!(
cfg,
Config {
link: Link::Static,
index_size: IndexSize::LP64,
parallel: Parallel::OpenMP
}
);
Ok(())
}

#[test]
fn name_to_config_to_name() -> Result<()> {
let valid_names = [
"mkl-dynamic-ilp64-iomp",
"mkl-dynamic-ilp64-seq",
"mkl-dynamic-lp64-iomp",
"mkl-dynamic-lp64-seq",
"mkl-static-ilp64-iomp",
"mkl-static-ilp64-seq",
"mkl-static-lp64-iomp",
"mkl-static-lp64-seq",
];
for name in &valid_names {
let cfg = Config::from_str(name)?;
assert_eq!(&cfg.name(), name);
}
Ok(())
}

#[test]
fn invalid_names() -> Result<()> {
assert!(Config::from_str("").is_err());
assert!(Config::from_str("static-lp64-iomp").is_err());
assert!(Config::from_str("mkll-static-lp64-iomp").is_err());
assert!(Config::from_str("mkl-sttic-lp64-iomp").is_err());
assert!(Config::from_str("mkl-static-l64-iomp").is_err());
assert!(Config::from_str("mkl-static-lp64-omp").is_err());
Ok(())
}
}
Loading