示例#1
0
        public void TestOptimizationProblemSubgridObjectives()
        {
            Hypergrid cacheSearchSpace = new Hypergrid(
                name: "smart_cache_config",
                dimension: new CategoricalDimension("cache_implementation", 0, 1))
                                         .Join(
                subgrid: new Hypergrid(
                    name: "lru_cache_config",
                    dimension: new DiscreteDimension("cache_size", min: 1, max: 1 << 12)),
                onExternalDimension: new CategoricalDimension("cache_implementation", 0))
                                         .Join(
                subgrid: new Hypergrid(
                    name: "mru_cache_config",
                    dimension: new DiscreteDimension("cache_size", min: 1, max: 1 << 12)),
                onExternalDimension: new CategoricalDimension("cache_implementation", 1));

            var optimizationProblem = new OptimizationProblem
            {
                ParameterSpace = cacheSearchSpace,
                ContextSpace   = null,
                ObjectiveSpace = new Hypergrid(
                    name: "objectives",
                    dimensions: new ContinuousDimension(name: "HitRate", min: 0.0, max: 1.0)),
            };

            optimizationProblem.Objectives.Add(
                new OptimizationObjective(name: "HitRate", minimize: false));

            var serialized   = OptimizerServiceEncoder.EncodeOptimizationProblem(optimizationProblem);
            var deserialized = OptimizerServiceDecoder.DecodeOptimizationProblem(serialized);

            Assert.True(deserialized.Objectives.Count == 1);
            Assert.Equal(deserialized.Objectives[0].Name, optimizationProblem.Objectives[0].Name);
            Assert.True(deserialized.ObjectiveSpace.Dimensions.Count == 1);
        }
示例#2
0
        /// <inheritdoc/>
        public IOptimizationProblem GetOptimizationProblem()
        {
            OptimizerService.OptimizerInfo optimizerInfo = client.GetOptimizerInfo(optimizerHandle);

            Hypergrid contextSpace   = Hypergrid.FromJson(optimizerInfo.OptimizationProblem.ContextSpace?.HypergridJsonString);
            Hypergrid objectiveSpace = Hypergrid.FromJson(optimizerInfo.OptimizationProblem.ObjectiveSpace?.HypergridJsonString);
            Hypergrid parameterSpace = Hypergrid.FromJson(optimizerInfo.OptimizationProblem.ParameterSpace?.HypergridJsonString);

            var optimizationProblem = new OptimizationProblem
            {
                ContextSpace   = contextSpace,
                ObjectiveSpace = objectiveSpace,
                ParameterSpace = parameterSpace,
            };

            // Add optimization objectives.
            //
            optimizationProblem.Objectives.AddRange(
                optimizerInfo.OptimizationProblem.Objectives.Select(r =>
                                                                    new OptimizationObjective
            {
                Minimize = r.Minimize,
                Name     = r.Name,
            }));

            return(optimizationProblem);
        }
示例#3
0
        public void TestOptimizationProblemContext()
        {
            var in1                = new ContinuousDimension("in_1", 0, 10);
            var in2                = new DiscreteDimension("in_2", 1, 20);
            var inputHypergrid     = new Hypergrid("input", in1, in2);
            var out1               = new ContinuousDimension("out_1", -5, 7);
            var objectiveHypergrid = new Hypergrid("output", out1);
            var context1           = new DiscreteDimension("ctx_1", -100, -0);
            var contextHypergrid   = new Hypergrid("context", context1);
            var objectives         = new OptimizationObjective[]
            {
                new OptimizationObjective("out_1", true),
                new OptimizationObjective("nonExistent", false),
            };
            var optimizationProblem = new OptimizationProblem(inputHypergrid, contextHypergrid, objectiveHypergrid, objectives);
            var serialized          = OptimizerServiceEncoder.EncodeOptimizationProblem(optimizationProblem);
            var deserialized        = OptimizerServiceDecoder.DecodeOptimizationProblem(serialized);

            Assert.Equal(optimizationProblem.ParameterSpace.Name, deserialized.ParameterSpace.Name);
            Assert.Equal(optimizationProblem.ObjectiveSpace.Name, deserialized.ObjectiveSpace.Name);
            Assert.Equal(optimizationProblem.ContextSpace.Name, deserialized.ContextSpace.Name);

            Assert.Equal(optimizationProblem.Objectives[0].Name, objectives[0].Name);
            Assert.Equal(optimizationProblem.Objectives[0].Minimize, objectives[0].Minimize);
            Assert.Equal(optimizationProblem.Objectives[1].Name, objectives[1].Name);
            Assert.Equal(optimizationProblem.Objectives[1].Minimize, objectives[1].Minimize);

            // This is not a rigorous test but it should be sufficient given the other tests in this set.
            Assert.Equal(optimizationProblem.ParameterSpace.Dimensions[0].Name, deserialized.ParameterSpace.Dimensions[0].Name);
            Assert.Equal(optimizationProblem.ParameterSpace.Dimensions[1].Name, deserialized.ParameterSpace.Dimensions[1].Name);
            Assert.Equal(optimizationProblem.ObjectiveSpace.Dimensions[0].Name, deserialized.ObjectiveSpace.Dimensions[0].Name);
            Assert.Equal(optimizationProblem.ContextSpace.Dimensions[0].Name, deserialized.ContextSpace.Dimensions[0].Name);
        }
