Non-unitary gate is a bit of an oxymoron for reasons explained here and here. Qiskit support non-unitary instructions. Gates are Instructions subclasses. A gate, like XGate is an instruction, but not every instruction, such as Reset, is a gate:
from qiskit.circuit import Gate, Instruction, Reset
issubclass(Reset, Instruction) # True
issubclass(Reset, Gate) # False
issubclass(XGate, Instruction) # True
issubclass(XGate, Gate) # True
So Qiskit already supports the notion of non-unitary instruction. You can create your own instruction with to_instruction. For example, this is a "reset to 1" instruction:
- Create a circuit:
from qiskit import QuantumCircuit
reset_to_one = QuantumCircuit(1, name="reset to 1")
reset_to_one.reset(0)
reset_to_one.x(0)
print(reset_to_one)
┌───┐
q: ─|0>─┤ X ├
└───┘
- Convert that circuit into a instruction:
reset_to_one_inst = reset_to_one.to_instruction()
- Add your instruction into a circuit:
circuit = QuantumCircuit(2)
circuit.h(0)
circuit.cx(0, 1)
circuit.append(reset_to_one, [1])
circuit.measure_all()
print(circuit)
┌───┐ ░ ┌─┐
q_0: ┤ H ├──■─────────────────░─┤M├───
└───┘┌─┴─┐┌────────────┐ ░ └╥┘┌─┐
q_1: ─────┤ X ├┤ reset to 1 ├─░──╫─┤M├
└───┘└────────────┘ ░ ║ └╥┘
meas: 2/════════════════════════════╩══╩═
0 1
In this case, $q_1$ will be reset to 1 before being measured into $meas_1$. reset to 1 is a non-unitary instruction.