Also, numpy is built on some fortran libraries, like BLAS and LAPACK that assume a column major order. If it took row major input, it would need to transpose matrices in some cases change the order, or rewrite those libraries to use row major form.
So, x and y must be columns. So, it is nice if our language has column-order as the default, that way a vector is also just a good old 1d array.
If we did y=xA, x and y would be rows, the actual math would be the same but… I dunno, isn’t it just hideous? Ax is like a sentence, it should start with an upper case!
It also fits well with how we tend to learn math. First we learn about functions, f(x). Then we learn that a function can be an operator. And a matrix can represent a linear operator. So, we tend to have a long history of stuff sitting to the left of x getting ready to transform it.
For the row-major layout the multiplication Ax ends up being more cache-efficient than for the column major layout, as for calculating each component of y you need to scan x and a row of A.
I don't know if tiling is done for matvec. I don't think it makes sense there, but I didn't think about it too hard.
Is how you'd write it in NumPy and most (/all?) deep learning libraries, with x.shape=[batch, ndim]
I'd personally prefer that to be the convention, for consistency.
Is it because in much of the maths domain it turns out you manipulate columns more often than rows?
(not a mathematician but I could believe if the columns represent "dimensions" or "qualities" of some dataset, and you want to apply a function to a given dimension, having data in column-natural order makes that faster.)
Obviously you want to believe naievely there is no difference to the X and Y in the X,Y plane, but machines are not naieve and sometimes there IS a difference to doing things to the set of verticals, and the set of horizontals.