From 8d740bbe4e9ce351cdb466e769324d9390ccbdb5 Mon Sep 17 00:00:00 2001 From: Charlie Hewitt Date: Thu, 1 Apr 2021 10:14:26 +0100 Subject: [PATCH 1/7] AML cloud support initial --- .amlignore | 10 +++ .gitignore | 3 + Project.toml | 3 + src/Cloud/Cloud.jl | 128 ++++++++++++++++++++++++++++++++++++++ src/Cloud/dockerfile | 15 +++++ src/Cloud/entry_script.py | 12 ++++ src/OpticSim.jl | 1 + 7 files changed, 172 insertions(+) create mode 100644 .amlignore create mode 100644 src/Cloud/Cloud.jl create mode 100644 src/Cloud/dockerfile create mode 100644 src/Cloud/entry_script.py diff --git a/.amlignore b/.amlignore new file mode 100644 index 000000000..5b47c780e --- /dev/null +++ b/.amlignore @@ -0,0 +1,10 @@ +docs/ +test/ +.git/ +.github/ +.vscode/ +*.md +LICENSE +Manifest.toml +.gitignore +src/Cloud/amlconf \ No newline at end of file diff --git a/.gitignore b/.gitignore index f62b311eb..b0361d455 100644 --- a/.gitignore +++ b/.gitignore @@ -50,3 +50,6 @@ docs/site/ # committed for packages, but should be committed for applications that require a static # environment. Manifest.toml + +# Cloud config file +src/Cloud/amlconf diff --git a/Project.toml b/Project.toml index 48394a77d..a82b3f605 100644 --- a/Project.toml +++ b/Project.toml @@ -9,6 +9,7 @@ CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b" ColorSchemes = "35d6a980-a343-548e-a6ea-1d62b119f2f4" ColorTypes = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" Colors = "5ae59095-9a9b-59fe-a467-6f913c188581" +Conda = "8f4d0f93-b110-5947-807f-2305c1781a2d" DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" @@ -30,6 +31,8 @@ PackageCompiler = "9b87118b-4619-50d2-8e1e-99f35a4d4d9d" Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" Polynomials = "f27b6e38-b328-58d1-80ce-0feddd5e7a45" +PyCall = "438e738f-606a-5dbb-bf0a-cddfbfd45ab0" +Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" SHA = "ea8e919c-243c-51af-8825-aaa63cd721ce" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" diff --git a/src/Cloud/Cloud.jl b/src/Cloud/Cloud.jl new file mode 100644 index 000000000..0120c458d --- /dev/null +++ b/src/Cloud/Cloud.jl @@ -0,0 +1,128 @@ +module Cloud + +using PyCall +using Conda +using Pkg +using Random + +function cache_run_config(subscription_id::String, resource_group::String, workspace_name::String, compute_name::String, path::String = joinpath(@__DIR__, "amlconf")) + open(path, "w") do io + write(io, subscription_id * "\n") + write(io, resource_group * "\n") + write(io, workspace_name * "\n") + write(io, compute_name) + end + nothing +end + +function get_cached_run_config(path::String = joinpath(@__DIR__, "amlconf")) + open(path, "r") do io + subscription_id = readline(io) + resource_group = readline(io) + workspace_name = readline(io) + compute_name = readline(io) + return subscription_id, resource_group, workspace_name, compute_name + end +end + +function submit_run_to_AML(run_name::String, path_to_script::String, script_args::Union{Nothing,Vector{String}} = nothing, config_path::String = joinpath(@__DIR__, "amlconf")) + subscription_id, resource_group, workspace_name, compute_name = get_cached_run_config(config_path) + submit_run_to_AML(run_name, path_to_script, script_args, subscription_id, resource_group, workspace_name, compute_name) +end + +function submit_run_to_AML(run_name::String, path_to_script::String, script_args::Union{Nothing,Vector{String}}, + subscription_id::String, resource_group::String, workspace_name::String, compute_name::String) + + dockerfile = open(joinpath(@__DIR__, "dockerfile")) do file + read(file, String) + end + + # add deps to dockerfile + project_dict = Pkg.TOML.parsefile(Base.active_project()) + packages = collect(keys(project_dict["deps"])) + sort!(packages) + pkg_install_cmd = "RUN julia -e \"using Pkg; " + for package_name in packages + if "compat" in keys(project_dict) && package_name in keys(project_dict["compat"]) + pkg_install_cmd = pkg_install_cmd * "Pkg.add(name=\\\"" * package_name * "\\\", version=\\\"" * project_dict["compat"][package_name] * "\\\");" + else + pkg_install_cmd = pkg_install_cmd * "Pkg.add(\\\"" * package_name * "\\\");" + end + end + if "OpticSim" in packages + # build OpticSim if it is there + pkg_install_cmd = pkg_install_cmd * "Pkg.build(\\\"OpticSim\\\");" + end + pkg_install_cmd = pkg_install_cmd * "\"" + + dockerfile = dockerfile * pkg_install_cmd + + # TODO maybe compile sysimage in docker - would be horribly slow but should speed up import a lot? + + source_directory = joinpath(dirname(Base.active_project())) + + if isfile(joinpath(source_directory, "Manifest.toml")) + println("WARNING: Manifest.toml must be included in .amlignore file.") + end + + # set up env for python stuff + try + pyimport("azureml.core") + catch + # FIXME maybe won't work, might need to restart Julia after this? + Conda.add("python=3.7") + Conda.add("pip=20.1.1") + Conda.pip_interop(true) + Conda.pip("install", "azureml-sdk") + Pkg.build("PyCall") + end + + # copy entry_script from here to source_directory + entry_script_path = "entry_script_" * randstring() * ".py" + cp(joinpath(@__DIR__, "entry_script.py"), joinpath(source_directory, entry_script_path)) + + py""" + import os + import webbrowser + from azureml.core import Environment, Experiment, Run, Workspace, ScriptRunConfig + # import azureml.train.hyperdrive as hyperdrive + # from azureml.train.hyperdrive.parameter_expressions import choice + + def submit_run(subscription_id, resource_group, workspace_name, compute_name, source_directory, julia_script, script_args, run_name, dockerfile, entry_script_path): + workspace = Workspace(subscription_id, resource_group, workspace_name) + + compute_target = workspace.compute_targets[compute_name] + + env = Environment("opticsim") + env.docker.base_image = None + env.docker.base_dockerfile = dockerfile + + args = [julia_script.replace(os.sep, "/")] + if script_args is not None: + args.extend(script_args) + + src = ScriptRunConfig(source_directory=source_directory, + script=entry_script_path, + arguments=args, + compute_target=compute_target, + environment=env) + src.run_config.docker.use_docker = True + + # TODO support hyperdrive + + exp_name = os.getlogin() + "-opticsim" + experiment = Experiment(workspace, exp_name) + run_object = experiment.submit(src, tags={"run_name": run_name}) + + webbrowser.open_new(run_object.get_portal_url()) + """ + + py"submit_run"(subscription_id, resource_group, workspace_name, compute_name, source_directory, path_to_script, script_args, run_name, dockerfile, entry_script_path) + + # remove the entry script + rm(joinpath(source_directory, entry_script_path)) +end + +export submit_run_to_AML, cache_run_config, get_cached_run_config + +end \ No newline at end of file diff --git a/src/Cloud/dockerfile b/src/Cloud/dockerfile new file mode 100644 index 000000000..34827ec53 --- /dev/null +++ b/src/Cloud/dockerfile @@ -0,0 +1,15 @@ +FROM mcr.microsoft.com/azureml/openmpi3.1.2-ubuntu18.04 + +ENV JULIA_VERSION_MAJOR 1.6 +ENV JULIA_VERSION_MINOR 0 + +# install stuff for xvfb-run +RUN apt install -y libxt6 libxrender1 libxext6 libgl1-mesa-glx libqt5widgets5 xvfb + +# install julia +ENV JULIA_VERSION $JULIA_VERSION_MAJOR.$JULIA_VERSION_MINOR + +RUN wget https://julialang-s3.julialang.org/bin/linux/x64/$JULIA_VERSION_MAJOR/julia-$JULIA_VERSION-linux-x86_64.tar.gz -O julia-$JULIA_VERSION-linux-x86_64.tar.gz +RUN tar -xvzf julia-$JULIA_VERSION-linux-x86_64.tar.gz +RUN mv julia-$JULIA_VERSION/ /opt/ +RUN ln -s /opt/julia-$JULIA_VERSION/bin/julia /usr/local/bin/julia diff --git a/src/Cloud/entry_script.py b/src/Cloud/entry_script.py new file mode 100644 index 000000000..57bf75df6 --- /dev/null +++ b/src/Cloud/entry_script.py @@ -0,0 +1,12 @@ +import os +import sys +import multiprocessing + +# set up the project (should already be installed in base through docker so should be quick) +ret = os.system(f"xvfb-run julia --project -e \"using Pkg; Pkg.resolve()\"") +if os.WEXITSTATUS(ret) != 0: + sys.exit(os.WEXITSTATUS(ret)) + +# run the script +ret = os.system(f"JULIA_NUM_THREADS={multiprocessing.cpu_count()} xvfb-run julia --project {' '.join(sys.argv[1:])}") +sys.exit(os.WEXITSTATUS(ret)) diff --git a/src/OpticSim.jl b/src/OpticSim.jl index 528b5ae8b..aedda65aa 100644 --- a/src/OpticSim.jl +++ b/src/OpticSim.jl @@ -43,6 +43,7 @@ include("Optical/Optical.jl") include("Visualization/Visualization.jl") include("Examples/Examples.jl") include("Optimization/Optimization.jl") +include("Cloud/Cloud.jl") #initialize these caches here so they will get the correct number of threads from the load time environment, rather than the precompile environment. The latter happens if the initialization happens in the const definition. If the precompile and load environments have different numbers of threads this will cause an error. function __init__() From 3ff429438248a8c9f729b67a91efa39617f0fee8 Mon Sep 17 00:00:00 2001 From: Charlie Hewitt Date: Thu, 1 Apr 2021 10:52:03 +0100 Subject: [PATCH 2/7] Relative glass import paths --- deps/generate.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/deps/generate.jl b/deps/generate.jl index ef8924b5e..c94e0ae06 100644 --- a/deps/generate.jl +++ b/deps/generate.jl @@ -46,8 +46,8 @@ function generate_jls( # parse the catalog into a module string and write it to a catalog file (.jl) id, modstring = catalog_to_modstring(id, catalogname, catalog) - push!(catalogfiles, joinpath(jldir, "$(catalogname).jl")) - open(catalogfiles[end], "w") do io + push!(catalogfiles, "$(catalogname).jl") + open(joinpath(jldir, catalogfiles[end]), "w") do io write(io, modstring) end @@ -59,7 +59,7 @@ function generate_jls( agfstrings = [ "export $(join(sourcenames, ", "))", "", - ["include(raw\"$(catalogfile)\")" for catalogfile in catalogfiles]..., + ["include(\"$(catalogfile)\")" for catalogfile in catalogfiles]..., "", "const AGF_GLASS_NAMES = [$(join(repr.(glassnames), ", "))]", "const AGF_GLASSES = [$(join(glassnames, ", "))]", From d8a6d4ae77840f12d9d61a17f60857092f959da4 Mon Sep 17 00:00:00 2001 From: Alfred Wong Date: Thu, 1 Apr 2021 11:18:34 +0100 Subject: [PATCH 3/7] force AGFGlassCat.jl to reside in jldir fixes #69 --- deps/build.jl | 5 ++--- deps/generate.jl | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/deps/build.jl b/deps/build.jl index 24f136467..cbc4fa301 100644 --- a/deps/build.jl +++ b/deps/build.jl @@ -25,7 +25,7 @@ const GLASSCAT_DIR = joinpath(@__DIR__, "..", "src", "GlassCat") # contains Glas const JL_DIR = joinpath(GLASSCAT_DIR, "data") # contains AGFGlasscat.jl, SCHOTT.jl, etc. const SOURCES_PATH = joinpath(@__DIR__, "sources.txt") -const AGFGLASSCAT_PATH = joinpath(JL_DIR, "AGFGlassCat.jl") +const AGFGLASSCAT_NAME = "AGFGlassCat.jl" include(joinpath(GLASSCAT_DIR, "GlassTypes.jl")) include("sources.jl") @@ -40,6 +40,5 @@ verify_sources!(sources, AGF_DIR) verified_source_names = [source[1] for source in sources] # Use verified sources to generate required .jl files -@info "$(isfile(AGFGLASSCAT_PATH) ? "Re-g" : "G")enerating $AGFGLASSCAT_PATH" @info "Using sources: $(join(verified_source_names, ", ", " and "))" -generate_jls(verified_source_names, AGFGLASSCAT_PATH, JL_DIR, AGF_DIR) +generate_jls(verified_source_names, AGFGLASSCAT_NAME, JL_DIR, AGF_DIR) diff --git a/deps/generate.jl b/deps/generate.jl index c94e0ae06..f364f4229 100644 --- a/deps/generate.jl +++ b/deps/generate.jl @@ -65,7 +65,7 @@ function generate_jls( "const AGF_GLASSES = [$(join(glassnames, ", "))]", "" ] - open(mainfile, "w") do io + open(joinpath(jldir, mainfile), "w") do io write(io, join(agfstrings, "\n")) end end From a26294f43578f9376726608eb515c23f2dbc006a Mon Sep 17 00:00:00 2001 From: Charlie Hewitt Date: Wed, 7 Apr 2021 17:17:21 +0100 Subject: [PATCH 4/7] Add docs and hyperdrive support --- .amlignore | 3 +- docs/make.jl | 5 +-- docs/src/cloud.md | 51 +++++++++++++++++++++ src/Cloud/Cloud.jl | 77 ++++++++++++++++++++++++++------ src/Optimization/Optimization.jl | 2 +- 5 files changed, 120 insertions(+), 18 deletions(-) create mode 100644 docs/src/cloud.md diff --git a/.amlignore b/.amlignore index 5b47c780e..c6515a247 100644 --- a/.amlignore +++ b/.amlignore @@ -7,4 +7,5 @@ test/ LICENSE Manifest.toml .gitignore -src/Cloud/amlconf \ No newline at end of file +src/Cloud/amlconf +outputs/ diff --git a/docs/make.jl b/docs/make.jl index 7cd776349..c13a80a42 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -32,8 +32,7 @@ makedocs( modules = [OpticSim], pages = [ "Home" => "index.md", - "Examples" => "examples.md", - # "Glasses" => cat_pages, + "Examples" => "examples.md", "Geometry" => [ "Primitives" => "primitives.md", "CSG" => "csg.md" @@ -47,6 +46,7 @@ makedocs( "Visualization" => "vis.md", "Glass Functions" => "glasscat.md", "Optimization" => "optimization.md", + "Cloud Execution" => "cloud.md", "Reference" => "ref.md", "Roadmap" => "roadmap.md" ], @@ -60,7 +60,6 @@ deploydocs( # function children(m::Module) # ns = names(m, imported = false, all = true) # ms = [] - # for n in ns # try # x = Core.eval(m, n) diff --git a/docs/src/cloud.md b/docs/src/cloud.md new file mode 100644 index 000000000..f2fa5bc38 --- /dev/null +++ b/docs/src/cloud.md @@ -0,0 +1,51 @@ +# Cloud Execution + +## Azure + +A key benefit and design motivation of OpticSim is being able to execute many simulations/optimizations at once. +This is best enabled through the use of cloud computing services such as Azure. + +As part of the base package, we provide support for cloud execution using an [Azure Machine Learning](https://azure.microsoft.com/en-gb/free/machine-learning) workspace. + +To use this functionally you'll first need to set up an AML workspace with a compute cluster. Then you'll need to provide a few bits of information to OpticSim: + +- Subscription ID, of the form `XXXXXXXX-XXX-XXX-XXXX-XXXXXXXXXXXX` +- Resource group name +- Workspace name +- Compute cluster name + +This information can be cached either to a specific file, or globally: + +```@docs +Optics.Cloud.cache_run_config +Optics.Cloud.get_cached_run_config +``` + +You should also include an `.amlignore` file in the root of your project. +This is similar to a `.gitignore` file and should include any files which should not be uploaded to AML as part of your source snapshot, for examples `test/`. +**`Manifest.toml` must be listed in your `.amlignore` file.** +If an `.amlignore` doesn't already exist then one will be created on the first submission of a run to AML. + +Once everything is configured, you can submit a run: + +```@docs +Optics.Cloud.submit_run_to_AML +``` + +To retrieve outputs from your run simply write files to the `outputs/` directory and the files will automatically appear as part of the AML run. + +### Examples + +```julia +using Optics.Cloud + +cache_run_config([subscription_id], [resource_group_name], [workspace_name], [compute_name], [path_to_config]) + +submit_run_to_AML("example-run", [path_to_script], ["--arg1", "1", "--arg2", "2"], nothing, [path_to_config]) + +submit_run_to_AML("example-hyperdrive-run", [path_to_script], ["--arg1", "1"], Dict("--arg2" => ["1", "2", "3"]), [path_to_config]) +``` + +## Other Cloud Services + +Currently no other services are supported, though it should be reasonably straightforward to add similar functionality to that for AML. diff --git a/src/Cloud/Cloud.jl b/src/Cloud/Cloud.jl index 0120c458d..decd11ec4 100644 --- a/src/Cloud/Cloud.jl +++ b/src/Cloud/Cloud.jl @@ -5,6 +5,11 @@ using Conda using Pkg using Random +""" + cache_run_config(subscription_id::String, resource_group::String, workspace_name::String, compute_name::String[, path::String]) + +Writes the AML config information to a file at `path`. If `path` isn't set then the config will be used globally for that OpticSim install. +""" function cache_run_config(subscription_id::String, resource_group::String, workspace_name::String, compute_name::String, path::String = joinpath(@__DIR__, "amlconf")) open(path, "w") do io write(io, subscription_id * "\n") @@ -15,6 +20,11 @@ function cache_run_config(subscription_id::String, resource_group::String, works nothing end +""" + get_cached_run_config([path::String]) + +Reads the AML config information from a file at `path`. If not specified then the global config will be read. +""" function get_cached_run_config(path::String = joinpath(@__DIR__, "amlconf")) open(path, "r") do io subscription_id = readline(io) @@ -25,13 +35,30 @@ function get_cached_run_config(path::String = joinpath(@__DIR__, "amlconf")) end end -function submit_run_to_AML(run_name::String, path_to_script::String, script_args::Union{Nothing,Vector{String}} = nothing, config_path::String = joinpath(@__DIR__, "amlconf")) +""" + submit_run_to_AML(run_name::String, path_to_script::String, script_args::Vector{String} = nothing, sampled_args:Dict{String,Vector{String}} = nothing, config_path::String; hyperdrive_concurrent_runs::Int = 10) + submit_run_to_AML(run_name::String, path_to_script::String, subscription_id::String, resource_group::String, workspace_name::String, compute_name::String, script_args::Vector{String} = nothing, sampled_args::Dict{String, Vector{String}} = nothing; hyperdrive_concurrent_runs::Int = 10) + +Submit a run to AML, `path_to_script` is relative to your local package root (i.e. location of `Project.toml`). +`script_args` are a series of arguments to your script as strings. +`sampled_args` is a dictionary where keys are argument names and values are lists of values (as strings) that that argument will take. +`config_path` is a path to a config file as written by [`cache_run_config`](@ref), if not specified the global config is used. Alternatively this information can be provided directly using the second method above. +`hyperdrive_concurrent_runs` is the maximum number of concurrent runs that will execute on AML (limited by your compute cluster size). +""" +function submit_run_to_AML(run_name::String, path_to_script::String, script_args::Union{Nothing,Vector{String}} = nothing, + sampled_args::Union{Nothing,Dict{String,Vector{String}}} = nothing; + config_path::String = joinpath(@__DIR__, "amlconf"), + hyperdrive_concurrent_runs::Int = 10) subscription_id, resource_group, workspace_name, compute_name = get_cached_run_config(config_path) - submit_run_to_AML(run_name, path_to_script, script_args, subscription_id, resource_group, workspace_name, compute_name) + submit_run_to_AML(run_name, path_to_script, subscription_id, resource_group, workspace_name, compute_name, + script_args, sampled_args, hyperdrive_concurrent_runs=hyperdrive_concurrent_runs) end -function submit_run_to_AML(run_name::String, path_to_script::String, script_args::Union{Nothing,Vector{String}}, - subscription_id::String, resource_group::String, workspace_name::String, compute_name::String) +function submit_run_to_AML(run_name::String, path_to_script::String, + subscription_id::String, resource_group::String, workspace_name::String, compute_name::String, + script_args::Union{Nothing,Vector{String}} = nothing, + sampled_args::Union{Nothing,Dict{String,Vector{String}}} = nothing; + hyperdrive_concurrent_runs::Int = 10) dockerfile = open(joinpath(@__DIR__, "dockerfile")) do file read(file, String) @@ -61,8 +88,11 @@ function submit_run_to_AML(run_name::String, path_to_script::String, script_args source_directory = joinpath(dirname(Base.active_project())) - if isfile(joinpath(source_directory, "Manifest.toml")) - println("WARNING: Manifest.toml must be included in .amlignore file.") + if isfile(joinpath(source_directory, "Manifest.toml")) && !isfile(joinpath(source_directory, ".amlignore")) + println("No .amlignore file found, creating one") + open(joinpath(source_directory, ".amlignore"), "w") do io + write(io, "Manifest.toml\n") + end end # set up env for python stuff @@ -85,10 +115,20 @@ function submit_run_to_AML(run_name::String, path_to_script::String, script_args import os import webbrowser from azureml.core import Environment, Experiment, Run, Workspace, ScriptRunConfig - # import azureml.train.hyperdrive as hyperdrive - # from azureml.train.hyperdrive.parameter_expressions import choice + import azureml.train.hyperdrive as hyperdrive + from azureml.train.hyperdrive.parameter_expressions import choice + + def get_hyperparam_dict(param_dict): + hyper_param_dict = {} + num_params = 1 + for key, value in param_dict.items(): + hyper_param_dict[key] = choice(value) + num_params = num_params * len(value) - def submit_run(subscription_id, resource_group, workspace_name, compute_name, source_directory, julia_script, script_args, run_name, dockerfile, entry_script_path): + return hyper_param_dict, num_params + + def submit_run(subscription_id, resource_group, workspace_name, compute_name, source_directory, julia_script, + script_args, sampled_args, run_name, dockerfile, entry_script_path, hyperdrive_concurrent_runs): workspace = Workspace(subscription_id, resource_group, workspace_name) compute_target = workspace.compute_targets[compute_name] @@ -108,16 +148,27 @@ function submit_run_to_AML(run_name::String, path_to_script::String, script_args environment=env) src.run_config.docker.use_docker = True - # TODO support hyperdrive - exp_name = os.getlogin() + "-opticsim" experiment = Experiment(workspace, exp_name) - run_object = experiment.submit(src, tags={"run_name": run_name}) + + if sampled_args is not None: + sampling_params, num_params = get_hyperparam_dict(sampled_args) + param_sampling = hyperdrive.GridParameterSampling(sampling_params) + hyperdrive_run_config = hyperdrive.HyperDriveConfig(run_config=src, + hyperparameter_sampling=param_sampling, + max_concurrent_runs=hyperdrive_concurrent_runs, + primary_metric_name="", + primary_metric_goal=hyperdrive.PrimaryMetricGoal.MINIMIZE, + max_total_runs=num_params) + run_object = experiment.submit(hyperdrive_run_config, tags={"run_name": run_name}) + else: + run_object = experiment.submit(src, tags={"run_name": run_name}) webbrowser.open_new(run_object.get_portal_url()) """ - py"submit_run"(subscription_id, resource_group, workspace_name, compute_name, source_directory, path_to_script, script_args, run_name, dockerfile, entry_script_path) + py"submit_run"(subscription_id, resource_group, workspace_name, compute_name, source_directory, path_to_script, + script_args, sampled_args, run_name, dockerfile, entry_script_path, hyperdrive_concurrent_runs) # remove the entry script rm(joinpath(source_directory, entry_script_path)) diff --git a/src/Optimization/Optimization.jl b/src/Optimization/Optimization.jl index debdc332f..9d47a6498 100644 --- a/src/Optimization/Optimization.jl +++ b/src/Optimization/Optimization.jl @@ -36,7 +36,7 @@ using ..OpticSim: detectorsize, temperature, pressure Pack variables that have been marked to be optimized into a vector in a form suitable for the optimizer. Variables are marked for optimization by having a true value in the `:OptimizeName` column, where `Name` can be `Radius`, `Thickness` or `Conic`. - """ +""" function optimizationvariables(a::AxisymmetricOpticalSystem{T}) where {T<:Real} prescription = a.prescription From d5e06c2a58d3f05437d7f772690bde0b14a5dcd3 Mon Sep 17 00:00:00 2001 From: Alfred Wong Date: Wed, 7 Apr 2021 18:30:31 +0100 Subject: [PATCH 5/7] upgrade to julia 1.6 and set push_preview=true for deploydocs --- .github/workflows/Documentation.yml | 2 +- docs/make.jl | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/Documentation.yml b/.github/workflows/Documentation.yml index 47fc0ef1c..589101a3c 100644 --- a/.github/workflows/Documentation.yml +++ b/.github/workflows/Documentation.yml @@ -12,7 +12,7 @@ jobs: - uses: actions/checkout@v2 - uses: julia-actions/setup-julia@latest with: - version: 1.5 + version: 1.6 - name: Install dependencies run: | xvfb-run julia --project=docs/ -e ' diff --git a/docs/make.jl b/docs/make.jl index ae36d4a6b..c9233b26b 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -56,6 +56,7 @@ makedocs( deploydocs( repo = "github.com/microsoft/OpticSim.jl.git", devbranch = "main", + push_preview = true, ) # function children(m::Module) From 3c263b684f5459832e431fe6b940185bbf304494 Mon Sep 17 00:00:00 2001 From: Alfred Wong Date: Wed, 7 Apr 2021 19:02:24 +0100 Subject: [PATCH 6/7] Optics -> OpticSim --- docs/src/cloud.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/src/cloud.md b/docs/src/cloud.md index f2fa5bc38..afadd251c 100644 --- a/docs/src/cloud.md +++ b/docs/src/cloud.md @@ -17,8 +17,8 @@ To use this functionally you'll first need to set up an AML workspace with a com This information can be cached either to a specific file, or globally: ```@docs -Optics.Cloud.cache_run_config -Optics.Cloud.get_cached_run_config +OpticSim.Cloud.cache_run_config +OpticSim.Cloud.get_cached_run_config ``` You should also include an `.amlignore` file in the root of your project. @@ -29,7 +29,7 @@ If an `.amlignore` doesn't already exist then one will be created on the first s Once everything is configured, you can submit a run: ```@docs -Optics.Cloud.submit_run_to_AML +OpticSim.Cloud.submit_run_to_AML ``` To retrieve outputs from your run simply write files to the `outputs/` directory and the files will automatically appear as part of the AML run. @@ -37,7 +37,7 @@ To retrieve outputs from your run simply write files to the `outputs/` directory ### Examples ```julia -using Optics.Cloud +using OpticSim.Cloud cache_run_config([subscription_id], [resource_group_name], [workspace_name], [compute_name], [path_to_config]) From d6ae5faf77ff0fa05daea2b00cbb242971ee1f97 Mon Sep 17 00:00:00 2001 From: Alfred Wong Date: Wed, 7 Apr 2021 19:56:46 +0100 Subject: [PATCH 7/7] try out !!! note markdown syntax --- docs/src/cloud.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/src/cloud.md b/docs/src/cloud.md index afadd251c..f77b14e13 100644 --- a/docs/src/cloud.md +++ b/docs/src/cloud.md @@ -23,7 +23,10 @@ OpticSim.Cloud.get_cached_run_config You should also include an `.amlignore` file in the root of your project. This is similar to a `.gitignore` file and should include any files which should not be uploaded to AML as part of your source snapshot, for examples `test/`. -**`Manifest.toml` must be listed in your `.amlignore` file.** + +!!! note + **`Manifest.toml` must be listed in your `.amlignore` file.** + If an `.amlignore` doesn't already exist then one will be created on the first submission of a run to AML. Once everything is configured, you can submit a run: