44
55using System . IO ;
66using Microsoft . Data . DataView ;
7- using Microsoft . ML . Model ;
7+ using Microsoft . ML ;
8+ using Microsoft . ML . Data ;
9+
10+ [ assembly: LoadableClass ( CompositeDataLoader < IMultiStreamSource , ITransformer > . Summary , typeof ( CompositeDataLoader < IMultiStreamSource , ITransformer > ) , null , typeof ( SignatureLoadModel ) ,
11+ "Composite Loader" , CompositeDataLoader < IMultiStreamSource , ITransformer > . LoaderSignature ) ]
812
913namespace Microsoft . ML . Data
1014{
@@ -15,6 +19,10 @@ namespace Microsoft.ML.Data
1519 public sealed class CompositeDataLoader < TSource , TLastTransformer > : IDataLoader < TSource >
1620 where TLastTransformer : class , ITransformer
1721 {
22+ private const string LoaderDirectory = "Loader" ;
23+ private const string LegacyLoaderDirectory = "Reader" ;
24+ private const string TransformerDirectory = TransformerChain . LoaderSignature ;
25+
1826 /// <summary>
1927 /// The underlying data loader.
2028 /// </summary>
@@ -33,6 +41,24 @@ public CompositeDataLoader(IDataLoader<TSource> loader, TransformerChain<TLastTr
3341 Transformer = transformerChain ?? new TransformerChain < TLastTransformer > ( ) ;
3442 }
3543
44+ private CompositeDataLoader ( IHost host , ModelLoadContext ctx )
45+ {
46+ if ( ! ctx . LoadModelOrNull < IDataLoader < TSource > , SignatureLoadModel > ( host , out Loader , LegacyLoaderDirectory ) )
47+ ctx . LoadModel < IDataLoader < TSource > , SignatureLoadModel > ( host , out Loader , LoaderDirectory ) ;
48+ ctx . LoadModel < TransformerChain < TLastTransformer > , SignatureLoadModel > ( host , out Transformer , TransformerDirectory ) ;
49+ }
50+
51+ private static CompositeDataLoader < TSource , TLastTransformer > Create ( IHostEnvironment env , ModelLoadContext ctx )
52+ {
53+ Contracts . CheckValue ( env , nameof ( env ) ) ;
54+ IHost h = env . Register ( LoaderSignature ) ;
55+
56+ h . CheckValue ( ctx , nameof ( ctx ) ) ;
57+ ctx . CheckAtModel ( GetVersionInfo ( ) ) ;
58+
59+ return h . Apply ( "Loading Model" , ch => new CompositeDataLoader < TSource , TLastTransformer > ( h , ctx ) ) ;
60+ }
61+
3662 /// <summary>
3763 /// Produce the data view from the specified input.
3864 /// Note that <see cref="IDataView"/>'s are lazy, so no actual loading happens here, just schema validation.
@@ -62,6 +88,16 @@ public CompositeDataLoader<TSource, TNewLast> AppendTransformer<TNewLast>(TNewLa
6288 return new CompositeDataLoader < TSource , TNewLast > ( Loader , Transformer . Append ( transformer ) ) ;
6389 }
6490
91+ void ICanSaveModel . Save ( ModelSaveContext ctx )
92+ {
93+ Contracts . CheckValue ( ctx , nameof ( ctx ) ) ;
94+ ctx . CheckAtModel ( ) ;
95+ ctx . SetVersionInfo ( GetVersionInfo ( ) ) ;
96+
97+ ctx . SaveModel ( Loader , LoaderDirectory ) ;
98+ ctx . SaveModel ( Transformer , TransformerDirectory ) ;
99+ }
100+
65101 /// <summary>
66102 /// Save the contents to a stream, as a "model file".
67103 /// </summary>
@@ -76,47 +112,27 @@ public void SaveTo(IHostEnvironment env, Stream outputStream)
76112 using ( var rep = RepositoryWriter . CreateNew ( outputStream , ch ) )
77113 {
78114 ch . Trace ( "Saving data loader" ) ;
79- ModelSaveContext . SaveModel ( rep , Loader , "Reader" ) ;
115+ ModelSaveContext . SaveModel ( rep , Loader , LoaderDirectory ) ;
80116
81117 ch . Trace ( "Saving transformer chain" ) ;
82- ModelSaveContext . SaveModel ( rep , Transformer , TransformerChain . LoaderSignature ) ;
118+ ModelSaveContext . SaveModel ( rep , Transformer , TransformerDirectory ) ;
83119 rep . Commit ( ) ;
84120 }
85121 }
86122 }
87- }
88123
89- /// <summary>
90- /// Utility class to facilitate loading from a stream.
91- /// </summary>
92- [ BestFriend ]
93- internal static class CompositeDataLoader
94- {
95- /// <summary>
96- /// Save the contents to a stream, as a "model file".
97- /// </summary>
98- public static void SaveTo < TSource > ( this IDataLoader < TSource > loader , IHostEnvironment env , Stream outputStream )
99- => new CompositeDataLoader < TSource , ITransformer > ( loader ) . SaveTo ( env , outputStream ) ;
124+ internal const string Summary = "A loader that encapsulates a loader and a transformer chain." ;
100125
101- /// <summary>
102- /// Load the pipeline from stream.
103- /// </summary>
104- public static CompositeDataLoader < IMultiStreamSource , ITransformer > LoadFrom ( IHostEnvironment env , Stream stream )
126+ internal const string LoaderSignature = "CompositeLoader" ;
127+ private static VersionInfo GetVersionInfo ( )
105128 {
106- Contracts . CheckValue ( env , nameof ( env ) ) ;
107- env . CheckValue ( stream , nameof ( stream ) ) ;
108-
109- env . Check ( stream . CanRead && stream . CanSeek , "Need a readable and seekable stream to load" ) ;
110- using ( var rep = RepositoryReader . Open ( stream , env ) )
111- using ( var ch = env . Start ( "Loading pipeline" ) )
112- {
113- ch . Trace ( "Loading data loader" ) ;
114- ModelLoadContext . LoadModel < IDataLoader < IMultiStreamSource > , SignatureLoadModel > ( env , out var loader , rep , "Reader" ) ;
115-
116- ch . Trace ( "Loader transformer chain" ) ;
117- ModelLoadContext . LoadModel < TransformerChain < ITransformer > , SignatureLoadModel > ( env , out var transformerChain , rep , TransformerChain . LoaderSignature ) ;
118- return new CompositeDataLoader < IMultiStreamSource , ITransformer > ( loader , transformerChain ) ;
119- }
129+ return new VersionInfo (
130+ modelSignature : "CMPSTLDR" ,
131+ verWrittenCur : 0x00010001 , // Initial
132+ verReadableCur : 0x00010001 ,
133+ verWeCanReadBack : 0x00010001 ,
134+ loaderSignature : LoaderSignature ,
135+ loaderAssemblyName : typeof ( CompositeDataLoader < , > ) . Assembly . FullName ) ;
120136 }
121137 }
122138}
0 commit comments