示例#4
0
        public void TestSerializingSimpleHypergrid()
        {
            string originalValidSimpleHypergridJsonString = PythonScriptsAndJsons.SpinlockSearchSpaceJson;

            Hypergrid spinlockSearchSpace = new Hypergrid(
                "SpinlockSearchSpace",
                new DiscreteDimension(name: "shortBackOffMilliSeconds", min: 1, max: 1 << 20),
                new DiscreteDimension(name: "longBackOffMilliSeconds", min: 1, max: 1 << 20),
                new DiscreteDimension(name: "longBackOffWaitMilliSeconds", min: 1, max: 1 << 20),
                new DiscreteDimension(name: "minSpinCount", min: 1, max: 1 << 20),
                new DiscreteDimension(name: "maxSpinCount", min: 1, max: 1 << 20),
                new DiscreteDimension(name: "maxbackOffAttempts", min: 1, max: 1 << 20),
                new DiscreteDimension(name: "acquireSpinCount", min: 1, max: 1 << 20),
                new CategoricalDimension(name: "algorithm", values: new[] { "Optimistic", "ExponentialBackoff" }));
            var jsonSerializerOptions = new JsonSerializerOptions
            {
                WriteIndented = true,
                Converters    =
                {
                    new JsonStringEnumConverter(),
                    new HypergridJsonConverter(),
                    new DimensionJsonConverter(),
                },
            };

            string serializedJsonString = JsonSerializer.Serialize(spinlockSearchSpace, jsonSerializerOptions);

            Assert.Equal(originalValidSimpleHypergridJsonString, serializedJsonString);

            string yetAnotherSerializedJsonString = spinlockSearchSpace.ToJson();

            Assert.Equal(originalValidSimpleHypergridJsonString, yetAnotherSerializedJsonString);
        }
示例#5
0
        public void TestHypergrid()
        {
            var dataDim1     = new object[] { "a", "b", false, 2, 5.8, "c " };
            var dim0         = new CategoricalDimension("dim0", false, "a", "b", false, 2, 5.8, "c ");
            var dim1         = new ContinuousDimension("dim1", 0, 10.2, false, true);
            var hypergrid    = new Hypergrid("hypergrid", dim0, dim1);
            var serialized   = OptimizerServiceEncoder.EncodeHypergrid(hypergrid);
            var deserialized = OptimizerServiceDecoder.DecodeHypergrid(serialized);

            Assert.Equal(deserialized.Name, hypergrid.Name);
            Assert.True(deserialized.Dimensions[0] is CategoricalDimension);
            Assert.True(deserialized.Dimensions[1] is ContinuousDimension);

            Assert.True(
                ((CategoricalDimension)deserialized.Dimensions[0]).Values.SequenceEqual(
                    ((CategoricalDimension)hypergrid.Dimensions[0]).Values));
            Assert.Equal(
                ((ContinuousDimension)deserialized.Dimensions[1]).Name,
                dim1.Name);
            Assert.Equal(
                ((ContinuousDimension)deserialized.Dimensions[1]).Min,
                dim1.Min);
            Assert.Equal(
                ((ContinuousDimension)deserialized.Dimensions[1]).Max,
                dim1.Max);
            Assert.Equal(
                ((ContinuousDimension)deserialized.Dimensions[1]).IncludeMin,
                dim1.IncludeMin);
            Assert.Equal(
                ((ContinuousDimension)deserialized.Dimensions[1]).IncludeMax,
                dim1.IncludeMax);
        }
        /// <inheritdoc/>
        public override Hypergrid.SubgridJoin Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            Expect(ref reader, JsonTokenType.StartObject);

            Expect(ref reader, JsonTokenType.PropertyName, "ObjectType");
            Expect(ref reader, JsonTokenType.String, "GuestSubgrid");

            Expect(ref reader, JsonTokenType.PropertyName, "Subgrid");

            Expect(ref reader, JsonTokenType.StartObject);

            // Subgrid.
            //
            var       hypergridConverter = (JsonConverter <Hypergrid>)options.GetConverter(typeof(Hypergrid));
            Hypergrid hypergrid          = hypergridConverter.Read(ref reader, typeof(Hypergrid), options);

            // Dimension.
            //
            Expect(ref reader, JsonTokenType.PropertyName, "ExternalPivotDimension");
            var        dimensionConverter = (JsonConverter <IDimension>)options.GetConverter(typeof(IDimension));
            IDimension dimension          = dimensionConverter.Read(ref reader, typeof(IDimension), options);

            Expect(ref reader, JsonTokenType.EndObject);

            return(new Hypergrid.SubgridJoin
            {
                OnExternalJoin = dimension,
                Subgrid = hypergrid,
            });
        }
