11use tf;
2- use libc:: c_int;
2+ use libc:: { c_char, c_int} ;
3+ use std:: ffi:: CString ;
34use std:: marker;
5+ use std:: path:: Path ;
46use std:: ptr;
57use super :: Code ;
68use super :: DataType ;
@@ -32,6 +34,45 @@ impl Session {
3234 }
3335 }
3436
37+ /// Loads a session from an exported model.
38+ pub fn from_saved_model < P : AsRef < Path > , Tag : AsRef < str > , Tags : IntoIterator < Item = Tag > >
39+ ( options : & SessionOptions ,
40+ tags : Tags ,
41+ graph : & mut Graph ,
42+ export_dir : P )
43+ -> Result < Self > {
44+ let mut status = Status :: new ( ) ;
45+
46+ let export_dir_cstr =
47+ try!( export_dir. as_ref ( )
48+ . to_str ( )
49+ . and_then ( |s| CString :: new ( s. as_bytes ( ) ) . ok ( ) )
50+ . ok_or_else ( || invalid_arg ! ( "Invalid export directory path" ) ) ) ;
51+
52+ let tags_cstr: Vec < _ > = try!( tags. into_iter ( )
53+ . map ( |t| CString :: new ( t. as_ref ( ) ) )
54+ . collect :: < :: std:: result:: Result < _ , _ > > ( )
55+ . map_err ( |_| invalid_arg ! ( "Invalid tag name" ) ) ) ;
56+ // keeping tags_cstr to retain strings in memory
57+ let tags_ptr: Vec < * const c_char > = tags_cstr. iter ( ) . map ( |t| t. as_ptr ( ) ) . collect ( ) ;
58+
59+ let inner = unsafe {
60+ tf:: TF_LoadSessionFromSavedModel ( options. inner ,
61+ ptr:: null ( ) ,
62+ export_dir_cstr. as_ptr ( ) ,
63+ tags_ptr. as_ptr ( ) ,
64+ tags_ptr. len ( ) as c_int ,
65+ graph. inner ( ) ,
66+ ptr:: null_mut ( ) ,
67+ status. inner ( ) )
68+ } ;
69+ if inner. is_null ( ) {
70+ Err ( status)
71+ } else {
72+ Ok ( Session { inner : inner } )
73+ }
74+ }
75+
3576 /// Closes the session.
3677 pub fn close ( & mut self ) -> Result < ( ) > {
3778 let mut status = Status :: new ( ) ;
@@ -143,19 +184,19 @@ impl<'l> StepWithGraph<'l> {
143184 index : c_int ,
144185 tensor : & ' l Tensor < T > ) {
145186 self . input_ports . push ( tf:: TF_Output {
146- oper : operation. inner ( ) ,
147- index : index,
148- } ) ;
187+ oper : operation. inner ( ) ,
188+ index : index,
189+ } ) ;
149190 self . input_tensors . push ( tensor. inner ) ;
150191 }
151192
152193 /// Requests that an output is fetched from the graph after running this step.
153194 /// Returns an index that you can then use to fetch this output from the step after running it.
154195 pub fn request_output ( & mut self , operation : & Operation , index : c_int ) -> OutputToken {
155196 self . output_ports . push ( tf:: TF_Output {
156- oper : operation. inner ( ) ,
157- index : index,
158- } ) ;
197+ oper : operation. inner ( ) ,
198+ index : index,
199+ } ) ;
159200 self . output_tensors . push ( ptr:: null_mut ( ) ) ;
160201 OutputToken { index : self . output_tensors . len ( ) - 1 }
161202 }
@@ -172,13 +213,13 @@ impl<'l> StepWithGraph<'l> {
172213 {}",
173214 output_idx,
174215 self . output_tensors. len( ) ) )
175- . unwrap ( ) ) ;
216+ . unwrap ( ) ) ;
176217 }
177218 if self . output_tensors [ output_idx] . is_null ( ) {
178219 return Err ( Status :: new_set ( Code :: Unavailable ,
179220 "Output not available. Either it was already taken, or \
180221 this step has not been sucessfully run yet.")
181- . unwrap ( ) ) ;
222+ . unwrap ( ) ) ;
182223 }
183224 let actual_data_type = self . output_data_type ( output_idx) . unwrap ( ) ;
184225 if actual_data_type != T :: data_type ( ) {
@@ -260,13 +301,13 @@ mod tests {
260301 let y = {
261302 let mut nd = g. new_operation ( "Mul" , "y" ) . unwrap ( ) ;
262303 nd. add_input ( Output {
263- operation : & two,
264- index : 0 ,
265- } ) ;
304+ operation : & two,
305+ index : 0 ,
306+ } ) ;
266307 nd. add_input ( Output {
267- operation : & x,
268- index : 0 ,
269- } ) ;
308+ operation : & x,
309+ index : 0 ,
310+ } ) ;
270311 nd. finish ( ) . unwrap ( )
271312 } ;
272313 let options = SessionOptions :: new ( ) ;
0 commit comments