Jobs
When solving an Optimization Model, an Optimization Job is generated that spawns a Sub Job that runs on your selected solver.
These jobs can be accessed via the main Jobs page or directly on the Resource page. Each job provides details about its execution, including any associated files or data generated. Visualizations for various data types are available, with new ones frequently added.
The Optimization Job aggregates the results of the Sub Jobs and provides the best solution found. The Sub Job is a single execution of the solver on a specific model configuration and will contain product specific execution data and specific error logs.
Running a Job
The StrangeworksOptimizer
class employs the run()
method to initiate a job. This method requires model
, solver
, and options
as arguments.
so = StrangeworksOptimizer(model=model,
solver=solver
options=options)
sw_job = so.run()
Status
Job progress can be monitored on the portal or through the SDK like so:
so = StrangeworksOptimizer()
print(f"Job status: {so.status(sw_job.slug)}")
The statuses include:
QUEUED
: The job is queued for execution.CANCELLED
: On some systems it is possible to cancel jobsRUNNING
: The job is currently being processed.COMPLETED
: The job has finished, and results are available.FAILED
: The job encountered an error during execution.
💡 Failed Jobs:
If the job status comes back as failed you can view the job page in the portal or use the Strangeworks SDK to retrieve the errors:
import strangeworks as sw
sw.get_error_messages(sw_job.slug)
Results
Once a job is completed, you can fetch the solution.
so = StrangeworksOptimizer()
results = so.results(sw_job.slug)
print(f"Best solution:\n{results.solution.first}")
Tagging Jobs
To enhance organization and searchability, you can assign tags to jobs.
so = StrangeworksOptimizer(model=model,
solver=solver,
options=options,
tags=["tag1", "tag2"])
sw_job = so.run()
To find jobs by tag, use the jobs_by_tag
method. You can filter by multiple tags and specify whether to use AND
or OR
for the search.
so = StrangeworksOptimizer()
# andor = "AND"
job_list = so.jobs_by_tag(andor="AND",
tags=[
"tag",
"another-tag",
"athird-tag"]
)
# andor = "OR"
job_list = so.jobs_by_tag(andor="OR",
tags=[
"tag",
"another-tag",
"athird-tag"]
)
Download a Run
If you want to fetch a previously submitted run for resubmission or to inspect the contents, you can use the download_input_file
method to recreate the optimizer used to run the job:
so = StrangeworksOptimizer()
optimization_job = so.download_input_file(sw_job.slug)
Files
When a model is uploaded to the platform, it is saved in the workspace and becomes accessible to users. Each model is stored as a RemoteFile
, allowing users to download it for further inspection or reuse.
Downloading a Model from a Job
To access the model associated with a previous job, use the download_input_model
method from the StrangeworksOptimizer
class:
so = StrangeworksOptimizer()
model = so.download_input_model(job_slug)
print(type(model))
By default, download_input_model
retrieves a reference to the remote model file rather than downloading the actual file. This reference includes a URL pointing to the model's location. If you need to download the physical model file, set the download_remote=True
parameter:
so = StrangeworksOptimizer()
model = so.download_input_model(job_slug, download_remote=True)
print(type(model))
Remote Files
A RemoteFile
can be submitted directly to the platform.
from strangeworks_optimization_models.problem_models import RemoteFile
model_url = model.model_url
model_type = model.model_type
model = RemoteFile(model_url, model_type)
solver = 'your.solver'
so = StrangeworksOptimizer(model=model, solver=solver)
sw_job = so.run()
If you want to submit a model file you must first retrieve the model_url
and model_type
. Accepted model_type
values are (see Models for more information):
BinaryQuadraticModel
ConstrainedQuadraticModel
DiscreteQuadraticModel
AquilaNDArray
QuboDict
MPSFile
HitachiModel
FujitsuModel
MatrixMarket
QplibFile
Upload Models
To upload a model to the platform, use the upload_model
method from the StrangeworksOptimizer
class:
import strangeworks as sw
from strangeworks_optimizer import StrangeworksOptimizer
from dimod import BinaryQuadraticModel
sw.authenticate('your-api-key')
linear = {1: -2, 2: -2, 3: -3, 4: -3, 5: -2}
quadratic = {(1, 2): 2, (1, 3): 2, (2, 4): 2, (3, 4): 2, (3, 5): 2, (4, 5): 2}
bqm = BinaryQuadraticModel(linear, quadratic, "BINARY")
model = StrangeworksOptimizer().upload_model(bqm)
# model_url = model.model_url
# model_type = model.model_type
Download Remote Model
Once you have obtained the url of the model, you can retrieve it using:
so = StrangeworksOptimizer()
model = so.download_input_model_from_url(file_url)
print(type(model))
Batching Jobs
You can run multiple jobs in parallel by using a batch.yaml
file (see Remote Jobs for how to produce a model_url
):
job_name: BatchJob
runs:
- run: "rundwave1"
problem_parameters:
model_url: "https://api.strangeworks.com/workspace//files/"
model_type: "BinaryQuadraticModel"
solver: "dwave.Advantage_system6.4"
solver_options:
num_reads: 50
chain_strength: 30
- run: "rundwave2"
problem_parameters:
model_url: "https://api.strangeworks.com/workspace//files/"
model_type: "BinaryQuadraticModel"
solver: "dwave.Advantage2_prototype2.2"
solver_options:
num_reads: 50
chain_strength: 30
- run: "rungurobi1"
problem_parameters:
model_url: "https://api.strangeworks.com/workspace//files/"
model_type: "BinaryQuadraticModel"
solver: "gurobi.qubo"
solver_options:
TimeLimit: 100
WorkLimit: 1000
Cutoff: 10
BarIterLimit: 1000
BestBdStop: 10
BestObjStop: 10
and the run_batch
method to retrieve a list of Jobs.
batch_file = "batch.yaml"
so = StrangeworksOptimizer()
sw_jobs = so.run_batch(batch_file=batch_file)