示例#7
0
 public OptimizationProblem(Hypergrid parameterSpace, Hypergrid contextSpace, Hypergrid objectiveSpace, IEnumerable <OptimizationObjective> objectives)
 {
     ParameterSpace = parameterSpace;
     ContextSpace   = contextSpace;
     ObjectiveSpace = objectiveSpace;
     Objectives     = objectives.ToList();
 }
        public static OptimizerService.SimpleHypergrid EncodeHypergrid(Hypergrid hypergrid)
        {
            OptimizerService.SimpleHypergrid instance = new OptimizerService.SimpleHypergrid();

            instance.GuestSubgrids.AddRange(hypergrid.Subgrids.SelectMany(subgridSet => subgridSet.Value.Select(subgrid => EncodeJoinedSubgrid(subgrid))));

            instance.Dimensions.AddRange(hypergrid.Dimensions.Select(dimension => EncodeDimension(dimension)));

            instance.Name = hypergrid.Name;

            return(instance);
        }
        public static Hypergrid DecodeHypergrid(OptimizerService.SimpleHypergrid hypergrid)
        {
            IDimension[] dimensions = hypergrid.Dimensions.Select(dimension => DecodeDimension(dimension)).ToArray();

            var instance = new Hypergrid(name: hypergrid.Name, dimensions: dimensions);

            foreach (var subgrid in hypergrid.GuestSubgrids)
            {
                instance.Join(DecodeHypergrid(subgrid.Subgrid), DecodeDimension(subgrid.ExternalPivotDimension));
            }

            return(instance);
        }
示例#10
0
        public TestSerializingAndDeserializing()
        {
            /* FIXME: This needs better cross-plat support and error handling.
             * - We should include C:\Python37 as another PYTHONHOME location to look for by default
             * - Currently this doesn't handle Linux very well
             * - On Ubuntu Python 3.7 needs to be installed from a separate
             *   repo, which installs as libpython3.7m.so which fails tobe
             *   found due to the trailing "m".
             */

            string pathToVirtualEnv = Environment.GetEnvironmentVariable("PYTHONHOME");

            if (string.IsNullOrEmpty(pathToVirtualEnv))
            {
                pathToVirtualEnv = @"c:\ProgramData\Anaconda3";
            }
            else
            {
                Environment.SetEnvironmentVariable("PYTHONHOME", pathToVirtualEnv, EnvironmentVariableTarget.Process);
            }

            string pathToPythonPkg = $"{pathToVirtualEnv}\\pkgs\\python-3.7.4-h5263a28_0";

            Environment.SetEnvironmentVariable("PATH", $"{pathToVirtualEnv};{pathToPythonPkg}", EnvironmentVariableTarget.Process);
            Environment.SetEnvironmentVariable("PYTHONPATH", $"{pathToVirtualEnv}\\Lib\\site-packages;{pathToVirtualEnv}\\Lib", EnvironmentVariableTarget.Process);

            continuous = new ContinuousDimension(name: "continuous", min: 1, max: 10);
            discrete   = new DiscreteDimension(name: "discrete", min: 1, max: 10);
            ordinal    = new OrdinalDimension(name: "ordinal", orderedValues: new List <object>()
            {
                1, 2, 3, 4, 5, 6, 7, 8, 9, 10
            }, ascending: true);
            categorical = new CategoricalDimension(name: "categorical", values: new List <object>()
            {
                1, 2, 3, 4, 5, 6, 7, 8, 9, 10
            });
            allKindsOfDimensions = new Hypergrid(
                name: "all_kinds_of_dimensions",
                dimensions: new IDimension[]
            {
                continuous,
                discrete,
                ordinal,
                categorical,
            });
        }
