예제 #1
0
        /// <summary>
        /// Submit a job to be run on Azure.
        /// </summary>
        /// <param name="job">Job parameters.</param>
        /// <param name="ct">Cancellation token.</param>
        /// <param name="UpdateStatus">Action which will display job submission status to the user.</param>
        public async Task SubmitJobAsync(JobParameters job, CancellationToken ct, Action <string> UpdateStatus)
        {
            if (batchClient == null || storageClient == null)
            {
                throw new Exception("Unable to submit job to Azure: no credentials provided");
            }

            // Initialise a working directory.
            UpdateStatus("Initialising job environment...");
            string workingDirectory = Path.Combine(Path.GetTempPath(), job.ID.ToString());

            Directory.CreateDirectory(workingDirectory);

            // Set job owner.
            string owner = Environment.UserName.ToLower();

            await SetAzureMetaDataAsync("job-" + job.ID, "Owner", owner, ct);

            if (ct.IsCancellationRequested)
            {
                UpdateStatus("Cancelled");
                return;
            }

            // If the ApsimX path is a directory it will need to be compressed.
            if (Directory.Exists(job.ApsimXPath))
            {
                UpdateStatus("Compressing APSIM Next Generation...");

                string zipFile = Path.Combine(workingDirectory, $"Apsim-tmp-X-{owner}.zip");
                if (File.Exists(zipFile))
                {
                    File.Delete(zipFile);
                }

                CreateApsimXZip(job.ApsimXPath, zipFile, ct);

                job.ApsimXPath    = zipFile;
                job.ApsimXVersion = Path.GetFileName(zipFile).Substring(Path.GetFileName(zipFile).IndexOf('-') + 1);
            }

            if (ct.IsCancellationRequested)
            {
                UpdateStatus("Cancelled");
                return;
            }

            // Upload tools such as 7zip, AzCopy, CMail, etc.
            UpdateStatus("Uploading tools...");
            string executableDirectory = Path.GetDirectoryName(GetType().Assembly.Location);
            string toolsDir            = Path.Combine(executableDirectory, "tools");

            if (!Directory.Exists(toolsDir))
            {
                throw new Exception("Tools Directory not found: " + toolsDir);
            }

            foreach (string filePath in Directory.EnumerateFiles(toolsDir))
            {
                await UploadFileIfNeededAsync("tools", filePath, ct);

                if (ct.IsCancellationRequested)
                {
                    UpdateStatus("Cancelled");
                    return;
                }
            }

            // Upload email config file.
            if (job.SendEmail)
            {
                Licence       licence = new Licence(AzureSettings.Default.LicenceFilePath);
                StringBuilder config  = new StringBuilder();
                config.AppendLine($"EmailRecipient={job.EmailRecipient}");
                config.AppendLine($"EmailSender={licence.EmailSender}");
                config.AppendLine($"EmailPW={licence.EmailPW}");

                // Write these settings to a temporary config file.
                string configFile = Path.Combine(workingDirectory, "settings.txt");
                File.WriteAllText(configFile, config.ToString());

                await UploadFileIfNeededAsync("job-" + job.ID, configFile, ct);

                File.Delete(configFile);
            }

            if (ct.IsCancellationRequested)
            {
                UpdateStatus("Cancelled");
                return;
            }

            // Upload job manager.
            UpdateStatus("Uploading job manager...");
            await UploadFileIfNeededAsync("jobmanager", Path.Combine(executableDirectory, "azure-apsim.exe"), ct);

            if (ct.IsCancellationRequested)
            {
                UpdateStatus("Cancelled");
                return;
            }

            // Upload apsim.
            UpdateStatus("Uploading APSIM Next Generation...");
            await UploadFileIfNeededAsync("apsim", job.ApsimXPath, ct);

            if (ct.IsCancellationRequested)
            {
                UpdateStatus("Cancelled");
                return;
            }

            // Generate model files.
            UpdateStatus("Generating model files...");
            if (!Directory.Exists(job.ModelPath))
            {
                Directory.CreateDirectory(job.ModelPath);
            }

            if (ct.IsCancellationRequested)
            {
                UpdateStatus("Cancelled");
                return;
            }

            // Generate .apsimx file for each simulation to be run.
            Runner run = new Runner(job.Model);

            GenerateApsimXFiles.Generate(run, job.ModelPath, p => { /* Don't bother with progress reporting */ }, collectExternalFiles: true);

            if (ct.IsCancellationRequested)
            {
                UpdateStatus("Cancelled");
                return;
            }

            // Compress model (.apsimx file) directory.
            UpdateStatus("Compressing model files...");
            string tmpZip = Path.Combine(workingDirectory, $"Model-{Guid.NewGuid()}.zip");

            ZipFile.CreateFromDirectory(job.ModelPath, tmpZip, CompressionLevel.Fastest, false);
            job.ModelPath = tmpZip;

            if (ct.IsCancellationRequested)
            {
                UpdateStatus("Cancelled");
                return;
            }

            // Upload models.
            UpdateStatus("Uploading model files...");
            string modelZipFileSas = await UploadFileIfNeededAsync(job.ID.ToString(), job.ModelPath, ct);

            if (ct.IsCancellationRequested)
            {
                UpdateStatus("Cancelled");
                return;
            }

            // Clean up temp files.
            UpdateStatus("Deleting temp files...");
            Directory.Delete(workingDirectory, true);

            // Submit job.
            UpdateStatus("Submitting Job...");
            CloudJob cloudJob = batchClient.JobOperations.CreateJob(job.ID.ToString(), GetPoolInfo(job));

            cloudJob.DisplayName        = job.DisplayName;
            cloudJob.JobPreparationTask = CreateJobPreparationTask(job, modelZipFileSas);
            cloudJob.JobReleaseTask     = CreateJobReleaseTask(job, modelZipFileSas);
            cloudJob.JobManagerTask     = CreateJobManagerTask(job);

            await cloudJob.CommitAsync(cancellationToken : ct);

            UpdateStatus("Job Successfully submitted");
        }
