static void DoMatrix() { int size = true ? 512 : 16; Console.WriteLine("Matrix size: " + size); Console.WriteLine("Vector size: " + Vector <float> .Count); int bumper = 0; var a = DataGenerator.Matrix(size, size + bumper); var am = new FloatMatrix2d(a); var b = DataGenerator.Matrix(size + bumper, size); var bm = new FloatMatrix2d(b); var mm = new MatrixMultiply(); if (size <= 20) { //EnsureCorrectness(a, b, mm.Naive, mm.NaiveSumUnsafe); EnsureCorrectness(a, b, mm.TransposeSum, am, bm, mm.TransposeSumStridingVectorMat2d); } TimeIt("MM - " + nameof(mm.Naive), () => mm.Naive(a, b)); TimeIt("MM - " + nameof(mm.NaiveMat2d), () => mm.NaiveMat2d(am, bm)); TimeIt("MM - " + nameof(mm.NaiveSum), () => mm.NaiveSum(a, b)); TimeIt("MM - " + nameof(mm.NaiveSumUnsafe), () => mm.NaiveSumUnsafe(a, b)); TimeIt("MM - " + nameof(mm.TransposeSum), () => mm.TransposeSum(a, b)); TimeIt("MM - " + nameof(mm.TransposeSumMat2d), () => mm.TransposeSumMat2d(am, bm)); TimeIt("MM - " + nameof(mm.TransposeSumVectorMat2d), () => mm.TransposeSumVectorMat2d(am, bm)); TimeIt("MM - " + nameof(mm.TransposeSumStridingVectorMat2d), () => mm.TransposeSumStridingVectorMat2d(am, bm)); TimeIt("MM - " + nameof(mm.TransposeSumUnsafe), () => mm.TransposeSumUnsafe(a, b)); TimeIt("MM - " + nameof(mm.StridingSum), () => mm.StridingSum(a, b)); TimeIt("MM - " + nameof(mm.StridingSumUnsafe), () => mm.StridingSumUnsafe(a, b)); TimeIt("MM - " + nameof(mm.StridingUnrolledUnsafe), () => mm.StridingUnrolledUnsafe(a, b)); }
public FloatMatrix2d TransposeSumVectorMat2d(FloatMatrix2d a, FloatMatrix2d b) { var bT = MatrixTransposeMat2d(b); var x = a.rows; var z = a.cols; var y = b.cols; FloatMatrix2d result = new FloatMatrix2d(x, y); for (int i = 0; i < x; i++) { for (int j = 0; j < y; j++) { float sum = 0f; for (int k = 0; k < z; k += Vector <float> .Count) { var am = a.Vector(i, k); var bm = bT.Vector(j, k); //sum += a[i, k] * bT[j, k]; sum += Vector.Dot <float>(am, bm); } result[i, j] = sum; } } return(result); }
static void EnsureCorrectness( float[,] a, float[,] b, Func <float[, ], float[, ], float[, ]> baseline, FloatMatrix2d am, FloatMatrix2d bm, Func <FloatMatrix2d, FloatMatrix2d, FloatMatrix2d> hypothesis) { var bl = baseline(a, b); var h = hypothesis(am, bm); for (int i = 0; i < a.GetLength(0); i++) { for (int j = 0; j < a.GetLength(1); j++) { Console.WriteLine(i + ", " + j + " --- " + bl[i, j] + " --- " + h[i, j]); } } }
public FloatMatrix2d MatrixTransposeMat2d(FloatMatrix2d m) { var x = m.rows; var y = m.cols; var result = new FloatMatrix2d(x, y); for (int i = 0; i < x; i++) { for (int j = 0; j < y; j++) { result[j, i] = m[i, j]; } } return(result); }
public FloatMatrix2d TransposeSumStridingVectorMat2d(FloatMatrix2d a, FloatMatrix2d b) { const int stride = 64 / sizeof(float); var bT = MatrixTransposeMat2d(b); var x = a.rows; var z = a.cols; var y = b.cols; FloatMatrix2d result = new FloatMatrix2d(x, y); for (int i = 0; i < x; i += stride) { for (int j = 0; j < y; j += stride) { for (int k = 0; k < z; k += stride) { for (int i2 = i; i2 < i + stride; i2++) { for (int j2 = j; j2 < j + stride; j2++) { float sum = 0f; //for (int k2 = k; k2 < k+stride; k2++) for (int k2 = k; k2 < k + stride; k2 += Vector <float> .Count) { try{ var am = a.Vector(i2, k2); var bm = bT.Vector(j2, k2); sum += Vector.Dot <float>(am, bm); }catch (Exception) { Console.WriteLine("error: " + i2 + "," + k2 + "," + j2); throw; } //sum += a[i2, k2] * bT[j2, k2]; } result[i2, j2] = sum; } } } } } return(result); }
public FloatMatrix2d NaiveMat2d(FloatMatrix2d a, FloatMatrix2d b) { var x = a.rows; var z = a.cols; var y = b.cols; var result = new FloatMatrix2d(x, y); for (int i = 0; i < x; i++) { for (int j = 0; j < y; j++) { for (int k = 0; k < z; k++) { result[i, j] += a[i, k] * b[k, j]; } } } return(result); }
public FloatMatrix2d TransposeSumMat2d(FloatMatrix2d a, FloatMatrix2d b) { var bT = MatrixTransposeMat2d(b); var x = a.rows; var z = a.cols; var y = b.cols; FloatMatrix2d result = new FloatMatrix2d(x, y); for (int i = 0; i < x; i++) { for (int j = 0; j < y; j++) { float sum = 0f; for (int k = 0; k < z; k++) { sum += a[i, k] * bT[j, k]; } result[i, j] = sum; } } return(result); }