示例#11
0
        public void TestOptimizationProblemNoContext()
        {
            var in1                = new ContinuousDimension("in_1", 0, 10);
            var in2                = new DiscreteDimension("in_2", 1, 20);
            var inputHypergrid     = new Hypergrid("input", in1, in2);
            var out1               = new ContinuousDimension("out_1", -5, 7);
            var objectiveHypergrid = new Hypergrid("output", out1);
            var objectives         = new OptimizationObjective[]
            {
                new OptimizationObjective("out_1", true),
                new OptimizationObjective("nonExistent", false),
            };
            var optimizationProblem = new OptimizationProblem(inputHypergrid, objectiveHypergrid, objectives);
            var serialized          = OptimizerServiceEncoder.EncodeOptimizationProblem(optimizationProblem);
            var deserialized        = OptimizerServiceDecoder.DecodeOptimizationProblem(serialized);

            Assert.Null(deserialized.ContextSpace);
        }
示例#12
0
        /// <inheritdoc/>
        public override void Write(Utf8JsonWriter writer, Hypergrid.SubgridJoin value, JsonSerializerOptions options)
        {
            writer.WriteStartObject();

            // Subgrid.
            //
            writer.WriteString("ObjectType", "GuestSubgrid");
            writer.WritePropertyName("Subgrid");
            Hypergrid subgrid = (Hypergrid)value.Subgrid;

            JsonSerializer.Serialize(writer, subgrid, options);

            // Dimensions.
            //
            writer.WritePropertyName("ExternalPivotDimension");
            IDimension dimension = value.OnExternalJoin;

            JsonSerializer.Serialize(writer, dimension, options);

            writer.WriteEndObject();
        }
示例#13
0
        /// <summary>
        /// This is the entry point for setting up the message handlers for the
        /// messages code generated from the (partial) structs defined for this
        /// smart component in the CodeGen/SmartCache.cs.
        /// </summary>
        /// <remarks>
        /// See class comments for further details.
        /// </remarks>
        static AssemblyInitializer()
        {
            // Setup message callbacks.
            //
            // Note: these message properties are code generated from the
            // (partial) structs in CodeGen/SmartCache.cs
            //
            // See out/Mlos.CodeGen.out/SmartCache/*.cs for the C# code
            // generation output from those partial definitions.
            //
            SmartCacheProxy.CacheRequestEventMessage.Callback       = CacheRequestEventMessageHandler;
            SmartCacheProxy.RequestNewConfigurationMessage.Callback = RequestNewConfigurationMessageHandler;

            // Create smart cache parameter search space.
            //
            // These hypergrids define the combination of valid ranges
            // of values for the different tunables.
            // Note that some of these are interdependent.
            //
            // TODO: Eventually this will also be code generated from additional
            // "domain range" attributes on the "ScalarSettings" defined for the
            // component (see also CodeGen/SmartCache.cs)
            //
            Hypergrid cacheSearchSpace = new Hypergrid(
                name: "smart_cache_config",
                dimension: new CategoricalDimension("cache_implementation", CacheEvictionPolicy.LeastRecentlyUsed, CacheEvictionPolicy.MostRecentlyUsed))
                                         .Join(
                subgrid: new Hypergrid(
                    name: "lru_cache_config",
                    dimension: new DiscreteDimension("cache_size", min: 1, max: 1 << 12)),
                onExternalDimension: new CategoricalDimension("cache_implementation", CacheEvictionPolicy.LeastRecentlyUsed))
                                         .Join(
                subgrid: new Hypergrid(
                    name: "mru_cache_config",
                    dimension: new DiscreteDimension("cache_size", min: 1, max: 1 << 12)),
                onExternalDimension: new CategoricalDimension("cache_implementation", CacheEvictionPolicy.MostRecentlyUsed));

            // Create optimization problem.
            //
            // Here we declare to the optimizer what our desired output from the
            // component to optimize is.
            //
            // In this case we declare "hit rate", which will be calculated as a
            // percentage, is the thing we want the optimizer to improve.
            //
            var optimizationProblem = new OptimizationProblem
            {
                ParameterSpace = cacheSearchSpace,
                ContextSpace   = null,
                ObjectiveSpace = new Hypergrid(
                    name: "objectives",
                    dimensions: new ContinuousDimension(name: "HitRate", min: 0.0, max: 1.0)),
            };

            // Define optimization objective.
            //
            optimizationProblem.Objectives.Add(
                new OptimizationObjective
            {
                // Tell the optimizer that we want to maximize hit rate.
                //
                Name     = "HitRate",
                Minimize = false,
            });

            // Get a local reference to the optimizer to reuse when processing messages later on.
            //
            // Note: we read this from a global variable that should have been
            // setup for the Mlos.Agent (e.g. in the Mlos.Agent.Server).
            //
            IOptimizerFactory optimizerFactory = MlosContext.OptimizerFactory;

            OptimizerProxy = optimizerFactory?.CreateRemoteOptimizer(optimizationProblem: optimizationProblem);
        }
