syntax = "proto3";
package services.translation;
option go_package = "gitlab.com/rigetti/share/service-model/golang/translation";
import "controller/job.proto";
import "translation/metadata.proto";

// Options specified on RPCs that translate Quil to a ControllerJob. Intended to support custom pre-processing
// and other translation features.
message TranslationOptions {

    // When set, the client program will be pre-processed via the Q-CTRL API
    // before translation.
    .services.translation.TranslationOptions.QCtrl q_ctrl = 1;
    .services.translation.TranslationOptions.Riverlane riverlane = 2;
    message QCtrl {

        // Indicates whether Q-CTRL pre-processing should consider the set of
        // program qubits to be fixed. If true, Q-CTRL may only remap qubits to
        // others specified within the user-submitted program. If false, Q-CTRL may
        // remap program qubits to any physical qubit on the device in order to
        // optimize the program.
        //
        // Note, this attribute is used to set `fixed_layouts` attribute on Q-CTRL's
        // `CompileOptions` message. Q-CTRL supports compilation of mutliple programs
        // at once, while Rigetti's `TranslationOptions` are currently scoped to a
        // single program. As such, we use `fixed_layout` rather than `fixed_layouts`.
        optional bool fixed_layout = 1;
    }
    message Riverlane {

        // The (opaque) configuration data, per instrument, to send to Riverlane's QECi box(es).
        map<string, bytes> qeci_configuration_data = 2;

        // The maximum expected latency between a `qeci_csr_read_request` extern
        // call and receiving the data with the `is_qeci_csr_read_complete` extern
        uint64 qeci_max_nanoseconds_until_read_available = 3;
    }

    // The backend to use for translation, to include relevant options.
    // If neither is specified, the implementing service may select the
    // translation backend and options.
    oneof translation_backend {
        .services.translation.BackendV1Options v1 = 101;
        .services.translation.BackendV2Options v2 = 102;
    }
}

// Options for translation backend V1
message BackendV1Options {
}

// Options for translation backend V2
message BackendV2Options {

    // Whether to prepend the default calibrations for a particular QPU to the program.
    // This may be set to false if you have prepended your own calibrations, or are submitting
    // a pre-calibrated pulse-level program which does not need further expansion.
    optional bool prepend_default_calibrations = 1;

    // The number of seconds to stall at the beginning of each num-shots loop iteration in order to allow adiabatic reset.
    optional double passive_reset_delay_seconds = 2;

    // Whether to disable bounds checks on dynamic memory access. Only available to authorized users.
    optional bool allow_unchecked_pointer_arithmetic = 4;

    // Whether to skip program frame validation against Rigetti calibrations.
    optional bool allow_frame_redefinition = 5;

    // Whether to force all real-time-classified readout values to be stored in sequencer memory. If false or unset, only readout values that are
    // read by the program are written to sequencer memory following readout.
    optional bool store_all_readout_values = 6;
}
message TranslateQuilToEncryptedControllerJobRequest {
    string quantum_processor_id = 1;
    string quil_program = 2;

    // Specification of optional translation features.
    .services.translation.TranslationOptions options = 4;
    oneof num_shots {
        uint32 num_shots_value = 3;
    }
}
message TranslateQuilToEncryptedControllerJobResponse {
    .models.controller.EncryptedControllerJob job = 1;
    .models.translation.QuilTranslationMetadata metadata = 2;
}
message QuantumProcessorQuilCalibrationProgram {

    // The Quil program containing the requested calibrations
    string quil_calibration_program = 1;
}
message GetQuantumProcessorQuilCalibrationProgramRequest {

    // The quantum processor for which to retrieve the calibration program.
    string quantum_processor_id = 1;
}

service Translation {

    rpc TranslateQuilToEncryptedControllerJob(.services.translation.TranslateQuilToEncryptedControllerJobRequest) returns (.services.translation.TranslateQuilToEncryptedControllerJobResponse) {
    }

    // Get the current calibration program for the given quantum processor.
    rpc GetQuantumProcessorQuilCalibrationProgram(.services.translation.GetQuantumProcessorQuilCalibrationProgramRequest) returns (.services.translation.QuantumProcessorQuilCalibrationProgram) {
    }
}
