Repository: dwavesystems/dwave-cloud-client

Issue:
Prefer QPU solvers in `dwave ping`
As the CLI docs already claim (because they weren't updated after we added support for HSS/unstructured solvers).

There are two main issues with randomly picking a solver to ping:
- HSS solvers have required parameters (`time_limit`) client is not aware of, hence ping fails unless user specifies them with `-m/--sampling-params`. Once Solver API exposes more detailed solver parameter description, the client will be able to automatically pick a reasonable value for required params, and we can revisit this approach.
- HSS solvers have minimum runtime of at least 3s, hence sampling a dummy problem on them is slower than using a QPU solver

Discussion:

Patch:
diff --git a/dwave/cloud/cli.py b/dwave/cloud/cli.py
index c2ff0f9..1095999 100644
--- a/dwave/cloud/cli.py
+++ b/dwave/cloud/cli.py
@@ -483,11 +483,18 @@ def ping(*, config_file, profile, endpoint, region, client_type, solver_def,
     if label:
         params.update(label=label)
 
+    # gently prefer the least busy QPU
+    def order_by(solver):
+        category = solver.properties.get('category')
+        avg_load = solver.properties.get('avg_load')
+        return (0 if category == 'qpu' else 1, avg_load)
+
     config = dict(
         config_file=config_file, profile=profile,
         endpoint=endpoint, region=region,
         client=client_type, solver=solver_def,
-        request_timeout=request_timeout, polling_timeout=polling_timeout)
+        request_timeout=request_timeout, polling_timeout=polling_timeout,
+        defaults=dict(solver=dict(order_by=order_by)))
 
     t0 = timer()
     client, solver = _get_client_solver(config, output)
diff --git a/releasenotes/notes/make-ping-prefer-qpu-cde93e75acffeafc.yaml b/releasenotes/notes/make-ping-prefer-qpu-cde93e75acffeafc.yaml
new file mode 100644
index 0000000..58030e8
--- /dev/null
+++ b/releasenotes/notes/make-ping-prefer-qpu-cde93e75acffeafc.yaml
@@ -0,0 +1,5 @@
+---
+features:
+  - |
+    Prefer QPU solvers in ``dwave ping``, unless overridden by user/config.
+    See `#592 <https://github.com/dwavesystems/dwave-cloud-client/issues/592>`_


Test patch:
diff --git a/tests/test_cli.py b/tests/test_cli.py
index 38891fe..408dea9 100644
--- a/tests/test_cli.py
+++ b/tests/test_cli.py
@@ -282,11 +282,14 @@ class TestCli(unittest.TestCase):
                                              '--label', label])
 
             # proper arguments passed to Client.from_config?
-            m.from_config.assert_called_with(
+            expected_config = dict(
                 config_file=config_file, profile=profile,
                 endpoint=None, region=None,
                 client=client_type, solver=None,
                 request_timeout=0.5, polling_timeout=30)
+            call = m.from_config.call_args.kwargs
+            self.assertTrue(callable(call.pop('defaults', {}).get('solver', {}).get('order_by')))
+            self.assertEqual(call, expected_config)
 
             # get solver called?
             client.get_solver.assert_called_with()