示例#14
0
        public void TestPythonInterop()
        {
            var jsonSerializerOptions = new JsonSerializerOptions
            {
                WriteIndented = true,
                Converters    =
                {
                    new JsonStringEnumConverter(),
                    new HypergridJsonConverter(),
                    new DimensionJsonConverter(),
                },
            };

            string csContinuousJsonString      = JsonSerializer.Serialize(continuous, jsonSerializerOptions);
            string csDiscreteJsonString        = JsonSerializer.Serialize(discrete, jsonSerializerOptions);
            string csOrdinalJsonString         = JsonSerializer.Serialize(ordinal, jsonSerializerOptions);
            string csCategoricalJsonString     = JsonSerializer.Serialize(categorical, jsonSerializerOptions);
            string csSimpleHypergridJsonString = JsonSerializer.Serialize(allKindsOfDimensions, jsonSerializerOptions);

            using (Py.GIL())
            {
                using PyScope pythonScope = Py.CreateScope();

                pythonScope.Set("cs_continuous_dimension_json_string", csContinuousJsonString);
                pythonScope.Set("cs_discrete_dimension_json_string", csDiscreteJsonString);
                pythonScope.Set("cs_ordinal_dimension_json_string", csOrdinalJsonString);
                pythonScope.Set("cs_categorical_dimension_json_string", csCategoricalJsonString);
                pythonScope.Set("cs_simple_hypergrid_json_string", csSimpleHypergridJsonString);

                pythonScope.Exec(PythonScriptsAndJsons.CreateDimensionsAndSpacesScript);
                pythonScope.Exec(PythonScriptsAndJsons.DeserializeDimensionsScript);

                bool   successfullyDeserializedDimensions = pythonScope.Get("success").As <bool>();
                string exceptionMessage = string.Empty;
                if (!successfullyDeserializedDimensions)
                {
                    exceptionMessage = pythonScope.Get("exception_message").As <string>();
                }

                Assert.True(successfullyDeserializedDimensions, exceptionMessage);

                pythonScope.Exec(PythonScriptsAndJsons.DeserializeSimpleHypergridScript);

                bool successfullyDeserializedSimpleHypergrid = pythonScope.Get("success").As <bool>();
                if (!successfullyDeserializedSimpleHypergrid)
                {
                    exceptionMessage = pythonScope.Get("exception_message").As <string>();
                }

                Assert.True(successfullyDeserializedSimpleHypergrid, exceptionMessage);

                string    pySimpleHypergridJsonString           = pythonScope.Get("py_simple_hypergrid_json_string").As <string>();
                Hypergrid simpleHypergridDeserializedFromPython = JsonSerializer.Deserialize <Hypergrid>(pySimpleHypergridJsonString, jsonSerializerOptions);

                Assert.True(simpleHypergridDeserializedFromPython.Name == "all_kinds_of_dimensions");
                Assert.True(simpleHypergridDeserializedFromPython.Dimensions.Count == 4);

                string reserializedHypergrid = JsonSerializer.Serialize(simpleHypergridDeserializedFromPython, jsonSerializerOptions);

                pythonScope.Set("cs_reserialized_hypergrid_json_string", reserializedHypergrid);
                pythonScope.Exec(PythonScriptsAndJsons.ValidateReserializedHypergridScript);

                bool successfullyValidatedReserializedHypergrid = pythonScope.Get("success").As <bool>();
                if (!successfullyValidatedReserializedHypergrid)
                {
                    exceptionMessage = pythonScope.Get("exception_message").As <string>();
                }

                Assert.True(successfullyValidatedReserializedHypergrid, exceptionMessage);
            }

            string currentDirectory = Directory.GetCurrentDirectory();

            Console.WriteLine($"Current directory {currentDirectory}");
        }