/// <summary> /// If you just want to get the <see cref="BlockMsrMatrix"/>, which corresponds to this <see cref="BlockMask"/>. /// This is the method to choose! In addition, MPI communicator can be defined via <paramref name="comm"/>. /// </summary> /// <returns>submatrix on <paramref name="comm"/></returns> public BlockMsrMatrix GetSubBlockMatrix(BlockMsrMatrix source, MPI_Comm comm) { if (source == null) { throw new ArgumentNullException(); } if (source.NoOfRows < BMLoc.LocalDOF) { throw new ArgumentException(); } BlockMsrMatrix target; if (m_includeExternalCells) { BlockPartitioning targetBlocking = new BlockPartitioning(BMLoc.LocalDOF + BMExt.LocalDOF, SubMatrixOffsets, SubMatrixLen, comm); //make an extended block dummy to fit local and external blocks target = new BlockMsrMatrix(targetBlocking, targetBlocking); //get the external rows via MPI exchange var ExtRowsTmp = m_ExtRows; int offset = BMLoc.m_GlobalMask.Count; var extBlockRows = BMExt.m_GlobalMask.Count.ForLoop(i => i + offset); var extBlockCols = BMExt.m_GlobalMask.Count.ForLoop(i => i + offset); //ExtRowsTmp lives at the MPI-Communicator of the target, thus the global index is related to a new partitioning and has nothing to do with the partitioning of the multigrid operator ... var GlobalIdxExtRows = BMExt.m_GlobalMask.Count.ForLoop(i => BMExt.m_LocalMask[i] - m_map.LocalLength); for (int iGlob = 0; iGlob < GlobalIdxExtRows.Count(); iGlob++) { Debug.Assert(GlobalIdxExtRows[iGlob] < ExtRowsTmp._RowPartitioning.LocalLength); GlobalIdxExtRows[iGlob] += ExtRowsTmp._RowPartitioning.i0; Debug.Assert(ExtRowsTmp._RowPartitioning.IsInLocalRange(GlobalIdxExtRows[iGlob])); } //add local Block ... source.WriteSubMatrixTo(target, BMLoc.m_GlobalMask, default(int[]), BMLoc.m_GlobalMask, default(int[])); //add columns related to external rows ... source.AccSubMatrixTo(1.0, target, BMLoc.m_GlobalMask, default(int[]), new int[0], default(int[]), BMExt.m_GlobalMask, extBlockCols); //add external rows ... ExtRowsTmp.AccSubMatrixTo(1.0, target, GlobalIdxExtRows, extBlockRows, BMLoc.m_GlobalMask, default(int[]), BMExt.m_GlobalMask, extBlockCols); } else { BlockPartitioning localBlocking = new BlockPartitioning(BMLoc.LocalDOF, SubMatrixOffsets, SubMatrixLen, csMPI.Raw._COMM.SELF, i0isLocal: true); target = new BlockMsrMatrix(localBlocking); source.AccSubMatrixTo(1.0, target, BMLoc.m_GlobalMask, default(int[]), BMLoc.m_GlobalMask, default(int[])); } Debug.Assert(target != null); return(target); }
public static BlockMsrMatrix ConvertToQuadraticBMsr(this BlockMsrMatrix M, int[] Colidx, bool isinternal) { Debug.Assert(M._RowPartitioning.LocalLength == Colidx.Length); int NoOfBlocks = M._RowPartitioning.LocalNoOfBlocks; int[] Offsets = new int[NoOfBlocks]; int[] Lengths = new int[NoOfBlocks]; int IdxOffset = M._RowPartitioning.i0; int ColIdxOffset = M._ColPartitioning.i0; for (int i = 0; i < NoOfBlocks; i++) { int iBlock = i + M._RowPartitioning.FirstBlock; Offsets[i] = M._RowPartitioning.GetBlockI0(iBlock) - IdxOffset; Lengths[i] = M._RowPartitioning.GetBlockLen(iBlock); } BlockPartitioning part = new BlockPartitioning(M._RowPartitioning.LocalLength, Offsets, Lengths, csMPI.Raw._COMM.SELF, true); BlockMsrMatrix ret = new BlockMsrMatrix(part); int[] RowISrc = M._RowPartitioning.LocalLength.ForLoop(i => i + IdxOffset); //int[] ColISrc = M._ColPartitioning.LocalLength.ForLoop(i => Colidx[i]); //if (ColISrc.Length < RowISrc.Length) // ExtISrc = (RowISrc.Length - ColISrc.Length).ForLoop(i => Colidx[i+ ColISrc.Length]); int[] ExtISrc = M._RowPartitioning.LocalLength.ForLoop(i => Colidx[i]); int[] ExtITrg = M._RowPartitioning.LocalLength.ForLoop(i => i); if (isinternal) { M.AccSubMatrixTo(1.0, ret, RowISrc, default(int[]), ExtISrc, default(int[])); } else { M.AccSubMatrixTo(1.0, ret, RowISrc, default(int[]), new int[0], default(int[]), ExtISrc, ExtITrg); } return(ret); }
public static void SubMatrixTest( [Values(XDGusage.none, XDGusage.mixed1, XDGusage.mixed2, XDGusage.all)] XDGusage UseXdg, [Values(1, 3)] int DGOrder, [Values(false, true)] bool compressL1, [Values(false, true)] bool compressL2) { unsafe { int[] Params = new int[8], ParamsGlob = new int[8]; fixed(int *pParams = Params, pParamsGlob = ParamsGlob) { pParams[0] = (int)UseXdg; pParams[1] = DGOrder; pParams[2] = compressL1 ? 1 : 0; pParams[3] = compressL2 ? 1 : 0; pParams[4] = -pParams[0]; pParams[5] = -pParams[1]; pParams[6] = -pParams[2]; pParams[7] = -pParams[3]; csMPI.Raw.Allreduce((IntPtr)pParams, (IntPtr)pParamsGlob, 8, csMPI.Raw._DATATYPE.INT, csMPI.Raw._OP.MIN, csMPI.Raw._COMM.WORLD); } int[] ParamsMin = ParamsGlob.GetSubVector(0, 4); int[] ParamsMax = ParamsGlob.GetSubVector(4, 4); for (int i = 0; i < 4; i++) { if (Params[i] != ParamsMin[i]) { throw new ApplicationException(); } if (Params[i] != -ParamsMax[i]) { throw new ApplicationException(); } } Console.WriteLine("SubMatrixTest({0},{1},{2},{3})", UseXdg, DGOrder, compressL1, compressL2); } using (var solver = new Matrix_MPItestMain() { m_UseXdg = UseXdg, m_DGorder = DGOrder }) { // create the test data // ==================== BoSSS.Solution.Application.CommandLineOptions opts = null; //opts = new BoSSS.Solution.Application.CommandLineOptions(); solver.Init(null, opts); solver.RunSolverMode(); Stopwatch stw = new Stopwatch(); stw.Reset(); stw.Start(); BlockMsrMatrix M = solver.OperatorMatrix; int[] Ilist1 = solver.ProblemMapping.GetSubvectorIndices(false, 0); int[] Ilist2 = solver.ProblemMapping.GetSubvectorIndices(false, 1); foreach (int i in Ilist1) { Assert.IsTrue(solver.ProblemMapping.IsInLocalRange(i)); } foreach (int i in Ilist2) { Assert.IsTrue(solver.ProblemMapping.IsInLocalRange(i)); } var Blk1 = solver.ProblemMapping.GetSubBlocking(Ilist1, csMPI.Raw._COMM.WORLD, compressL1 ? -1 : 0); var Blk2 = solver.ProblemMapping.GetSubBlocking(Ilist2, csMPI.Raw._COMM.WORLD, compressL2 ? -1 : 0); int[] Tlist1 = compressL1 ? default(int[]) : Blk1.GetOccupiedIndicesList(); int[] Tlist2 = compressL2 ? default(int[]) : Blk2.GetOccupiedIndicesList(); if (Tlist1 != null) { Assert.AreEqual(Tlist1.Length, Ilist1.Length); foreach (int i in Tlist1) { Assert.IsTrue(Blk1.IsInLocalRange(i)); } } if (Tlist2 != null) { Assert.AreEqual(Tlist2.Length, Ilist2.Length); foreach (int i in Tlist2) { Assert.IsTrue(Blk2.IsInLocalRange(i)); } } BlockMsrMatrix M11 = new BlockMsrMatrix(Blk1, Blk1); BlockMsrMatrix M12 = new BlockMsrMatrix(Blk1, Blk2); BlockMsrMatrix M21 = new BlockMsrMatrix(Blk2, Blk1); BlockMsrMatrix M22 = new BlockMsrMatrix(Blk2, Blk2); M.AccSubMatrixTo(1.0, M11, Ilist1, Tlist1, Ilist1, Tlist1); M.AccSubMatrixTo(1.0, M12, Ilist1, Tlist1, Ilist2, Tlist2); M.AccSubMatrixTo(1.0, M21, Ilist2, Tlist2, Ilist1, Tlist1); M.AccSubMatrixTo(1.0, M22, Ilist2, Tlist2, Ilist2, Tlist2); BlockMsrMatrix restored_M = new BlockMsrMatrix(M._RowPartitioning, M._ColPartitioning); int[] Idx1 = compressL1 ? Blk1.LocalLength.ForLoop(i => i + Blk1.i0) : Tlist1; int[] Idx2 = compressL2 ? Blk2.LocalLength.ForLoop(i => i + Blk2.i0) : Tlist2; M11.AccSubMatrixTo(1.0, restored_M, Idx1, Ilist1, Idx1, Ilist1); M12.AccSubMatrixTo(1.0, restored_M, Idx1, Ilist1, Idx2, Ilist2); M21.AccSubMatrixTo(1.0, restored_M, Idx2, Ilist2, Idx1, Ilist1); M22.AccSubMatrixTo(1.0, restored_M, Idx2, Ilist2, Idx2, Ilist2); // test transpose-operator var M_TT = M.Transpose().Transpose(); var M11_TT = M11.Transpose().Transpose(); var M12_TT = M12.Transpose().Transpose(); var M21_TT = M21.Transpose().Transpose(); var M22_TT = M22.Transpose().Transpose(); M_TT.Acc(-1.0, M); M11_TT.Acc(-1.0, M11); M12_TT.Acc(-1.0, M12); M21_TT.Acc(-1.0, M21); M22_TT.Acc(-1.0, M22); double M_TT_norm = M_TT.InfNorm(); double M11_TT_norm = M11_TT.InfNorm(); double M12_TT_norm = M12_TT.InfNorm(); double M21_TT_norm = M21_TT.InfNorm(); double M22_TT_norm = M22_TT.InfNorm(); Assert.IsTrue(M_TT_norm == 0.0, "Transpose^2 is not identity."); Assert.IsTrue(M11_TT_norm == 0.0, "Transpose^2 is not identity."); Assert.IsTrue(M12_TT_norm == 0.0, "Transpose^2 is not identity."); Assert.IsTrue(M21_TT_norm == 0.0, "Transpose^2 is not identity."); Assert.IsTrue(M22_TT_norm == 0.0, "Transpose^2 is not identity."); //M.SaveToTextFileSparse(@"C:\tmp\M.txt"); //M11.SaveToTextFileSparse(@"C:\tmp\M11.txt"); //M12.SaveToTextFileSparse(@"C:\tmp\M12.txt"); //M21.SaveToTextFileSparse(@"C:\tmp\M21.txt"); //M22.SaveToTextFileSparse(@"C:\tmp\M22.txt"); //restored_M.SaveToTextFileSparse(@"C:\tmp\Mr.txt"); stw.Stop(); using (var MatlabRef = new BatchmodeConnector()) { MatlabRef.PutVector(Ilist1.Select(i => (double)i + 1.0).ToArray(), "Ilist1"); MatlabRef.PutVector(Ilist2.Select(i => (double)i + 1.0).ToArray(), "Ilist2"); MatlabRef.PutVector(Tlist1 == null ? Ilist1.Length.ForLoop(i => (double)i + 1.0 + Blk1.i0) : Tlist1.Select(i => (double)i + 1.0).ToArray(), "Tlist1"); MatlabRef.PutVector(Tlist2 == null ? Ilist2.Length.ForLoop(i => (double)i + 1.0 + Blk2.i0) : Tlist2.Select(i => (double)i + 1.0).ToArray(), "Tlist2"); MultidimensionalArray CheckRes = MultidimensionalArray.Create(1, 4); MatlabRef.PutSparseMatrix(M, "M"); MatlabRef.PutSparseMatrix(M11, "M11"); MatlabRef.PutSparseMatrix(M12, "M12"); MatlabRef.PutSparseMatrix(M21, "M21"); MatlabRef.PutSparseMatrix(M22, "M22"); MatlabRef.Cmd("L1 = {0};", Blk1.TotalLength); MatlabRef.Cmd("L2 = {0};", Blk2.TotalLength); MatlabRef.Cmd("refM11 = sparse(L1, L1);"); MatlabRef.Cmd("refM12 = sparse(L1, L2);"); MatlabRef.Cmd("refM21 = sparse(L2, L1);"); MatlabRef.Cmd("refM22 = sparse(L2, L2);"); MatlabRef.Cmd("refM11(Tlist1, Tlist1) = M(Ilist1, Ilist1);"); MatlabRef.Cmd("refM12(Tlist1, Tlist2) = M(Ilist1, Ilist2);"); MatlabRef.Cmd("refM21(Tlist2, Tlist1) = M(Ilist2, Ilist1);"); MatlabRef.Cmd("refM22(Tlist2, Tlist2) = M(Ilist2, Ilist2);"); MatlabRef.Cmd("err11 = norm(refM11 - M11, inf);"); MatlabRef.Cmd("err12 = norm(refM12 - M12, inf);"); MatlabRef.Cmd("err21 = norm(refM21 - M21, inf);"); MatlabRef.Cmd("err22 = norm(refM22 - M22, inf);"); MatlabRef.Cmd("CheckRes = [err11, err12, err21, err22];"); MatlabRef.GetMatrix(CheckRes, "CheckRes"); MatlabRef.Execute(); Console.WriteLine("Matlab check 11: " + CheckRes[0, 0]); Console.WriteLine("Matlab check 12: " + CheckRes[0, 1]); Console.WriteLine("Matlab check 21: " + CheckRes[0, 2]); Console.WriteLine("Matlab check 22: " + CheckRes[0, 3]); Assert.IsTrue(CheckRes[0, 0] == 0.0); Assert.IsTrue(CheckRes[0, 1] == 0.0); Assert.IsTrue(CheckRes[0, 2] == 0.0); Assert.IsTrue(CheckRes[0, 3] == 0.0); } stw.Start(); restored_M.Acc(-1.0, M); double err = restored_M.InfNorm(); Console.WriteLine("Submatrix operations error: " + err); Assert.IsTrue(err == 0.0); restored_M.Clear(); restored_M.Acc(1.0, M); IMutuableMatrixEx_Extensions.Acc(restored_M, -1.0, M); double err2 = restored_M.InfNorm(); Console.WriteLine("Submatrix operations error: " + err2); Assert.IsTrue(err2 == 0.0); stw.Stop(); Console.WriteLine("Time spend in matrix operations: " + stw.Elapsed.TotalSeconds + " sec."); TotTime_MatrixOp += stw.Elapsed; } }
public static void MultiplyTest( [Values(XDGusage.none, XDGusage.mixed1, XDGusage.mixed2, XDGusage.all)] XDGusage UseXdg, [Values(1, 3)] int DGOrder, [Values(false, true)] bool compressL1, [Values(false, true)] bool compressL2) { unsafe { int[] Params = new int[8], ParamsGlob = new int[8]; fixed(int *pParams = Params, pParamsGlob = ParamsGlob) { pParams[0] = (int)UseXdg; pParams[1] = DGOrder; pParams[2] = compressL1 ? 1 : 0; pParams[3] = compressL2 ? 1 : 0; pParams[4] = -pParams[0]; pParams[5] = -pParams[1]; pParams[6] = -pParams[2]; pParams[7] = -pParams[3]; csMPI.Raw.Allreduce((IntPtr)pParams, (IntPtr)pParamsGlob, 8, csMPI.Raw._DATATYPE.INT, csMPI.Raw._OP.MIN, csMPI.Raw._COMM.WORLD); } int[] ParamsMin = ParamsGlob.GetSubVector(0, 4); int[] ParamsMax = ParamsGlob.GetSubVector(4, 4); for (int i = 0; i < 4; i++) { if (Params[i] != ParamsMin[i]) { throw new ApplicationException(); } if (Params[i] != -ParamsMax[i]) { throw new ApplicationException(); } } Console.WriteLine("MultiplyTest({0},{1},{2},{3})", UseXdg, DGOrder, compressL1, compressL2); } using (var solver = new Matrix_MPItestMain() { m_UseXdg = UseXdg, m_DGorder = DGOrder }) { // create the test data // ==================== solver.Init(null); solver.RunSolverMode(); Stopwatch stw = new Stopwatch(); stw.Reset(); stw.Start(); BlockMsrMatrix M = solver.OperatorMatrix; int[] Ilist1 = solver.ProblemMapping.GetSubvectorIndices(false, 0); int[] Ilist2 = solver.ProblemMapping.GetSubvectorIndices(false, 1); foreach (int i in Ilist1) { Assert.IsTrue(solver.ProblemMapping.IsInLocalRange(i)); } foreach (int i in Ilist2) { Assert.IsTrue(solver.ProblemMapping.IsInLocalRange(i)); } var Blk1 = solver.ProblemMapping.GetSubBlocking(Ilist1, csMPI.Raw._COMM.WORLD, compressL1 ? -1 : 0); var Blk2 = solver.ProblemMapping.GetSubBlocking(Ilist2, csMPI.Raw._COMM.WORLD, compressL2 ? -1 : 0); int[] Tlist1 = compressL1 ? default(int[]) : Blk1.GetOccupiedIndicesList(); int[] Tlist2 = compressL2 ? default(int[]) : Blk2.GetOccupiedIndicesList(); if (Tlist1 != null) { Assert.AreEqual(Tlist1.Length, Ilist1.Length); foreach (int i in Tlist1) { Assert.IsTrue(Blk1.IsInLocalRange(i)); } } if (Tlist2 != null) { Assert.AreEqual(Tlist2.Length, Ilist2.Length); foreach (int i in Tlist2) { Assert.IsTrue(Blk2.IsInLocalRange(i)); } } BlockMsrMatrix M11 = new BlockMsrMatrix(Blk1, Blk1); BlockMsrMatrix M12 = new BlockMsrMatrix(Blk1, Blk2); BlockMsrMatrix M21 = new BlockMsrMatrix(Blk2, Blk1); BlockMsrMatrix M22 = new BlockMsrMatrix(Blk2, Blk2); M.AccSubMatrixTo(1.0, M11, Ilist1, Tlist1, Ilist1, Tlist1); M.AccSubMatrixTo(1.0, M12, Ilist1, Tlist1, Ilist2, Tlist2); M.AccSubMatrixTo(1.0, M21, Ilist2, Tlist2, Ilist1, Tlist1); M.AccSubMatrixTo(1.0, M22, Ilist2, Tlist2, Ilist2, Tlist2); /* * MultidimensionalArray CheckRes2 = MultidimensionalArray.Create(1, 4); * using (var MatlabRef = new BatchmodeConnector()) { * * MatlabRef.PutVector(Ilist1.Select(i => (double)i + 1.0).ToArray(), "Ilist1"); * MatlabRef.PutVector(Ilist2.Select(i => (double)i + 1.0).ToArray(), "Ilist2"); * MatlabRef.PutVector(Tlist1 == null ? Ilist1.Length.ForLoop(i => (double)i + 1.0 + Blk1.i0) : Tlist1.Select(i => (double)i + 1.0).ToArray(), "Tlist1"); * MatlabRef.PutVector(Tlist2 == null ? Ilist2.Length.ForLoop(i => (double)i + 1.0 + Blk2.i0) : Tlist2.Select(i => (double)i + 1.0).ToArray(), "Tlist2"); * * MatlabRef.PutSparseMatrix(solver.AltOperatorMatrix, "M"); * * * MatlabRef.Cmd("L1 = {0};", Blk1.TotalLength); * MatlabRef.Cmd("L2 = {0};", Blk2.TotalLength); * //MatlabRef.Cmd("refM11 = sparse(L1, L1);"); * //MatlabRef.Cmd("refM12 = sparse(L1, L2);"); * MatlabRef.Cmd("refM21 = sparse(L2, L1);"); * //MatlabRef.Cmd("refM22 = sparse(L2, L2);"); * * //MatlabRef.Cmd("refM11(Tlist1, Tlist1) = M(Ilist1, Ilist1);"); * //MatlabRef.Cmd("refM12(Tlist1, Tlist2) = M(Ilist1, Ilist2);"); * MatlabRef.Cmd("refM21(Tlist2, Tlist1) = M(Ilist2, Ilist1);"); * //MatlabRef.Cmd("refM22(Tlist2, Tlist2) = M(Ilist2, Ilist2);"); * * //MatlabRef.Cmd("err11 = norm(refM11 - M11, inf);"); * //MatlabRef.Cmd("err12 = norm(refM12 - M12, inf);"); * //MatlabRef.Cmd("err21 = norm(refM21 - M21, inf);"); * //MatlabRef.Cmd("err22 = norm(refM22 - M22, inf);"); * * MatlabRef.Cmd("CheckRes = [refM21(1339, 1321), 0.0, 1.567, 0 ];"); * MatlabRef.GetMatrix(CheckRes2, "CheckRes"); * * MatlabRef.Execute(); * } */ // test multipliation (later verified by matlab) BlockMsrMatrix M11xM12 = new BlockMsrMatrix(M11._RowPartitioning, M12._ColPartitioning); M11xM12.Acc(1.0, M12); BlockMsrMatrix.Multiply(M11xM12, M11, M12); BlockMsrMatrix M22xM21 = new BlockMsrMatrix(M22._RowPartitioning, M21._ColPartitioning); BlockMsrMatrix.Multiply(M22xM21, M22, M21); double ProdNorm = M22xM21.InfNorm(); stw.Stop(); //M.SaveToTextFileSparse(@"C:\tmp\M.txt"); //M11.SaveToTextFileSparse(@"C:\tmp\M11.txt"); //M12.SaveToTextFileSparse(@"C:\tmp\M12.txt"); //M21.SaveToTextFileSparse(@"C:\tmp\M21.txt"); //M22.SaveToTextFileSparse(@"C:\tmp\M22.txt"); //M22xM21.SaveToTextFileSparse(@"C:\tmp\M22xM21.txt"); using (var MatlabRef = new BatchmodeConnector()) { MultidimensionalArray CheckRes = MultidimensionalArray.Create(1, 4); MatlabRef.PutSparseMatrix(M11, "M11"); MatlabRef.PutSparseMatrix(M12, "M12"); MatlabRef.PutSparseMatrix(M21, "M21"); MatlabRef.PutSparseMatrix(M22, "M22"); MatlabRef.PutSparseMatrix(M11xM12, "M11xM12"); MatlabRef.PutSparseMatrix(M22xM21, "M22xM21"); MatlabRef.Cmd("refM11xM12 = M12 + M11*M12;"); MatlabRef.Cmd("refM22xM21 = M22*M21;"); MatlabRef.Cmd("err1112 = norm(refM11xM12 - M11xM12, inf);"); MatlabRef.Cmd("err2221 = norm(refM22xM21 - M22xM21, inf);"); MatlabRef.Cmd("CheckRes = [err1112, err2221, 0, 0];"); MatlabRef.GetMatrix(CheckRes, "CheckRes"); MatlabRef.Execute(); Console.WriteLine("Matlab check M11*M12: " + CheckRes[0, 0]); Console.WriteLine("Matlab check M22*M21: " + CheckRes[0, 1]); Assert.IsTrue(CheckRes[0, 0] == 0.0); Assert.IsTrue(CheckRes[0, 1] < 1.0e-10 * ProdNorm); //Assert.IsTrue(CheckRes[0, 2] == 0.0); //Assert.IsTrue(CheckRes[0, 3] == 0.0); } Console.WriteLine("Time spend in matrix operations: " + stw.Elapsed.TotalSeconds + " sec."); TotTime_MatrixOp += stw.Elapsed; } }