Skip to content

Replace methods to common traits #79

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 5 commits into from
Aug 1, 2022
Merged
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
2 changes: 1 addition & 1 deletion intel-mkl-src/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

use anyhow::{bail, Result};
use intel_mkl_tool::*;
use std::{env, path::PathBuf};
use std::{env, path::PathBuf, str::FromStr};

#[cfg(feature = "mkl-static-lp64-iomp")]
const MKL_CONFIG: &str = "mkl-static-lp64-iomp";
Expand Down
12 changes: 4 additions & 8 deletions intel-mkl-tool/src/cli.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use anyhow::{bail, Result};
use intel_mkl_tool::*;
use std::{env, path::PathBuf};
use std::{env, path::PathBuf, str::FromStr};
use structopt::StructOpt;

/// CLI tool for intel-mkl crate
Expand Down Expand Up @@ -40,15 +40,11 @@ fn main() -> Result<()> {
let path = path.unwrap_or(xdg_home_path());
if let Some(name) = name {
let cfg = Config::from_str(&name)?;
cfg.download(&path.join(cfg.name()))?;
cfg.download(&path.join(cfg.to_string()))?;
} else {
for cfg in Config::possibles() {
println!(
"Download archive {:<22} into {}",
cfg.name(),
path.display()
);
cfg.download(&path.join(cfg.name()))?;
println!("Download archive {:<22} into {}", cfg, path.display());
cfg.download(&path.join(cfg.to_string()))?;
}
}
}
Expand Down
178 changes: 128 additions & 50 deletions intel-mkl-tool/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use anyhow::{bail, Result};
use derive_more::Display;
use std::{fmt, str::FromStr};

pub const VALID_CONFIGS: &[&str] = &[
"mkl-dynamic-ilp64-iomp",
Expand All @@ -12,86 +12,164 @@ pub const VALID_CONFIGS: &[&str] = &[
"mkl-static-lp64-seq",
];

#[derive(Debug, Clone, Copy, PartialEq, Display)]
/// How to link MKL
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum LinkType {
#[display(fmt = "static")]
Static,
#[display(fmt = "dynamic")]
Shared,
Dynamic,
}

impl fmt::Display for LinkType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
LinkType::Static => write!(f, "static"),
LinkType::Dynamic => write!(f, "dynamic"),
}
}
}

#[derive(Debug, Clone, Copy, PartialEq, Display)]
pub enum Interface {
#[display(fmt = "lp64")]
impl Default for LinkType {
fn default() -> Self {
LinkType::Static
}
}

impl FromStr for LinkType {
type Err = anyhow::Error;
fn from_str(input: &str) -> Result<Self> {
Ok(match input {
"static" => LinkType::Static,
"dynamic" => LinkType::Dynamic,
another => bail!("Invalid link spec: {}", another),
})
}
}

/// Data model of library
///
/// Array index of some APIs in MKL are defined by `int` in C,
/// whose size is not fixed.
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum DataModel {
/// `long` and pointer are 64bit, i.e. `sizeof(int) == 4`
LP64,
#[display(fmt = "ilp64")]
/// `int`, `long` and pointer are 64bit, i.e. `sizeof(int) == 8`
ILP64,
}

#[derive(Debug, Clone, Copy, PartialEq, Display)]
impl fmt::Display for DataModel {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
DataModel::LP64 => write!(f, "lp64"),
DataModel::ILP64 => write!(f, "ilp64"),
}
}
}

impl Default for DataModel {
fn default() -> Self {
DataModel::ILP64
}
}

impl FromStr for DataModel {
type Err = anyhow::Error;
fn from_str(input: &str) -> Result<Self> {
Ok(match input {
"lp64" => DataModel::LP64,
"ilp64" => DataModel::ILP64,
another => bail!("Invalid index spec: {}", another),
})
}
}

/// How to manage thread(s)
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Threading {
#[display(fmt = "iomp")]
/// Use iomp5, Intel OpenMP runtime.
OpenMP,
#[display(fmt = "seq")]
/// No OpenMP runtime.
Sequential,
}

/// Configure for linking, downloading and packaging Intel MKL
impl Default for Threading {
fn default() -> Self {
Threading::Sequential
}
}

impl fmt::Display for Threading {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Threading::OpenMP => write!(f, "iomp"),
Threading::Sequential => write!(f, "seq"),
}
}
}

impl FromStr for Threading {
type Err = anyhow::Error;
fn from_str(input: &str) -> Result<Self> {
Ok(match input {
"iomp" => Threading::OpenMP,
"seq" => Threading::Sequential,
another => bail!("Invalid parallel spec: {}", another),
})
}
}

/// Configuration for Intel MKL, e.g. `mkl-static-lp64-seq`
///
/// There are 2x2x2=8 combinations of [LinkType], [DataModel], and [Threading].
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Config {
pub link: LinkType,
pub index_size: Interface,
pub index_size: DataModel,
pub parallel: Threading,
}

impl Config {
pub fn from_str(name: &str) -> Result<Self> {
let parts: Vec<_> = name.split("-").collect();
impl fmt::Display for Config {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "mkl-{}-{}-{}", self.link, self.index_size, self.parallel)
}
}

impl Default for Config {
fn default() -> Self {
Config {
link: LinkType::default(),
index_size: DataModel::default(),
parallel: Threading::default(),
}
}
}

impl FromStr for Config {
type Err = anyhow::Error;
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" => LinkType::Static,
"dynamic" => LinkType::Shared,
another => bail!("Invalid link spec: {}", another),
};

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

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

