// SolveC solves the linear Complex system A.x = b // NOTES: // 1) sum_b_to_root is a flag for MUMPS; it tells Solve to sum the values in 'b' arrays to the root processor func (o *LinSolMumps) SolveC(xR, xC, bR, bC []float64, sum_b_to_root bool) (err error) { // check if !o.cmplx { return chk.Err(_linsol_mumps_err11) } // start time if o.ton { o.tini = time.Now() } // message if o.verb { io.Pfgreen("\n . . . . . . . . . . . . . . LinSolMumps.SolveC . . . . . . . . . . . . . . . \n\n") } // MUMPS: set RHS in processor # 0 if sum_b_to_root { mpi.SumToRoot(xR, bR) mpi.SumToRoot(xC, bC) // join complex values if mpi.Rank() == 0 { for i := 0; i < len(xR); i++ { o.xRC[i*2], o.xRC[i*2+1] = xR[i], xC[i] } } } else { // join complex values if mpi.Rank() == 0 { for i := 0; i < len(xR); i++ { o.xRC[i*2], o.xRC[i*2+1] = bR[i], bC[i] } } } // MUMPS: solve o.mz.job = 3 // solution code C.zmumps_c(&o.mz) // solve if o.mz.info[1-1] < 0 { return chk.Err(_linsol_mumps_err12, mumps_error(o.mz.info[1-1], o.mz.info[2-1])) } // MUMPS: split complex values if mpi.Rank() == 0 { for i := 0; i < len(xR); i++ { xR[i], xC[i] = o.xRC[i*2], o.xRC[i*2+1] } } // MUMPS: broadcast from root mpi.BcastFromRoot(xR) mpi.BcastFromRoot(xC) // duration if o.ton { io.Pfcyan("%s: Time spent in LinSolMumps.Solve = %v\n", o.name, time.Now().Sub(o.tini)) } return }
// SolveR solves the linear Real system A.x = b // NOTES: // 1) sum_b_to_root is a flag for MUMPS; it tells Solve to sum the values in 'b' arrays to the root processor func (o *LinSolMumps) SolveR(xR, bR []float64, sum_b_to_root bool) (err error) { // check if !o.is_initialised { return chk.Err("linear solver must be initialised first\n") } if o.cmplx { return chk.Err(_linsol_mumps_err09) } // start time if o.ton { o.tini = time.Now() } // message if o.verb { io.Pfgreen("\n . . . . . . . . . . . . . . LinSolMumps.SolveR . . . . . . . . . . . . . . . \n\n") } // MUMPS: set RHS in processor # 0 if sum_b_to_root { mpi.SumToRoot(xR, bR) } else { if mpi.Rank() == 0 { copy(xR, bR) // x := b } } // only proc # 0 needs the RHS if mpi.Rank() == 0 { o.m.rhs = (*C.double)(unsafe.Pointer(&xR[0])) } // MUMPS: solve o.m.job = 3 // solution code C.dmumps_c(&o.m) // solve if o.m.info[1-1] < 0 { return chk.Err(_linsol_mumps_err10, mumps_error(o.m.info[1-1], o.m.info[2-1])) } mpi.BcastFromRoot(xR) // broadcast from root // duration if o.ton { io.Pfcyan("%s: Time spent in LinSolMumps.Solve = %v\n", o.name, time.Now().Sub(o.tini)) } return }
func main() { mpi.Start(false) defer func() { mpi.Stop(false) }() if mpi.Rank() == 0 { io.PfYel("\nTest MPI 01\n") } if mpi.Size() != 3 { chk.Panic("this test needs 3 processors") } n := 11 x := make([]float64, n) id, sz := mpi.Rank(), mpi.Size() start, endp1 := (id*n)/sz, ((id+1)*n)/sz for i := start; i < endp1; i++ { x[i] = float64(i) } // Barrier mpi.Barrier() io.Pfgrey("x @ proc # %d = %v\n", id, x) // SumToRoot r := make([]float64, n) mpi.SumToRoot(r, x) var tst testing.T if id == 0 { chk.Vector(&tst, fmt.Sprintf("SumToRoot: r @ proc # %d", id), 1e-17, r, []float64{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) } else { chk.Vector(&tst, fmt.Sprintf("SumToRoot: r @ proc # %d", id), 1e-17, r, make([]float64, n)) } // BcastFromRoot r[0] = 666 mpi.BcastFromRoot(r) chk.Vector(&tst, fmt.Sprintf("BcastFromRoot: r @ proc # %d", id), 1e-17, r, []float64{666, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) // AllReduceSum setslice(x) w := make([]float64, n) mpi.AllReduceSum(x, w) chk.Vector(&tst, fmt.Sprintf("AllReduceSum: w @ proc # %d", id), 1e-17, w, []float64{110, 110, 110, 1021, 1021, 1021, 2032, 2032, 2032, 3043, 3043}) // AllReduceSumAdd setslice(x) y := []float64{-1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000} mpi.AllReduceSumAdd(y, x, w) chk.Vector(&tst, fmt.Sprintf("AllReduceSumAdd: y @ proc # %d", id), 1e-17, y, []float64{-890, -890, -890, 21, 21, 21, 1032, 1032, 1032, 2043, 2043}) // AllReduceMin setslice(x) mpi.AllReduceMin(x, w) chk.Vector(&tst, fmt.Sprintf("AllReduceMin: x @ proc # %d", id), 1e-17, x, []float64{0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3}) // AllReduceMax setslice(x) mpi.AllReduceMax(x, w) chk.Vector(&tst, fmt.Sprintf("AllReduceMax: x @ proc # %d", id), 1e-17, x, []float64{100, 100, 100, 1000, 1000, 1000, 2000, 2000, 2000, 3000, 3000}) }