Skip to main content

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 jobs
  • RUNNING: 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)