1
1
use curl:: easy:: Easy ;
2
2
use failure:: * ;
3
+ use glob:: glob;
3
4
use log:: * ;
4
5
use std:: {
5
6
fs,
6
- io:: { self , Write } ,
7
+ io:: { self , BufRead , Write } ,
7
8
path:: * ,
8
9
} ;
9
10
10
11
const S3_ADDR : & ' static str = "https://s3-ap-northeast-1.amazonaws.com/rust-intel-mkl" ;
11
12
12
- #[ cfg( target_os = "linux" ) ]
13
+ #[ cfg( all ( target_os = "linux" , target_arch = "x86_64" ) ) ]
13
14
mod mkl {
14
- pub const ARCHIVE : & ' static str = "mkl_linux.tar.xz " ;
15
+ pub const ARCHIVE : & ' static str = "mkl_linux64 " ;
15
16
pub const EXT : & ' static str = "so" ;
16
17
pub const PREFIX : & ' static str = "lib" ;
18
+ pub const VERSION_YEAR : u32 = 2019 ;
19
+ pub const VERSION_UPDATE : u32 = 5 ;
17
20
}
18
21
19
- #[ cfg( target_os = "macos" ) ]
22
+ #[ cfg( all ( target_os = "macos" , target_arch = "x86_64" ) ) ]
20
23
mod mkl {
21
- pub const ARCHIVE : & ' static str = "mkl_osx.tar.xz " ;
24
+ pub const ARCHIVE : & ' static str = "mkl_macos64 " ;
22
25
pub const EXT : & ' static str = "dylib" ;
23
26
pub const PREFIX : & ' static str = "lib" ;
27
+ pub const VERSION_YEAR : u32 = 2019 ;
28
+ pub const VERSION_UPDATE : u32 = 3 ;
24
29
}
25
30
26
- #[ cfg( target_os = "windows" ) ]
31
+ #[ cfg( all ( target_os = "windows" , target_arch = "x86_64" ) ) ]
27
32
mod mkl {
28
- pub const ARCHIVE : & ' static str = "mkl_windows64.tar.xz " ;
33
+ pub const ARCHIVE : & ' static str = "mkl_windows64" ;
29
34
pub const EXT : & ' static str = "lib" ;
30
35
pub const PREFIX : & ' static str = "" ;
36
+ pub const VERSION_YEAR : u32 = 2019 ;
37
+ pub const VERSION_UPDATE : u32 = 5 ;
38
+ }
39
+
40
+ pub fn archive_filename ( ) -> String {
41
+ format ! (
42
+ "{}_{}_{}.tar.zst" ,
43
+ mkl:: ARCHIVE ,
44
+ mkl:: VERSION_YEAR ,
45
+ mkl:: VERSION_UPDATE
46
+ )
31
47
}
32
48
33
49
pub fn home_library_path ( ) -> PathBuf {
@@ -61,13 +77,14 @@ pub fn download(out_dir: &Path) -> Fallible<()> {
61
77
bail ! ( "Not a directory: {}" , out_dir. display( ) ) ;
62
78
}
63
79
64
- let archive = out_dir. join ( mkl :: ARCHIVE ) ;
80
+ let archive = out_dir. join ( archive_filename ( ) ) ;
65
81
if !archive. exists ( ) {
66
- info ! ( "Download archive from AWS S3: {}/{}" , S3_ADDR , mkl:: ARCHIVE ) ;
82
+ let url = format ! ( "{}/{}" , S3_ADDR , archive_filename( ) ) ;
83
+ info ! ( "Download archive from AWS S3: {}" , url) ;
67
84
let f = fs:: File :: create ( & archive) ?;
68
85
let mut buf = io:: BufWriter :: new ( f) ;
69
86
let mut easy = Easy :: new ( ) ;
70
- easy. url ( & format ! ( "{}/{}" , S3_ADDR , mkl :: ARCHIVE ) ) ?;
87
+ easy. url ( & url ) ?;
71
88
easy. write_function ( move |data| Ok ( buf. write ( data) . unwrap ( ) ) ) ?;
72
89
easy. perform ( ) ?;
73
90
assert ! ( archive. exists( ) ) ;
@@ -78,7 +95,7 @@ pub fn download(out_dir: &Path) -> Fallible<()> {
78
95
let core = out_dir. join ( format ! ( "{}mkl_core.{}" , mkl:: PREFIX , mkl:: EXT ) ) ;
79
96
if !core. exists ( ) {
80
97
let f = fs:: File :: open ( & archive) ?;
81
- let de = xz2 :: read:: XzDecoder :: new ( f) ;
98
+ let de = zstd :: stream :: read:: Decoder :: new ( f) ? ;
82
99
let mut arc = tar:: Archive :: new ( de) ;
83
100
arc. unpack ( & out_dir) ?;
84
101
assert ! ( core. exists( ) ) ;
@@ -87,3 +104,63 @@ pub fn download(out_dir: &Path) -> Fallible<()> {
87
104
}
88
105
Ok ( ( ) )
89
106
}
107
+
108
+ // Read mkl_version.h to get MKL version (e.g. 2019.5)
109
+ fn get_mkl_version ( version_header : & Path ) -> Fallible < ( u32 , u32 ) > {
110
+ if !version_header. exists ( ) {
111
+ bail ! ( "MKL Version file not found: {}" , version_header. display( ) ) ;
112
+ }
113
+ let f = fs:: File :: open ( version_header) ?;
114
+ let f = io:: BufReader :: new ( f) ;
115
+ let mut year = 0 ;
116
+ let mut update = 0 ;
117
+ for line in f. lines ( ) {
118
+ if let Ok ( line) = line {
119
+ if !line. starts_with ( "#define" ) {
120
+ continue ;
121
+ }
122
+ let ss: Vec < & str > = line. split ( " " ) . collect ( ) ;
123
+ match ss[ 1 ] {
124
+ "__INTEL_MKL__" => year = ss[ 2 ] . parse ( ) ?,
125
+ "__INTEL_MKL_UPDATE__" => update = ss[ 2 ] . parse ( ) ?,
126
+ _ => continue ,
127
+ }
128
+ }
129
+ }
130
+ if year == 0 || update == 0 {
131
+ bail ! ( "Cannot determine MKL versions" ) ;
132
+ }
133
+ Ok ( ( year, update) )
134
+ }
135
+
136
+ pub fn package ( mkl_path : & Path ) -> Fallible < PathBuf > {
137
+ if !mkl_path. exists ( ) {
138
+ bail ! ( "MKL directory not found: {}" , mkl_path. display( ) ) ;
139
+ }
140
+ let ( year, update) = get_mkl_version ( & mkl_path. join ( "include/mkl_version.h" ) ) ?;
141
+ info ! ( "Intel MKL version: {}.{}" , year, update) ;
142
+ let out = PathBuf :: from ( archive_filename ( ) ) ;
143
+ info ! ( "Create archive: {}" , out. display( ) ) ;
144
+
145
+ let shared_libs: Vec < _ > = glob (
146
+ mkl_path
147
+ . join ( format ! ( "lib/intel64/*.{}" , mkl:: EXT ) )
148
+ . to_str ( )
149
+ . unwrap ( ) ,
150
+ ) ?
151
+ . map ( |path| path. unwrap ( ) )
152
+ . collect ( ) ;
153
+ let f = fs:: File :: create ( & out) ?;
154
+ let buf = io:: BufWriter :: new ( f) ;
155
+ let zstd = zstd:: stream:: write:: Encoder :: new ( buf, 6 ) ?;
156
+ let mut ar = tar:: Builder :: new ( zstd) ;
157
+ ar. mode ( tar:: HeaderMode :: Deterministic ) ;
158
+ for lib in & shared_libs {
159
+ info ! ( "Add {}" , lib. display( ) ) ;
160
+ ar. append_path_with_name ( lib, lib. file_name ( ) . unwrap ( ) ) ?;
161
+ }
162
+ let zstd = ar. into_inner ( ) ?;
163
+ zstd. finish ( ) ?;
164
+
165
+ Ok ( out)
166
+ }
0 commit comments