Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit dbbb31d

Browse files
authoredJun 16, 2020
Merge pull request #43 from rust-math/config-download
New package downloader
2 parents ec55002 + 9aa9cd5 commit dbbb31d

File tree

7 files changed

+112
-87
lines changed

7 files changed

+112
-87
lines changed
 

‎.github/workflows/rust.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ jobs:
4747
runs-on: ubuntu-18.04
4848
strategy:
4949
matrix:
50-
target: ["test", "seek", "package"]
50+
target: ["test", "seek", "package", "download"]
5151
steps:
5252
- uses: actions/checkout@v1
5353
- name: Test with mkl-rust container

‎intel-mkl-tool/Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,6 @@ seek:
1111

1212
package:
1313
docker run $(DOCKER_OPTION) $(IMAGE) cargo run --release -- package
14+
15+
download:
16+
docker run $(DOCKER_OPTION) $(IMAGE) cargo run --release -- download -o ./test_download

‎intel-mkl-tool/src/cli.rs

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,11 @@ use structopt::StructOpt;
99
enum Opt {
1010
/// Download Intel-MKL library
1111
Download {
12-
/// Install destination. Default is `$XDG_DATA_HOME/intel-mkl-tool`
12+
/// Archive name, e.g. "mkl-static-lp64-iomp". Download all archives if None
13+
#[structopt(long = "name")]
14+
name: Option<String>,
15+
/// Install destination. Default is `$XDG_DATA_HOME/intel-mkl-tool/${MKL_VERSION}/`
16+
#[structopt(short = "o", long = "path")]
1317
path: Option<PathBuf>,
1418
},
1519

@@ -22,8 +26,10 @@ enum Opt {
2226

2327
/// Package Intel MKL libraries into an archive
2428
Package {
29+
#[structopt(long = "name")]
2530
name: Option<String>,
26-
out: Option<PathBuf>,
31+
#[structopt(short = "o", long = "path")]
32+
path: Option<PathBuf>,
2733
},
2834
}
2935

@@ -34,13 +40,21 @@ fn main() -> Result<()> {
3440
let opt = Opt::from_args();
3541

3642
match opt {
37-
Opt::Download { path } => {
38-
let path = if let Some(path) = path {
39-
path
43+
Opt::Download { name, path } => {
44+
let path = path.unwrap_or(xdg_home_path());
45+
if let Some(name) = name {
46+
let cfg = Config::from_str(&name)?;
47+
cfg.download(&path.join(cfg.name()))?;
4048
} else {
41-
xdg_home_path()
42-
};
43-
download_default(&path)?;
49+
for cfg in Config::possibles() {
50+
info!(
51+
"Download archive {:<22} into {}",
52+
cfg.name(),
53+
path.display()
54+
);
55+
cfg.download(&path.join(cfg.name()))?;
56+
}
57+
}
4458
}
4559

4660
Opt::Seek {} => {
@@ -56,26 +70,26 @@ fn main() -> Result<()> {
5670
}
5771
}
5872

59-
Opt::Package { name, out } => {
60-
let out = out.unwrap_or(env::current_dir().unwrap());
73+
Opt::Package { name, path } => {
74+
let path = path.unwrap_or(env::current_dir().unwrap());
6175
if let Some(name) = name {
6276
let cfg = Config::from_str(&name)?;
6377
let entry = Entry::from_config(cfg)?;
64-
let out = if let Ok(version) = entry.version() {
65-
out.join(format!("{}.{}", version.0, version.1))
78+
let path = if let Ok(version) = entry.version() {
79+
path.join(format!("{}.{}", version.0, version.1))
6680
} else {
67-
out
81+
path
6882
};
69-
let package = entry.package(&out)?;
83+
let package = entry.package(&path)?;
7084
info!("Pacakge created: {}", package.display());
7185
} else {
7286
for entry in Entry::available() {
73-
let out = if let Ok(version) = entry.version() {
74-
out.join(format!("{}.{}", version.0, version.1))
87+
let path = if let Ok(version) = entry.version() {
88+
path.join(format!("{}.{}", version.0, version.1))
7589
} else {
76-
out.clone()
90+
path.clone()
7791
};
78-
let package = entry.package(&out)?;
92+
let package = entry.package(&path)?;
7993
info!("Pacakge created: {}", package.display());
8094
}
8195
}

‎intel-mkl-tool/src/config.rs

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
use anyhow::*;
2-
use derive_more::Display;
1+
use crate::*;
2+
use curl::easy::Easy;
3+
use derive_more::*;
4+
use std::fs;
35

46
pub const VALID_CONFIGS: &[&str] = &[
57
"mkl-dynamic-ilp64-iomp",
@@ -80,6 +82,13 @@ impl Config {
8082
})
8183
}
8284

85+
pub fn possibles() -> Vec<Self> {
86+
VALID_CONFIGS
87+
.iter()
88+
.map(|name| Self::from_str(name).unwrap())
89+
.collect()
90+
}
91+
8392
/// identifier used in pkg-config
8493
pub fn name(&self) -> String {
8594
format!("mkl-{}-{}-{}", self.link, self.index_size, self.parallel)
@@ -130,6 +139,41 @@ impl Config {
130139
}
131140
}
132141
}
142+
143+
/// Download archive from AWS S3, and expand into `${out_dir}/*.so`
144+
pub fn download<P: AsRef<Path>>(&self, out_dir: P) -> Result<()> {
145+
let out_dir = out_dir.as_ref();
146+
if out_dir.exists() {
147+
fs::create_dir_all(&out_dir)?;
148+
}
149+
let data = read_from_url(&format!("{}/{}.tar.zst", s3_addr(), self.name()))?;
150+
let zstd = zstd::stream::read::Decoder::new(data.as_slice())?;
151+
let mut arc = tar::Archive::new(zstd);
152+
arc.unpack(&out_dir)?;
153+
Ok(())
154+
}
155+
}
156+
157+
/// Helper for download file from URL
158+
///
159+
/// - This function expands obtained data into memory space
160+
///
161+
fn read_from_url(url: &str) -> Result<Vec<u8>> {
162+
let mut data = Vec::new();
163+
let mut handle = Easy::new();
164+
handle.fail_on_error(true)?;
165+
handle.url(url)?;
166+
{
167+
let mut transfer = handle.transfer();
168+
transfer
169+
.write_function(|new_data| {
170+
data.extend_from_slice(new_data);
171+
Ok(new_data.len())
172+
})
173+
.unwrap();
174+
transfer.perform().unwrap();
175+
}
176+
Ok(data)
133177
}
134178

135179
#[cfg(test)]

‎intel-mkl-tool/src/download.rs

Lines changed: 0 additions & 48 deletions
This file was deleted.

‎intel-mkl-tool/src/entry.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use crate::*;
2-
use anyhow::*;
32
use derive_more::Deref;
43
use std::{
54
collections::{HashMap, HashSet},

‎intel-mkl-tool/src/lib.rs

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -90,32 +90,31 @@
9090
//! |mkl_cdft_core | libmkl_cdft_core.so| libmkl_cdft_core.a|
9191
//!
9292
93+
use anyhow::*;
9394
use log::*;
9495
use std::path::*;
9596

9697
mod config;
97-
mod download;
9898
mod entry;
9999

100100
pub use config::*;
101-
pub use download::*;
102101
pub use entry::*;
103102

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

106105
#[cfg(all(target_os = "linux", target_arch = "x86_64"))]
107106
mod mkl {
108-
pub const ARCHIVE: &'static str = "mkl_linux64";
107+
pub const OS: &str = "linux";
109108
pub const EXTENSION_STATIC: &'static str = "a";
110109
pub const EXTENSION_SHARED: &'static str = "so";
111110
pub const PREFIX: &'static str = "lib";
112-
pub const VERSION_YEAR: u32 = 2019;
113-
pub const VERSION_UPDATE: u32 = 5;
111+
pub const VERSION_YEAR: u32 = 2020;
112+
pub const VERSION_UPDATE: u32 = 1;
114113
}
115114

116115
#[cfg(all(target_os = "macos", target_arch = "x86_64"))]
117116
mod mkl {
118-
pub const ARCHIVE: &'static str = "mkl_macos64";
117+
pub const OS: &str = "macos";
119118
pub const EXTENSION_STATIC: &'static str = "a";
120119
pub const EXTENSION_SHARED: &'static str = "dylib";
121120
pub const PREFIX: &'static str = "lib";
@@ -125,29 +124,34 @@ mod mkl {
125124

126125
#[cfg(all(target_os = "windows", target_arch = "x86_64"))]
127126
mod mkl {
128-
pub const ARCHIVE: &'static str = "mkl_windows64";
127+
pub const OS: &str = "windows";
129128
pub const EXTENSION_STATIC: &'static str = "lib";
130129
pub const EXTENSION_SHARED: &'static str = "lib";
131130
pub const PREFIX: &'static str = "";
132131
pub const VERSION_YEAR: u32 = 2019;
133132
pub const VERSION_UPDATE: u32 = 5;
134133
}
135134

136-
pub fn archive_filename() -> String {
135+
fn s3_addr() -> String {
137136
format!(
138-
"{}_{}_{}.tar.zst",
139-
mkl::ARCHIVE,
137+
"{}/{}/{}.{}",
138+
S3_ADDR,
139+
mkl::OS,
140140
mkl::VERSION_YEAR,
141141
mkl::VERSION_UPDATE
142142
)
143143
}
144144

145145
pub fn xdg_home_path() -> PathBuf {
146-
dirs::data_local_dir().unwrap().join("intel-mkl-tool")
146+
dirs::data_local_dir().unwrap().join(format!(
147+
"intel-mkl-tool/{}.{}",
148+
mkl::VERSION_YEAR,
149+
mkl::VERSION_UPDATE
150+
))
147151
}
148152

149153
pub fn seek_pkg_config() -> Option<PathBuf> {
150-
if let Ok(lib) = pkg_config::probe_library("mkl-dynamic-lp64-iomp") {
154+
if let Ok(lib) = pkg_config::probe_library("mkl-dynamic-lp64-seq") {
151155
if lib.libs.len() > 1 {
152156
warn!("Found {} MKL libraries. Use first found.", lib.libs.len())
153157
}
@@ -156,10 +160,19 @@ pub fn seek_pkg_config() -> Option<PathBuf> {
156160
None
157161
}
158162

159-
pub fn seek_home() -> Option<PathBuf> {
160-
let home_lib = xdg_home_path();
161-
if home_lib.is_dir() {
162-
return Some(home_lib);
163+
pub fn download_default<P: AsRef<Path>>(out_dir: P) -> Result<()> {
164+
let cfg = Config::from_str("mkl-dynamic-lp64-seq").unwrap();
165+
cfg.download(out_dir)?;
166+
Ok(())
167+
}
168+
169+
#[cfg(test)]
170+
mod tests {
171+
use super::*;
172+
173+
#[test]
174+
fn download() -> Result<()> {
175+
download_default("./test_download")?;
176+
Ok(())
163177
}
164-
None
165178
}

0 commit comments

Comments
 (0)
Please sign in to comment.