PacketOut and PacketIn messages are pretty much independent of each other. For example, a P4 program could be written to receive and process PacketOut messages from a controller, e.g. by making a few changes to some header fields, then sending that packet out of a non-CPU port determined by some metadata field in the controller header, or by some P4 table lookup. In such a program, there might be thousands of PacketOut messages from controller to switch with no PacketIn messages from switch to controller.
Similarly there could be times with thousands of PacketIn messages, with no PacketOut messages.
You could write a P4 program where it responds to every PacketOut packet by sending one PacketIn message back to the controller, or 10 PacketIn messages in response to every PacketOut message. Or a variable number from 0 up to 8 that cannot be easily determined by the controller in advance.