예제 #2
0
        public void TestManagerParameterChanges()
        {
            Manager m = new Manager()
            {
                Name = "Manager",
                Code = "using System; namespace Models { using Core; [Serializable] public class Script : Models.Core.Model { [Description(\"x\")] public string X { get; set; } } }"
            };
            Simulations sims = new Simulations()
            {
                Children = new List <IModel>()
                {
                    new DataStore(),
                    new Experiment()
                    {
                        Name     = "expt",
                        Children = new List <IModel>()
                        {
                            new Factors()
                            {
                                Children = new List <IModel>()
                                {
                                    new Factor()
                                    {
                                        Name          = "x",
                                        Specification = "[Manager].Script.X = 1"
                                    }
                                }
                            },
                            new Simulation()
                            {
                                Name     = "sim",
                                Children = new List <IModel>()
                                {
                                    new Clock()
                                    {
                                        StartDate = new DateTime(2020, 1, 1),
                                        EndDate   = new DateTime(2020, 1, 2),
                                        Name      = "Clock"
                                    },
                                    new Summary(),
                                    m
                                }
                            }
                        }
                    }
                }
            };

            sims.ParentAllDescendants();
            m.OnCreated();
            Runner runner = new Runner(sims);
            string temp   = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            try
            {
                IEnumerable <string> files = GenerateApsimXFiles.Generate(runner, 1, temp, _ => {});
                Assert.AreEqual(1, files.Count());
                string file = files.First();
                sims = FileFormat.ReadFromFile <Simulations>(file, e => throw e, false);
                Assert.AreEqual("1", sims.FindByPath("[Manager].Script.X").Value);
            }
            finally
            {
                if (Directory.Exists(temp))
                {
                    Directory.Delete(temp, true);
                }
            }
        }
