def test_implied_job_config(build): eng = cg.Engine(project_id='project_id') # Infer all from project id. implied = eng.implied_job_config(cg.JobConfig()) assert re.fullmatch(r'prog-[0-9A-Z]+', implied.program_id) assert implied.job_id == 'job-0' assert implied.gcs_prefix == 'gs://gqe-project_id/' assert re.fullmatch( r'gs://gqe-project_id/programs/prog-[0-9A-Z]+/prog-[0-9A-Z]+', implied.gcs_program) assert re.fullmatch( r'gs://gqe-project_id/programs/prog-[0-9A-Z]+/jobs/job-0', implied.gcs_results) # Force program id. implied = eng.implied_job_config(cg.JobConfig(program_id='j')) assert implied.program_id == 'j' assert implied.job_id == 'job-0' assert implied.gcs_prefix == 'gs://gqe-project_id/' assert implied.gcs_program == 'gs://gqe-project_id/programs/j/j' assert implied.gcs_results == 'gs://gqe-project_id/programs/j/jobs/job-0' # Force all. implied = eng.implied_job_config( cg.JobConfig(program_id='b', job_id='c', gcs_prefix='gs://d', gcs_program='e', gcs_results='f')) assert implied.program_id == 'b' assert implied.job_id == 'c' assert implied.gcs_prefix == 'gs://d/' assert implied.gcs_program == 'e' assert implied.gcs_results == 'f'
def test_implied_job_config(build): eng = cg.Engine(project_id='project_id') # Infer all from project id. implied = eng.implied_job_config(cg.JobConfig()) assert implied.job_id.startswith('job-') assert len(implied.job_id) == 26 # Force all. implied = eng.implied_job_config(cg.JobConfig(job_id='c')) assert implied.job_id == 'c'
def test_calibration_from_job(build): service = mock.Mock() build.return_value = service programs = service.projects().programs() jobs = programs.jobs() programs.create().execute.return_value = { 'name': 'projects/project-id/programs/test' } calibrationName = '/project/p/processor/x/calibrationsi/123' jobs.create().execute.return_value = { 'name': 'projects/project-id/programs/test/jobs/test', 'executionStatus': { 'state': 'SUCCESS', 'calibrationName': calibrationName, }, } calibrations = service.projects().processors().calibrations() calibrations.get().execute.return_value = {'data': _CALIBRATION} engine = cg.Engine(api_key="key") job = engine.run_sweep( program=cirq.moment_by_moment_schedule(cirq.UnconstrainedDevice, cirq.Circuit()), job_config=cg.JobConfig('project-id', gcs_prefix='gs://bucket/folder')) calibration = job.get_calibration() assert calibration.timestamp == 1562544000021 assert set(calibration.get_metric_names()) == set(['xeb', 't1']) assert calibrations.get.call_args[1]['name'] == calibrationName
def test_run_sweep_v2(client_constructor): client = setup_run_circuit_with_result_(client_constructor, _RESULTS_V2) engine = cg.Engine( project_id='project-id', proto_version=cg.engine.engine.ProtoVersion.V2, ) job = engine.run_sweep(program=_CIRCUIT, job_config=cg.JobConfig('project-id'), params=cirq.Points('a', [1, 2])) results = job.results() assert engine.proto_version == cg.engine.engine.ProtoVersion.V2 assert len(results) == 2 for i, v in enumerate([1, 2]): assert results[i].repetitions == 1 assert results[i].params.param_dict == {'a': v} assert results[i].measurements == {'q': np.array([[0]], dtype='uint8')} assert client.create_quantum_program.call_args[0][ 0] == 'projects/project-id' assert client.create_quantum_job.call_args[0][ 0] == 'projects/project-id/programs/test' run_context = v2.run_context_pb2.RunContext() client.create_quantum_job.call_args[0][1].run_context.Unpack(run_context) sweeps = run_context.parameter_sweeps assert len(sweeps) == 1 assert sweeps[0].repetitions == 1 assert sweeps[0].sweep.single_sweep.points.points == [1, 2] assert client.get_quantum_job.call_count == 1 assert client.get_quantum_result.call_count == 1
def test_run_circuit_failed(build): service = mock.Mock() build.return_value = service programs = service.projects().programs() jobs = programs.jobs() programs.create().execute.return_value = { 'name': 'projects/project-id/programs/test' } jobs.create().execute.return_value = { 'name': 'projects/project-id/programs/test/jobs/test', 'executionStatus': { 'state': 'READY' } } jobs.get().execute.return_value = { 'name': 'projects/project-id/programs/test/jobs/test', 'executionStatus': { 'state': 'FAILURE' } } with pytest.raises(RuntimeError, match='It is in state FAILURE'): cg.Engine(api_key="key").run(program=cirq.Circuit(), job_config=cg.JobConfig( 'project-id', gcs_prefix='gs://bucket/folder'))
def test_cancel(build): service = mock.Mock() build.return_value = service programs = service.projects().programs() jobs = programs.jobs() programs.create().execute.return_value = { 'name': 'projects/project-id/programs/test' } jobs.create().execute.return_value = { 'name': 'projects/project-id/programs/test/jobs/test', 'executionStatus': { 'state': 'READY' } } jobs.get().execute.return_value = { 'name': 'projects/project-id/programs/test/jobs/test', 'executionStatus': { 'state': 'CANCELLED' } } engine = cg.Engine(project_id='project-id') job = engine.run_sweep(program=_SCHEDULE, job_config=cg.JobConfig( 'project-id', gcs_prefix='gs://bucket/folder')) job.cancel() assert job.job_resource_name == ('projects/project-id/programs/test/' 'jobs/test') assert job.status() == 'CANCELLED' assert jobs.cancel.call_args[1][ 'name'] == 'projects/project-id/programs/test/jobs/test'
def test_bad_priority(build): eng = cg.Engine(api_key="key") with pytest.raises(ValueError, match='priority must be'): eng.run(program=cirq.Circuit(), job_config=cg.JobConfig('project-id', gcs_prefix='gs://bucket/folder'), priority=1001)
def test_run_sweep_params(client_constructor): client = setup_run_circuit_with_result_(client_constructor, _RESULTS) engine = cg.Engine(project_id='project-id') job = engine.run_sweep( program=_CIRCUIT, job_config=cg.JobConfig('project-id'), params=[cirq.ParamResolver({'a': 1}), cirq.ParamResolver({'a': 2})]) results = job.results() assert len(results) == 2 for i, v in enumerate([1, 2]): assert results[i].repetitions == 1 assert results[i].params.param_dict == {'a': v} assert results[i].measurements == {'q': np.array([[0]], dtype='uint8')} assert client.create_quantum_program.call_args[0][ 0] == 'projects/project-id' assert client.create_quantum_job.call_args[0][ 0] == 'projects/project-id/programs/test' run_context = v1.program_pb2.RunContext() client.create_quantum_job.call_args[0][1].run_context.Unpack(run_context) sweeps = run_context.parameter_sweeps assert len(sweeps) == 2 for i, v in enumerate([1, 2]): assert sweeps[i].repetitions == 1 assert sweeps[i].sweep.factors[0].sweeps[0].points.points == [v] assert client.get_quantum_job.call_count == 1 assert client.get_quantum_result.call_count == 1
def test_default_prefix(build): service = mock.Mock() build.return_value = service programs = service.projects().programs() jobs = programs.jobs() programs.create().execute.return_value = { 'name': 'projects/project-id/programs/test' } jobs.create().execute.return_value = { 'name': 'projects/project-id/programs/test/jobs/test', 'executionStatus': { 'state': 'READY' } } jobs.get().execute.return_value = { 'name': 'projects/project-id/programs/test/jobs/test', 'executionStatus': { 'state': 'SUCCESS' } } jobs.getResult().execute.return_value = {'result': _A_RESULT} result = cg.Engine(api_key="key").run( program=cirq.Circuit(), job_config=cg.JobConfig('org.com:project-id')) assert result.repetitions == 1 assert result.params.param_dict == {'a': 1} assert result.measurements == {'q': np.array([[0]], dtype='uint8')} build.assert_called_with( 'quantum', 'v1alpha1', discoveryServiceUrl=('https://{api}.googleapis.com' '/$discovery/rest?version=' '{apiVersion}&key=key')) assert programs.create.call_args[1]['body']['gcs_code_location'][ 'uri'].startswith('gs://gqe-project-id/programs/')
def test_implied_job_config(build): eng = cg.Engine(project_id='project_id') # Infer all from project id. implied = eng.implied_job_config(cg.JobConfig()) assert implied.job_id.startswith('job-') assert len(implied.job_id) == 10 assert implied.gcs_prefix == 'gs://gqe-project_id/' assert re.match(r'gs://gqe-project_id/jobs/job-', implied.gcs_results) # Force all. implied = eng.implied_job_config( cg.JobConfig(job_id='c', gcs_prefix='gs://d', gcs_results='f')) assert implied.job_id == 'c' assert implied.gcs_prefix == 'gs://d/' assert implied.gcs_results == 'f'
def test_circuit_device_validation_passes_non_xmon_gate(build): service = mock.Mock() build.return_value = service programs = service.projects().programs() jobs = programs.jobs() programs.create().execute.return_value = { 'name': 'projects/project-id/programs/test' } jobs.create().execute.return_value = { 'name': 'projects/project-id/programs/test/jobs/test', 'executionStatus': { 'state': 'READY' } } jobs.get().execute.return_value = { 'name': 'projects/project-id/programs/test/jobs/test', 'executionStatus': { 'state': 'SUCCESS' } } jobs.getResult().execute.return_value = {'result': _A_RESULT} circuit = cirq.Circuit.from_ops(cirq.H.on(cirq.GridQubit(0, 1)), device=cg.Foxtail) result = cg.Engine(api_key="key").run( program=circuit, job_config=cg.JobConfig('project-id')) assert result.repetitions == 1
def test_calibration_from_job(build): service = mock.Mock() build.return_value = service programs = service.projects().programs() jobs = programs.jobs() programs.create().execute.return_value = { 'name': 'projects/project-id/programs/test' } calibrationName = '/project/p/processor/x/calibrationsi/123' jobs.create().execute.return_value = { 'name': 'projects/project-id/programs/test/jobs/test', 'executionStatus': { 'state': 'SUCCESS', 'calibrationName': calibrationName, }, } calibrations = service.projects().processors().calibrations() calibrations.get().execute.return_value = {'data': _CALIBRATION} engine = cg.Engine(project_id='project-id') job = engine.run_sweep( program=_SCHEDULE, job_config=cg.JobConfig(gcs_prefix='gs://bucket/folder')) calibration = job.get_calibration() assert calibration.timestamp == 1562544000021 assert set(calibration.keys()) == set(['xeb', 't1', 'globalMetric']) assert calibrations.get.call_args[1]['name'] == calibrationName
def test_calibration_from_job_with_no_calibration(build): service = mock.Mock() build.return_value = service programs = service.projects().programs() jobs = programs.jobs() programs.create().execute.return_value = { 'name': 'projects/project-id/programs/test' } jobs.create().execute.return_value = { 'name': 'projects/project-id/programs/test/jobs/test', 'executionStatus': { 'state': 'SUCCESS', }, } calibrations = service.projects().processors().calibrations() engine = cg.Engine(project_id='project-id') job = engine.run_sweep( program=cirq.moment_by_moment_schedule(cirq.UnconstrainedDevice, cirq.Circuit()), job_config=cg.JobConfig(gcs_prefix='gs://bucket/folder')) calibration = job.get_calibration() assert not calibration assert not calibrations.get.called
def test_bad_sweep_proto(build): eng = cg.Engine(project_id='project-id', proto_version=cg.engine.engine.ProtoVersion.UNDEFINED) with pytest.raises(ValueError, match='invalid proto version'): eng.run(program=cirq.Circuit(), job_config=cg.JobConfig('project-id', gcs_prefix='gs://bucket/folder'))
def test_bad_result_proto(build): service = mock.Mock() build.return_value = service programs = service.projects().programs() jobs = programs.jobs() programs.create().execute.return_value = { 'name': 'projects/project-id/programs/test' } jobs.create().execute.return_value = { 'name': 'projects/project-id/programs/test/jobs/test', 'executionStatus': { 'state': 'READY' } } jobs.get().execute.return_value = { 'name': 'projects/project-id/programs/test/jobs/test', 'executionStatus': { 'state': 'SUCCESS' } } result = _RESULTS_V2.copy() result['@type'] = 'type.googleapis.com/unknown' jobs.getResult().execute.return_value = {'result': result} engine = cg.Engine(project_id='project-id', proto_version=cg.engine.engine.ProtoVersion.V2) job = engine.run_sweep(program=_SCHEDULE, job_config=cg.JobConfig( 'project-id', gcs_prefix='gs://bucket/folder'), params=cirq.Points('a', [1, 2])) with pytest.raises(ValueError, match='invalid result proto version'): job.results()
def test_str(): engine = mock.Mock() job = qtypes.QuantumJob(name='projects/a/programs/b/jobs/steve') job = cg.EngineJob(job_config=cg.JobConfig(job_id='steve'), job=job, engine=engine) assert str(job) == 'EngineJob(projects/a/programs/b/jobs/steve)'
def test_run_circuit(client_constructor): client = setup_run_circuit_with_result_(client_constructor, _A_RESULT) engine = cg.Engine(project_id='project-id', service_args={'client_info': 1}) result = engine.run(program=_CIRCUIT, job_config=cg.JobConfig('job-id'), processor_ids=['mysim']) assert result.repetitions == 1 assert result.params.param_dict == {'a': 1} assert result.measurements == {'q': np.array([[0]], dtype='uint8')} client_constructor.assert_called_with(client_info=1) assert client.create_quantum_program.call_args[0][ 0] == 'projects/project-id' assert client.create_quantum_job.call_args[0] == ( 'projects/project-id/programs/test', qtypes.QuantumJob( name='projects/project-id/programs/test/jobs/job-id', scheduling_config={ 'priority': 50, 'processor_selector': { 'processor_names': ['projects/project-id/processors/mysim'] } }, run_context=_to_any( v1.program_pb2.RunContext(parameter_sweeps=[{ 'repetitions': 1 }]))), False) assert client.get_quantum_job.call_count == 1 assert client.get_quantum_result.call_count == 1
def test_bad_priority(build): eng = cg.Engine(project_id='project-id', proto_version=cg.engine.engine.ProtoVersion.V2) with pytest.raises(ValueError, match='priority must be'): eng.run(program=cirq.Circuit(), job_config=cg.JobConfig('project-id', gcs_prefix='gs://bucket/folder'), priority=1001)
def test_implied_job_config_project_id(build): eng = cg.Engine(api_key="key") with pytest.raises(ValueError, match='project id'): _ = eng.implied_job_config(None) with pytest.raises(ValueError, match='project id'): _ = eng.implied_job_config(cg.JobConfig()) assert eng.implied_job_config( cg.JobConfig(project_id='specific')).project_id == 'specific' eng_with = cg.Engine(api_key="key", default_project_id='default') # Fallback to default. assert eng_with.implied_job_config(None).project_id == 'default' # Override default. assert eng_with.implied_job_config( cg.JobConfig(project_id='specific')).project_id == 'specific'
def test_get_cancel(): engine = mock.Mock() job = qtypes.QuantumJob(name='projects/a/programs/b/jobs/steve') job = cg.EngineJob(job_config=cg.JobConfig(job_id='steve'), job=job, engine=engine) job.cancel() engine.cancel_job.assert_called_once()
def test_run_circuit(build): service = mock.Mock() build.return_value = service programs = service.projects().programs() jobs = programs.jobs() programs.create().execute.return_value = { 'name': 'projects/project-id/programs/test' } jobs.create().execute.return_value = { 'name': 'projects/project-id/programs/test/jobs/test', 'executionStatus': { 'state': 'READY' } } jobs.get().execute.return_value = { 'name': 'projects/project-id/programs/test/jobs/test', 'executionStatus': { 'state': 'SUCCESS' } } jobs.getResult().execute.return_value = {'result': _A_RESULT} engine = cg.Engine(project_id='project-id') result = engine.run(program=_CIRCUIT, job_config=cg.JobConfig('job-id'), processor_ids=['mysim']) assert result.repetitions == 1 assert result.params.param_dict == {'a': 1} assert result.measurements == {'q': np.array([[0]], dtype='uint8')} build.assert_called_with( 'quantum', 'v1alpha1', discoveryServiceUrl=('https://{api}.googleapis.com' '/$discovery/rest?version=' '{apiVersion}'), requestBuilder=mock.ANY) assert programs.create.call_args[1]['parent'] == 'projects/project-id' assert jobs.create.call_args[1] == { 'parent': 'projects/project-id/programs/test', 'body': { 'name': 'projects/project-id/programs/test/jobs/job-id', 'scheduling_config': { 'priority': 50, 'processor_selector': { 'processor_names': ['projects/project-id/processors/mysim'] } }, 'run_context': { '@type': 'type.googleapis.com/cirq.google.api.v1.RunContext', 'parameter_sweeps': [{ 'repetitions': 1 }] } } } assert jobs.get().execute.call_count == 1 assert jobs.getResult().execute.call_count == 1
def test_bad_job_config_inference_order(build): eng = cg.Engine(project_id='project-id') config = cg.JobConfig() with pytest.raises(ValueError): eng._infer_gcs_results(config) eng._infer_gcs_prefix(config) eng._infer_gcs_results(config)
def test_str(): engine = mock.Mock() job = { 'name': 'projects/a/programs/b/jobs/steve', } job = cg.EngineJob(job_config=cg.JobConfig(job_id='steve'), job=job, engine=engine) assert str(job) == 'EngineJob(projects/a/programs/b/jobs/steve)'
def test_run_sweep_params_old_proto(build): service = mock.Mock() build.return_value = service programs = service.projects().programs() jobs = programs.jobs() results_old_proto = copy.deepcopy(_RESULTS) results_old_proto[ '@type'] = 'type.googleapis.com/cirq.api.google.v1.Result' programs.create().execute.return_value = { 'name': 'projects/project-id/programs/test' } jobs.create().execute.return_value = { 'name': 'projects/project-id/programs/test/jobs/test', 'executionStatus': { 'state': 'READY' } } jobs.get().execute.return_value = { 'name': 'projects/project-id/programs/test/jobs/test', 'executionStatus': { 'state': 'SUCCESS' } } jobs.getResult().execute.return_value = {'result': results_old_proto} engine = cg.Engine(project_id='project-id') job = engine.run_sweep( program=_CIRCUIT, job_config=cg.JobConfig('project-id'), params=[cirq.ParamResolver({'a': 1}), cirq.ParamResolver({'a': 2})]) results = job.results() assert len(results) == 2 for i, v in enumerate([1, 2]): assert results[i].repetitions == 1 assert results[i].params.param_dict == {'a': v} assert results[i].measurements == {'q': np.array([[0]], dtype='uint8')} build.assert_called_with( 'quantum', 'v1alpha1', discoveryServiceUrl=('https://{api}.googleapis.com' '/$discovery/rest?version=' '{apiVersion}'), requestBuilder=mock.ANY) assert programs.create.call_args[1]['parent'] == 'projects/project-id' sweeps = jobs.create.call_args[1]['body']['run_context'][ 'parameter_sweeps'] assert len(sweeps) == 2 for i, v in enumerate([1, 2]): assert sweeps[i]['repetitions'] == 1 assert sweeps[i]['sweep']['factors'][0]['sweeps'][0]['points'][ 'points'] == [v] assert jobs.create.call_args[1][ 'parent'] == 'projects/project-id/programs/test' assert jobs.get().execute.call_count == 1 assert jobs.getResult().execute.call_count == 1
def test_run_sweep_v2_new_proto(build): service = mock.Mock() build.return_value = service programs = service.projects().programs() jobs = programs.jobs() programs.create().execute.return_value = { 'name': 'projects/project-id/programs/test' } jobs.create().execute.return_value = { 'name': 'projects/project-id/programs/test/jobs/test', 'executionStatus': { 'state': 'READY' } } jobs.get().execute.return_value = { 'name': 'projects/project-id/programs/test/jobs/test', 'executionStatus': { 'state': 'SUCCESS' } } results_new_proto = copy.deepcopy(_RESULTS_V2) results_new_proto[ '@type'] = 'type.googleapis.com/cirq.google.api.v2.Result' jobs.getResult().execute.return_value = {'result': results_new_proto} engine = cg.Engine( project_id='project-id', proto_version=cg.engine.engine.ProtoVersion.V2, ) job = engine.run_sweep(program=_SCHEDULE, job_config=cg.JobConfig( 'project-id', gcs_prefix='gs://bucket/folder'), params=cirq.Points('a', [1, 2])) results = job.results() assert engine.proto_version == cg.engine.engine.ProtoVersion.V2 assert len(results) == 2 for i, v in enumerate([1, 2]): assert results[i].repetitions == 1 assert results[i].params.param_dict == {'a': v} assert results[i].measurements == {'q': np.array([[0]], dtype='uint8')} build.assert_called_with( 'quantum', 'v1alpha1', discoveryServiceUrl=('https://{api}.googleapis.com' '/$discovery/rest?version=' '{apiVersion}'), requestBuilder=mock.ANY) assert programs.create.call_args[1]['parent'] == 'projects/project-id' sweeps = jobs.create.call_args[1]['body']['run_context']['parameterSweeps'] assert len(sweeps) == 1 assert sweeps[0]['repetitions'] == 1 assert sweeps[0]['sweep']['singleSweep']['points']['points'] == [1, 2] assert jobs.create.call_args[1][ 'parent'] == 'projects/project-id/programs/test' assert jobs.get().execute.call_count == 1 assert jobs.getResult().execute.call_count == 1
def test_circuit_device_validation_fails(build): circuit = cirq.Circuit(device=cg.Foxtail) # Purposefully create an invalid Circuit by fiddling with internal bits. # This simulates a failure in the incremental checks. circuit._moments.append(cirq.Moment([cirq.Z(cirq.NamedQubit("dorothy"))])) with pytest.raises(ValueError, match='Unsupported qubit type'): cg.Engine(project_id='project-id').run( program=circuit, job_config=cg.JobConfig('project-id'))
def test_schedule_device_validation_fails(build): scheduled_op = cirq.ScheduledOperation(time=None, duration=None, operation=cirq.H.on( cirq.NamedQubit("dorothy"))) schedule = cirq.Schedule(device=cg.Foxtail, scheduled_operations=[scheduled_op]) with pytest.raises(ValueError): cg.Engine(api_key="key").run(program=schedule, job_config=cg.JobConfig('project-id'))
def test_timeout(patched_time_sleep): engine = mock.Mock() job = qtypes.QuantumJob(name='projects/a/programs/b/jobs/steve', execution_status=qtypes.ExecutionStatus( state=qtypes.ExecutionStatus.State.RUNNING)) engine.get_job.return_value = job job = cg.EngineJob(job_config=cg.JobConfig(job_id='steve'), job=job, engine=engine) with pytest.raises(RuntimeError, match='Timed out'): job.results()
def test_status(): engine = mock.Mock() job = qtypes.QuantumJob(name='projects/a/programs/b/jobs/steve', execution_status=qtypes.ExecutionStatus( state=qtypes.ExecutionStatus.State.RUNNING)) engine.get_job.return_value = job job = cg.EngineJob(job_config=cg.JobConfig(job_id='steve'), job=job, engine=engine) assert job.status() == 'RUNNING' engine.get_job.assert_called_once()
def test_get_calibration(): engine = mock.Mock() job = qtypes.QuantumJob( name='projects/a/programs/b/jobs/steve', execution_status=qtypes.ExecutionStatus(calibration_name='hobbes')) calibration = mock.Mock() engine.get_calibration.return_value = calibration job = cg.EngineJob(job_config=cg.JobConfig(job_id='steve'), job=job, engine=engine) assert job.get_calibration() == calibration engine.get_calibration.assert_called_once_with('hobbes')