using System; using System.Collections.Generic; using System.Linq; using System.Text; using HeuristicLab.Services.Optimization.ControllerService.Interfaces; using HeuristicLab.Optimization; using HeuristicLab.Algorithms.GeneticAlgorithm; using HeuristicLab.Problems.TravelingSalesman; using HeuristicLab; using System.Reflection; using HeuristicLab.Services.Optimization.ControllerService.Model; using HeuristicLab.Core; using System.Collections; using HeuristicLab.Clients.Hive; using System.Threading; using HeuristicLab.Data; namespace HeuristicLab.Services.Optimization.ControllerService { public class HiveScenarioManager : IScenarioManager { public object MapControllerDataType(object model, Parameter param) { switch (param.Type) { case ParameterType.Boolean: return (param.Value as Model.BoolValue).Value; case ParameterType.Integer: return Convert.ToInt32((param.Value as Model.DecimalValue).Value); case ParameterType.Percent: case ParameterType.Decimal: return (param.Value as Model.DecimalValue).Value; case ParameterType.DecimalMatrix: return Utility.ToMultiD(((param.Value as Model.DecimalMatrix).Value)); case ParameterType.DecimalVector: return (param.Value as Model.DecimalVector).Value; case ParameterType.Type: //TODO handle type correctly! var typeValue = param.Value as Model.TypeValue; IProblem problem = model as IProblem; IAlgorithm algoModel = model as IAlgorithm; if (problem == null && algoModel != null) { problem = algoModel.Problem; } if (problem != null) { var toselect = problem.Operators.OfType().FirstOrDefault(x => x.Name == typeValue.Value); if (toselect != null) { return toselect; } } string parameterPropertyName = typeValue.Name.EndsWith("Parameter") ? typeValue.Name : typeValue.Name + "Parameter"; var parameterProperty = model.GetType().GetProperty(parameterPropertyName); if (parameterProperty != null) { var parameterPropertyValue = parameterProperty.GetGetMethod().Invoke(model, null); var vvProp = parameterPropertyValue.GetType().GetProperty("ValidValues"); if (vvProp != null) { //http://stackoverflow.com/questions/245607/how-is-generic-covariance-contra-variance-implemented-in-c-sharp-4-0 because of covariance declared in IEnumerable var options = vvProp.GetGetMethod().Invoke(parameterPropertyValue, null) as IEnumerable; if (options != null) { var result = options.FirstOrDefault(x => x.ItemName == typeValue.Value); if (result != null) return result; } } } Type type = null; foreach (var asm in AppDomain.CurrentDomain.GetAssemblies()) { type = asm.GetType(typeValue.Value); if (type != null) break; } return Activator.CreateInstance(type); } return null; } public object CreateHLObjectForType(object obj, Type type, Parameter prop) { var value = MapControllerDataType(obj, prop); if (prop.Type == ParameterType.Type) return value; if (type == typeof(HeuristicLab.Encodings.PermutationEncoding.Permutation)) { double[] input = value as double[]; int[] arr = new int[input.Length]; for (int i = 0; i < input.Length; i++) { arr[i] = Convert.ToInt32(input[i]); } var valueObj = new HeuristicLab.Encodings.PermutationEncoding.Permutation(Encodings.PermutationEncoding.PermutationTypes.RelativeUndirected, arr); return valueObj; } var propertyGetter = obj.GetType().GetProperty(prop.Value.Name).GetGetMethod(); return Activator.CreateInstance(propertyGetter.ReturnType, value); } private void MapProperty(object model, Parameter prop) { var propertyGetter = model.GetType().GetProperty(prop.Value.Name).GetGetMethod(); var propertySetter = model.GetType().GetProperty(prop.Value.Name).GetSetMethod(); var value = propertyGetter.Invoke(model, null); var valueProperty = value != null ? value.GetType().GetProperty("Value") : null; if (propertySetter != null) { var instance = CreateHLObjectForType(model, propertyGetter.ReturnType, prop); propertySetter.Invoke(model, new object[] { instance }); } else if (valueProperty != null) { valueProperty.GetSetMethod().Invoke(value, new object[] { MapControllerDataType(model, prop) }); } else { Console.WriteLine("Failed to handle property!"); } } public void DispatchScenario(Model.User user, Model.OptimizationScenario scenario) { Experiment experiment = new Experiment(); var problem = new TravelingSalesmanProblem(); foreach (var prop in scenario.InputParameters.Items) { MapProperty(problem, prop); } var algo = new GeneticAlgorithm(); algo.Problem = problem; foreach (var prop in scenario.AlgorithmParameters.Items) { MapProperty(algo, prop); } experiment.Optimizers.Add(algo); SendExperimentToHive(user, experiment); } private void SendExperimentToHive(Model.User user, Experiment exp) { var job = new RefreshableJob(); job.IsAllowedPrivileged = true; job.Job.Name = "Web Scheduled Traveling Salesman Job"; job.Job.ResourceNames = "TESTGROUP"; job.RefreshAutomatically = false; job.HiveTasks.Add(new OptimizerHiveTask(exp)); HiveServiceLocator.Instance.Username = user.Username; HiveServiceLocator.Instance.Password = user.Password; HiveServiceLocator.Instance.EndpointConfigurationName = "WSHttpBinding_IHiveService"; HiveClient.StartJob((ex) => { Console.WriteLine(ex.StackTrace); }, job, new CancellationToken()); job.StopResultPolling(); } public IList GetJobs(User user) { HiveServiceLocator.Instance.Username = user.Username; HiveServiceLocator.Instance.Password = user.Password; HiveServiceLocator.Instance.EndpointConfigurationName = "WSHttpBinding_IHiveService"; var jobsLoaded = HiveServiceLocator.Instance.CallHiveService>(s => s.GetJobs()); IList jobs = new List(); foreach (var job in jobsLoaded) { jobs.Add(ConvertJob(user, job)); } return jobs; } private Model.Job ConvertJob(User user, HeuristicLab.Clients.Hive.Job job) { var waitingJobs = job.JobCount - job.CalculatingCount - job.FinishedCount; Model.JobState? state = null; var jobTasks = HiveServiceLocator.Instance.CallHiveService>(s => s.GetLightweightJobTasks(job.Id)); foreach (var task in jobTasks) { switch (task.State) { case TaskState.Aborted: state = JobState.Aborted; break; case TaskState.Failed: state = JobState.Failed; break; } } if (!state.HasValue) { if (job.CalculatingCount > 0) state = JobState.Calculating; else if (waitingJobs > 0) state = JobState.Waiting; else state = JobState.Finished; } return new Model.Job() { Id = job.Id.ToString(), Name = job.Name, Resource = job.ResourceNames, State = state.Value }; } public Model.Job GetJob(User user, string id) { HiveServiceLocator.Instance.Username = user.Username; HiveServiceLocator.Instance.Password = user.Password; HiveServiceLocator.Instance.EndpointConfigurationName = "WSHttpBinding_IHiveService"; var guid = Guid.Parse(id); return ConvertJob(user, HiveServiceLocator.Instance.CallHiveService(s => s.GetJob(guid))); } public void DeleteJob(User user, string id) { HiveServiceLocator.Instance.Username = user.Username; HiveServiceLocator.Instance.Password = user.Password; HiveServiceLocator.Instance.EndpointConfigurationName = "WSHttpBinding_IHiveService"; var guid = Guid.Parse(id); HiveServiceLocator.Instance.CallHiveService(s => s.DeleteJob(guid)); } public IList GetJobResults(User user, string id) { HiveServiceLocator.Instance.Username = user.Username; HiveServiceLocator.Instance.Password = user.Password; HiveServiceLocator.Instance.EndpointConfigurationName = "WSHttpBinding_IHiveService"; var guid = Guid.Parse(id); var jobTasks = HiveServiceLocator.Instance.CallHiveService>(s => s.GetLightweightJobTasks(guid)); IList taskIds = new List(); foreach (var task in jobTasks) { taskIds.Add(task.Id); } TaskDownloader downloader = new TaskDownloader(taskIds); downloader.StartAsync(); while (!downloader.IsFinished) { Thread.Sleep(500); if (downloader.IsFaulted) { throw downloader.Exception; } } IDictionary hiveTasks = downloader.Results; IList runs = new List(); foreach (var keyTask in hiveTasks.Keys) { var oht = hiveTasks[keyTask] as OptimizerHiveTask; if (oht != null) { foreach (var run in oht.ItemTask.Item.Runs) { Model.Run taskRun = new Model.Run(); taskRun.Id = taskRun.Name = run.Name; IList resultValues = new List(); foreach (var key in run.Results.Keys) { var value = run.Results[key]; Parameter result = MapHiveDataType(key, value); resultValues.Add(result); } taskRun.Results = resultValues; runs.Add(taskRun); } } } return runs; } private Parameter MapHiveDataType(string name, IItem item) { Parameter result = new Parameter(); result.Type = ParameterType.String; if (item is IStringConvertibleValue) { var value = (item as IStringConvertibleValue).GetValue(); result.Value = new HeuristicLab.Services.Optimization.ControllerService.Model.StringValue() { Name = name, Value = value }; } else if (item is IStringConvertibleValueTuple) { var value1 = (item as IStringConvertibleValueTuple).Item1.GetValue(); var value2 = (item as IStringConvertibleValueTuple).Item2.GetValue(); result.Value = new HeuristicLab.Services.Optimization.ControllerService.Model.StringValue() { Name = name, Value = "{" + value1 + ", " + value2 + "}" }; } else if (item is IStringConvertibleArray) { StringBuilder sb = new StringBuilder(); var array = item as IStringConvertibleArray; if (array.Length == 0) { sb.Append("[ ]"); } else { sb.Append("["); for (int i=0; i < array.Length - 1; i++) { sb.Append(array.GetValue(i)).Append(", "); } sb.Append(array.GetValue(array.Length - 1)); sb.Append(" ]"); } var value = sb.ToString(); result.Value = new HeuristicLab.Services.Optimization.ControllerService.Model.StringValue() { Name = name, Value = value }; } else if (item is IStringConvertibleMatrix) { StringBuilder sb = new StringBuilder(); var matrix = item as IStringConvertibleMatrix; if (matrix.Rows == 0 || matrix.Columns == 0) { sb.Append("[ ]"); } else { sb.Append("[ "); for (int r = 0; r < matrix.Rows; r++) { sb.Append("( "); for (int c = 0; c < matrix.Columns - 1; c++) { sb.Append(matrix.GetValue(r, c)).Append(", "); } sb.Append(matrix.GetValue(r, matrix.Columns - 1)).Append(r < matrix.Rows - 1 ? " ), " : " )"); } sb.Append(" ]"); } var value = sb.ToString(); result.Value = new HeuristicLab.Services.Optimization.ControllerService.Model.StringValue() { Name = name, Value = value }; } else { result.Value = new HeuristicLab.Services.Optimization.ControllerService.Model.StringValue() { Name = name, Value = "Cannot be displayed as string" }; } return result; } } }