Ok(Config {
link,
index_size,
parallel,
link: LinkType::from_str(parts[1])?,
index_size: DataModel::from_str(parts[2])?,
parallel: Threading::from_str(parts[3])?,
})
}
}

impl Config {
pub fn possibles() -> Vec<Self> {
VALID_CONFIGS
.iter()
.map(|name| Self::from_str(name).unwrap())
.collect()
}

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

/// Common components
///
/// The order must be following (or equivalent libs)
Expand All @@ -101,10 +179,10 @@ impl Config {
pub fn libs(&self) -> Vec<String> {
let mut libs = Vec::new();
match self.index_size {
Interface::LP64 => {
DataModel::LP64 => {
libs.push("mkl_intel_lp64".into());
}
Interface::ILP64 => {
DataModel::ILP64 => {
libs.push("mkl_intel_ilp64".into());
}
};
Expand All @@ -130,7 +208,7 @@ impl Config {
pub fn additional_libs(&self) -> Vec<String> {
match self.link {
LinkType::Static => Vec::new(),
LinkType::Shared => {
LinkType::Dynamic => {
let mut libs = Vec::new();
for prefix in &["mkl", "mkl_vml"] {
for suffix in &["def", "avx", "avx2", "avx512", "avx512_mic", "mc", "mc3"] {
Expand All @@ -157,7 +235,7 @@ mod tests {
cfg,
Config {
link: LinkType::Static,
index_size: Interface::LP64,
index_size: DataModel::LP64,
parallel: Threading::OpenMP
}
);
Expand All @@ -168,7 +246,7 @@ mod tests {
fn name_to_config_to_name() -> Result<()> {
for name in VALID_CONFIGS {
let cfg = Config::from_str(name)?;
assert_eq!(&cfg.name(), name);
assert_eq!(&cfg.to_string(), name);
}
Ok(())
}
Expand Down
3 changes: 2 additions & 1 deletion intel-mkl-tool/src/download.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ impl Config {
if out_dir.exists() {
fs::create_dir_all(&out_dir)?;
}
let data = read_from_url(&format!("{}/{}.tar.zst", s3_addr(), self.name()))?;
let data = read_from_url(&format!("{}/{}.tar.zst", s3_addr(), self))?;
let zstd = zstd::stream::read::Decoder::new(data.as_slice())?;
let mut arc = tar::Archive::new(zstd);
arc.unpack(&out_dir)?;
Expand Down Expand Up @@ -43,6 +43,7 @@ fn read_from_url(url: &str) -> Result<Vec<u8>> {
#[cfg(test)]
mod tests {
use super::*;
use std::str::FromStr;

macro_rules! impl_test_download {
($name:expr) => {
Expand Down
23 changes: 12 additions & 11 deletions intel-mkl-tool/src/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::{
fs,
io::{self, BufRead},
path::{Path, PathBuf},
str::FromStr,
};

#[derive(Debug, Deref)]
Expand All @@ -21,7 +22,7 @@ impl Targets {
{
let target = match config.link {
LinkType::Static => format!("{}{}.{}", mkl::PREFIX, name, mkl::EXTENSION_STATIC),
LinkType::Shared => format!("{}{}.{}", mkl::PREFIX, name, mkl::EXTENSION_SHARED),
LinkType::Dynamic => format!("{}{}.{}", mkl::PREFIX, name, mkl::EXTENSION_SHARED),
};
targets.insert(target, None);
}
Expand Down Expand Up @@ -88,7 +89,7 @@ impl Entry {
// pkg-config
if let Ok(_) = pkg_config::Config::new()
.cargo_metadata(false)
.probe(&config.name())
.probe(&config.to_string())
{
return Ok(Self {
config,
Expand All @@ -97,11 +98,11 @@ impl Entry {
}

// $XDG_DATA_HOME/intel-mkl-tool
let path = xdg_home_path().join(config.name());
let path = xdg_home_path().join(config.to_string());
targets.seek(&path);

// $MKLROOT
let mkl_root = std::env::var("MKLROOT").map(|path| PathBuf::from(path));
let mkl_root = std::env::var("MKLROOT").map(PathBuf::from);
if let Ok(path) = mkl_root {
if path.exists() {
targets.seek(path.join("lib/intel64"));
Expand All @@ -124,18 +125,18 @@ impl Entry {
}

if targets.found_any() {
return Ok(Self {
Ok(Self {
config,
target: EntryTarget::Manual(targets),
});
})
} else {
// None found
bail!("No library found for {}", config.name());
bail!("No library found for {}", config);
}
}

pub fn name(&self) -> String {
self.config.name()
self.config.to_string()
}

pub fn found_files(&self) -> Vec<(PathBuf, String)> {
Expand Down Expand Up @@ -186,7 +187,7 @@ impl Entry {
if !line.starts_with("#define") {
continue;
}
let ss: Vec<&str> = line.split(" ").collect();
let ss: Vec<&str> = line.split(' ').collect();
match ss[1] {
"__INTEL_MKL__" => year = ss[2].parse()?,
"__INTEL_MKL_UPDATE__" => update = ss[2].parse()?,
Expand Down Expand Up @@ -217,15 +218,15 @@ impl Entry {
LinkType::Static => {
println!("cargo:rustc-link-lib=static={}", lib);
}
LinkType::Shared => {
LinkType::Dynamic => {
println!("cargo:rustc-link-lib=dylib={}", lib);
}
}
}
}
EntryTarget::PkgConfig => {
pkg_config::Config::new()
.probe(&self.config.name())
.probe(&self.config.to_string())
.unwrap();
}
}
Expand Down
Loading