[SPARK-3974][MLlib] Distributed Block Matrix Abstractions

This pull request includes the abstractions for the distributed BlockMatrix representation. 
`BlockMatrix` will allow users to store very large matrices in small blocks of local matrices. Specific partitioners, such as `RowBasedPartitioner` and `ColumnBasedPartitioner`, are implemented in order to optimize addition and multiplication operations that will be added in a following PR.

This work is based on the ml-matrix repo developed at the AMPLab at UC Berkeley, CA.
https://github.com/amplab/ml-matrix

Additional thanks to @rezazadeh, @shivaram, and @mengxr for guidance on the design.
That's a good question... I left it in there for the following reason, not sure if it's going to be ever required, but in the end, I thought it would be good to cover corner cases such as irregular grids:
Assume you have a matrix A with dimensions 280 x d. Assume each `SubMatrix` has a dimension 30 x d/3. The last row will consist of SubMatrices 10 x d/3.
Then you vertically append a Matrix B, with dimensions n x d. Then you're left with an irregular grid.
Maybe vertical concatenation is not as common as horizontal concatenation, but being ready to support such operations seems beneficial for users.