/// <summary> /// Creates a serializer for the given type and settings. /// </summary> /// <typeparam name="TExample">The user type to serialize.</typeparam> /// <param name="settings"></param> /// <returns></returns> public static IVowpalWabbitSerializerCompiler <TExample> CreateSerializer <TExample>(VowpalWabbitSettings settings = null) { Schema schema = null; Type cacheKey = null; if (settings != null && settings.Schema != null) { schema = settings.Schema; } else { // only cache non-string generating serializer if (!settings.EnableStringExampleGeneration) { cacheKey = typeof(TExample); object serializer; if (SerializerCache.TryGetValue(cacheKey, out serializer)) { return((IVowpalWabbitSerializerCompiler <TExample>)serializer); } } ITypeInspector typeInspector = settings.TypeInspector; if (typeInspector == null) { typeInspector = TypeInspector.Default; } // TODO: enhance caching based on feature list & featurizer set // if no feature mapping is provided, use [Feature] annotation on provided type. schema = typeInspector.CreateSchema(settings, typeof(TExample)); var multiExampleSerializerCompiler = VowpalWabbitMultiExampleSerializerCompiler.TryCreate <TExample>(settings, schema); if (multiExampleSerializerCompiler != null) { return(multiExampleSerializerCompiler); } } // need at least a single feature to do something sensible if (schema == null || schema.Features.Count == 0) { return(null); } var newSerializer = new VowpalWabbitSingleExampleSerializerCompiler <TExample>( schema, settings == null ? null : settings.CustomFeaturizer, !settings.EnableStringExampleGeneration); if (cacheKey != null) { SerializerCache[cacheKey] = newSerializer; } return(newSerializer); }
internal VowpalWabbitSingleExampleSerializer(VowpalWabbitSingleExampleSerializerCompiler <TExample> compiler, VowpalWabbit vw) { if (compiler == null) { throw new ArgumentNullException("compiler"); } Contract.Ensures(vw != null); Contract.EndContractBlock(); this.vw = vw; this.compiler = compiler; var exampleType = typeof(TExample); if (!exampleType.IsVisible) { throw new ArgumentException($"Type '{typeof(TExample)}' must be public and all enclosing types must be public."); } this.serializerFunc = compiler.Func(vw); var cacheableAttribute = (CacheableAttribute)typeof(TExample).GetCustomAttributes(typeof(CacheableAttribute), true).FirstOrDefault(); if (cacheableAttribute == null) { return; } if (this.vw.Settings.EnableExampleCaching) { if (cacheableAttribute.EqualityComparer == null) { this.exampleCache = new Dictionary <TExample, CacheEntry>(); } else { if (!typeof(IEqualityComparer <TExample>).IsAssignableFrom(cacheableAttribute.EqualityComparer)) { throw new ArgumentException( string.Format( CultureInfo.InvariantCulture, "EqualityComparer ({1}) specified in [Cachable] of {0} must implement IEqualityComparer<{0}>", typeof(TExample), cacheableAttribute.EqualityComparer)); } var comparer = (IEqualityComparer <TExample>)Activator.CreateInstance(cacheableAttribute.EqualityComparer); this.exampleCache = new Dictionary <TExample, CacheEntry>(comparer); } #if DEBUG this.reverseLookup = new Dictionary <VowpalWabbitExample, CacheEntry>(new ReferenceEqualityComparer <VowpalWabbitExample>()); #endif } }
public VowpalWabbitMultiExampleSerializerCompilerImpl(VowpalWabbitSettings settings, Schema schema, FeatureExpression multiFeature) { Contract.Requires(settings != null); Contract.Requires(schema != null); Contract.Requires(multiFeature != null); var nonMultiFeatures = schema.Features.Where(fe => fe != multiFeature).ToList(); this.sharedSerializerCompiler = nonMultiFeatures.Count == 0 ? null : new VowpalWabbitSingleExampleSerializerCompiler <TExample>( new Schema { Features = nonMultiFeatures }, settings == null ? null : settings.CustomFeaturizer, !settings.EnableStringExampleGeneration); this.adfSerializerComputer = new VowpalWabbitSingleExampleSerializerCompiler <TActionDependentFeature>( settings.TypeInspector.CreateSchema(settings, typeof(TActionDependentFeature)), settings == null ? null : settings.CustomFeaturizer, !settings.EnableStringExampleGeneration); var exampleParameter = Expression.Parameter(typeof(TExample), "example"); // CODE condition1 && condition2 && condition3 ... var condition = multiFeature.ValueValidExpressionFactories .Skip(1) .Aggregate( multiFeature.ValueValidExpressionFactories.First()(exampleParameter), (cond, factory) => Expression.AndAlso(cond, factory(exampleParameter))); var multiExpression = multiFeature.ValueExpressionFactory(exampleParameter); // CODE example => (IEnumerable<TActionDependentFeature>)(example._multi != null ? example._multi : null) var expr = Expression.Lambda <Func <TExample, IEnumerable <TActionDependentFeature> > >( Expression.Condition( condition, multiExpression, Expression.Constant(null, multiExpression.Type), typeof(IEnumerable <TActionDependentFeature>)), exampleParameter); this.adfAccessor = (Func <TExample, IEnumerable <TActionDependentFeature> >)expr.CompileToFunc(); }
/// <summary> /// Creates a serializer for the given type and settings. /// </summary> /// <typeparam name="TExample">The user type to serialize.</typeparam> /// <param name="settings"></param> /// <returns></returns> public static IVowpalWabbitSerializerCompiler <TExample> CreateSerializer <TExample>(VowpalWabbitSettings settings = null) { Schema schema = null; Type cacheKey = null; if (settings != null && settings.Schema != null) { schema = settings.Schema; } else { // only cache non-string generating serializer if (!settings.EnableStringExampleGeneration) { cacheKey = typeof(TExample); object serializer; if (SerializerCache.TryGetValue(cacheKey, out serializer)) { return((IVowpalWabbitSerializerCompiler <TExample>)serializer); } } if (settings.FeatureDiscovery == VowpalWabbitFeatureDiscovery.Json) { schema = AnnotationJsonInspector.CreateSchema(typeof(TExample), settings.PropertyConfiguration); var multiExampleSerializerCompiler = VowpalWabbitMultiExampleSerializerCompiler.TryCreate <TExample>(settings, schema); if (multiExampleSerializerCompiler != null) { return(multiExampleSerializerCompiler); } } else { // TODO: enhance caching based on feature list & featurizer set // if no feature mapping is provided, use [Feature] annotation on provided type. Func <PropertyInfo, FeatureAttribute, bool> propertyPredicate = null; Func <PropertyInfo, LabelAttribute, bool> labelPredicate = null; switch (settings.FeatureDiscovery) { case VowpalWabbitFeatureDiscovery.Default: propertyPredicate = (_, attr) => attr != null; labelPredicate = (_, attr) => attr != null; break; case VowpalWabbitFeatureDiscovery.All: propertyPredicate = (_, __) => true; labelPredicate = (_, __) => true; break; } schema = AnnotationInspector.CreateSchema(typeof(TExample), propertyPredicate, labelPredicate); } } // need at least a single feature to do something sensible if (schema == null || schema.Features.Count == 0) { return(null); } var newSerializer = new VowpalWabbitSingleExampleSerializerCompiler <TExample>( schema, settings == null ? null : settings.CustomFeaturizer, !settings.EnableStringExampleGeneration); if (cacheKey != null) { SerializerCache[cacheKey] = newSerializer; } return(newSerializer); }