1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
use crate::{ common::{ log::LogRecord, types::{ArbCmd, ArbData, PluginType}, }, host::configuration::PluginLogConfiguration, }; use ipc_channel::ipc::IpcSender; use serde::{Deserialize, Serialize}; /// Simulator/host to plugin requests. #[derive(Debug, PartialEq, Serialize, Deserialize)] pub enum SimulatorToPlugin { /// Request to initialize the plugin. /// /// This is always the first message sent by DQCsim. In response, the /// plugin must: /// /// - initialize its logging facilities (note that the tee files provided /// by the copy of the plugin configuration are to be handled by the /// plugin); /// - verify with the user code that the plugin implementation is of the /// expected type (frontend, operator, or backend); /// - connect to the downstream plugin if the plugin is not a backend; /// - initialize an IPC endpoint for the upstream plugin to connect to if /// the plugin is not a frontend; /// - return the aforementioned URI to the simulator through a /// `PluginToSimulator::Initialized` message. /// /// The valid responses to this message are: /// /// - success: `PluginToSimulator::Initialized` /// - failure: `PluginToSimulator::Failure` Initialize(Box<PluginInitializeRequest>), /// Request to complete the connection with the upstream plugin. /// /// This is always the second message sent by DQCsim for operators and /// backends. It is called after the upstream plugin has been successfully /// initialized. In response, the plugin must wait for the upstream plugin /// to connect and finish setting up the connection. /// /// The valid responses to this message are: /// /// - success: `PluginToSimulator::Success` /// - failure: `PluginToSimulator::Failure` AcceptUpstream, /// Request to run user initialization code. /// /// This is always the second (frontend) or third (operator, backend) /// message sent by DQCsim. /// /// The valid responses to this message are: /// /// - success: `PluginToSimulator::Success` /// - failure: `PluginToSimulator::Failure` UserInitialize(PluginUserInitializeRequest), /// Request to abort the simulation and stop the plugin. /// /// The valid responses to this message are: /// /// - success: `PluginToSimulator::Success` /// - failure: `PluginToSimulator::Failure` Abort, /// Passes control from the host to the frontend plugin. /// /// This is only to be sent to frontends. In response, the frontend must: /// /// - queue up any enclosed messages for reception through the plugin's /// `recv()` function; /// - if start is specified, call the user's implementation of the `run()` /// callback (if this message was received while already executing /// `run()`, return an error instead); /// - if the user's implementation of `run()` terminates, put its return /// value in the `result` field of the response; /// - if the user's implementation of `run()` queued up messages through /// `send()`, put them into the `messages` field of the response; /// - send the `PluginToSimulator::RunResponse` message in response. /// /// The valid responses to this message are: /// /// - success: `PluginToSimulator::RunResponse` /// - failure: `PluginToSimulator::Failure` RunRequest(FrontendRunRequest), /// Requests execution of the given `ArbCmd` by the plugin. /// /// The valid responses to this message are: /// /// - success: `PluginToSimulator::ArbResponse` /// - failure: `PluginToSimulator::Failure` ArbRequest(ArbCmd), } impl Into<SimulatorToPlugin> for ArbCmd { fn into(self) -> SimulatorToPlugin { SimulatorToPlugin::ArbRequest(self) } } /// Plugin initialization request. See `SimulatorToPlugin::Initialize`. #[derive(Debug, Serialize, Deserialize)] pub struct PluginInitializeRequest { /// Gatestream endpoint for the downstream plugin to connect to. /// /// Must be specified for frontends and operators, must not be specified /// for backends. pub downstream: Option<String>, /// The expected plugin type. pub plugin_type: PluginType, /// Random seed. pub seed: u64, /// Configuration for the logging subsystem of the plugin. pub log_configuration: PluginLogConfiguration, /// Sender side of the log channel. Can be used by a Plugin to send log /// records to the simulator. pub log_channel: IpcSender<LogRecord>, } impl Into<SimulatorToPlugin> for PluginInitializeRequest { fn into(self) -> SimulatorToPlugin { SimulatorToPlugin::Initialize(Box::new(self)) } } impl PartialEq for PluginInitializeRequest { fn eq(&self, other: &PluginInitializeRequest) -> bool { self.downstream == other.downstream && self.plugin_type == other.plugin_type && self.log_configuration == other.log_configuration } } pub struct PluginAcceptUpstreamRequest; impl Into<SimulatorToPlugin> for PluginAcceptUpstreamRequest { fn into(self) -> SimulatorToPlugin { SimulatorToPlugin::AcceptUpstream } } /// Plugin user initialization request. See /// `SimulatorToPlugin::UserInitialize`. #[derive(Debug, Serialize, Deserialize, PartialEq)] pub struct PluginUserInitializeRequest { /// Vec with initialization commands. pub init_cmds: Vec<ArbCmd>, } impl Into<SimulatorToPlugin> for PluginUserInitializeRequest { fn into(self) -> SimulatorToPlugin { SimulatorToPlugin::UserInitialize(self) } } /// Frontend run request. See `SimulatorToPlugin::RunRequest`. #[derive(Debug, PartialEq, Serialize, Deserialize)] pub struct FrontendRunRequest { /// When specified, the frontend's `run()` callback must be called with the /// contained `ArbData` as argument. pub start: Option<ArbData>, /// Messages queued up through the host's `send()` function, to be consumed /// by the plugin's `recv()` function. pub messages: Vec<ArbData>, } impl Into<SimulatorToPlugin> for FrontendRunRequest { fn into(self) -> SimulatorToPlugin { SimulatorToPlugin::RunRequest(self) } }