예제 #3
0
        public void EnsureFilesAreGeneratedForTwoSimulations()
        {
            // Create a folder of 2 simulations.
            var folder = new Folder()
            {
                Children = new List <Model>()
                {
                    new Simulation()
                    {
                        Name     = "Sim1",
                        FileName = Path.GetTempFileName(),
                        Children = new List <Model>()
                        {
                            new Clock()
                            {
                                StartDate = new DateTime(1980, 1, 1),
                                EndDate   = new DateTime(1980, 1, 2)
                            },
                            new MockSummary(),
                        }
                    },
                    new Simulation()
                    {
                        Name     = "Sim2",
                        FileName = Path.GetTempFileName(),
                        Children = new List <Model>()
                        {
                            new Clock()
                            {
                                StartDate = new DateTime(1980, 1, 3),
                                EndDate   = new DateTime(1980, 1, 4)
                            },
                            new MockSummary(),
                        }
                    }
                }
            };

            var path = Path.Combine(Path.GetTempPath(), "GenerateApsimXFiles");

            if (Directory.Exists(path))
            {
                Directory.Delete(path, true);
            }
            Directory.CreateDirectory(path);

            // Create a list of progress ints.
            var progress = new List <int>();

            // Create a runner for our folder.
            Runner runner = new Runner(folder);

            GenerateApsimXFiles.Generate(runner, path, (s) => { progress.Add(s); });

            Assert.AreEqual(progress.Count, 2);
            Assert.AreEqual(progress[0], 50);
            Assert.AreEqual(progress[1], 100);

            var generatedFiles = Directory.GetFiles(path);

            Assert.AreEqual(generatedFiles.Length, 2);
            Assert.AreEqual(Path.GetFileName(generatedFiles[0]), "Sim1.apsimx");
            Assert.AreEqual(Path.GetFileName(generatedFiles[1]), "Sim2.apsimx");
            Directory.Delete(path, true);
        }
예제 #4
0
        public void EnsureFilesAreGeneratedForTwoSimulations()
        {
            // Create a folder of 2 simulations.
            var folder = new Folder()
            {
                Children = new List <IModel>()
                {
                    new Simulation()
                    {
                        Name     = "Sim1",
                        FileName = Path.GetTempFileName(),
                        Children = new List <IModel>()
                        {
                            new Clock()
                            {
                                StartDate = new DateTime(1980, 1, 1),
                                EndDate   = new DateTime(1980, 1, 2)
                            },
                            new MockSummary(),
                        }
                    },
                    new Simulation()
                    {
                        Name     = "Sim2",
                        FileName = Path.GetTempFileName(),
                        Children = new List <IModel>()
                        {
                            new Clock()
                            {
                                StartDate = new DateTime(1980, 1, 3),
                                EndDate   = new DateTime(1980, 1, 4)
                            },
                            new MockSummary(),
                        }
                    }
                }
            };

            var path = Path.Combine(Path.GetTempPath(), "GenerateApsimXFiles");

            if (Directory.Exists(path))
            {
                Directory.Delete(path, true);
            }
            Directory.CreateDirectory(path);

            // Create a list of progress ints.
            var progress = new List <double>();

            // Create a runner for our folder.
            Runner runner = new Runner(folder);
            IEnumerable <string> generatedFiles = GenerateApsimXFiles.Generate(runner, 1, path, (s) => { progress.Add(s); });

            Assert.AreEqual(2, progress.Count);
            Assert.AreEqual(0.5, progress[0]);
            Assert.AreEqual(1, progress[1]);

            Assert.AreEqual(2, generatedFiles.Count());
            Assert.AreEqual("generated-0.apsimx", Path.GetFileName(generatedFiles.First()));
            Assert.AreEqual("generated-1.apsimx", Path.GetFileName(generatedFiles.Last()));
            Directory.Delete(path, true);
        }