I found one using a program: [('row', 0, 1), ('row', 1, 2), ('row', 2, 0), ('row', 0, 3), ('col', 2, 3), ('col', 1, 2), ('col', 0, 1)]. It says it's the optimal.
You could use 7 row operations. row and col ops commute, and your last 3 col ops are equivalent to ('row', 1, 0), ('row', 2, 1), ('row', 3, 2) if acted on identity matrix. So, use them at first, and then your four row ops.
Alternatively, you could use 7 col. Your 4 row ops are equivalent to ('col', 3, 0), ('col', 0, 2), ('col', 2, 1), ('col', 1, 0).
With 8 moves and rows only: 2->1, 1->2, 2->1, 3->2, 2->3, 4->3, 4->1, 1->4.
A more efficient solution should be possible; did anyone find any?