public static Matrix <FieldType> GpuMultiply <FieldType, GpuStructType>(Matrix <FieldType> left, Matrix <FieldType> right) where FieldType : Field <FieldType>, IGpuCompatibleField <FieldType, GpuStructType>, new() where GpuStructType : struct { if (left.Width != right.Height) { throw new InvalidOperationException("Matrices of incompatible sizes can't be multiplied."); } IGpuStructManager <FieldType, GpuStructType> gpuStructManager = new FieldType().GetDefaultGpuStructManager(); GpuStructType[,] resultArr = new GpuStructType[left.Rows, right.Columns]; GpuStructType[,] leftArr = new GpuStructType[left.Rows, left.Columns]; GpuStructType[,] rightArr = new GpuStructType[right.Rows, right.Columns]; resultArr.AssignAll(gpuStructManager.GetStructDefaultValue()); leftArr.AssignAll(ind => gpuStructManager.ToStruct(left[ind[0], ind[1]])); rightArr.AssignAll(ind => gpuStructManager.ToStruct(right[ind[0], ind[1]])); Alea.Gpu gpu = Alea.Gpu.Default; int threadCount = left.Rows * right.Columns; int blockDimX = gpu.Device.Attributes.MaxThreadsPerBlock; // Threads per block int gridDimX = (int)Math.Ceiling((double)threadCount / blockDimX); // Blocks per thread LaunchParam lp = new LaunchParam(gridDimX, blockDimX); gpu.Launch(multiplicationKernel, lp, leftArr, rightArr, resultArr, gpuStructManager.GetStructAddition(), gpuStructManager.GetStructMultiplication()); FieldType[,] fieldResultArr = new FieldType[resultArr.GetLength(0), resultArr.GetLength(1)]; fieldResultArr.AssignAll(ind => gpuStructManager.ToClass(resultArr[ind[0], ind[1]])); return(new Matrix <FieldType>(fieldResultArr)); }
public Model(Alea.Gpu gpu, Reader.Reader reader) { GPU = gpu; LearningReader = reader; }