func main() { runtime.GOMAXPROCS(runtime.NumCPU()) // Parse must be called to set the addresses flag.Parse() // Initialize the MPI routines and make sure err := mpi.Init() if err != nil { log.Fatal(err) } defer mpi.Finalize() rank := mpi.Rank() if rank == -1 { log.Fatal("Incorrect initialization") } size := mpi.Size() fmt.Printf("Hello world, I'm node %v in a land with %v nodes\n", rank, size) // Send and receive messages to and from everyone concurrently wg := &sync.WaitGroup{} wg.Add(size) for i := 0; i < size; i++ { go func(i int) { defer wg.Done() str := fmt.Sprintf("\"Hello node %v, I'm node %v\"", i, rank) if i == rank { str = fmt.Sprintf("\"I'm just node %d talking to myself\"", rank) } err := mpi.Send(str, i, 0) if err != nil { log.Fatal(err) } }(i) } wg.Add(size) for i := 0; i < size; i++ { go func(i int) { defer wg.Done() var str string err := mpi.Receive(&str, i, 0) if err != nil { log.Fatal(err) } fmt.Printf("I, node %v, received a message: %v\n", rank, str) }(i) } wg.Wait() }
func main() { rand.Seed(time.Now().UnixNano()) flag.Parse() // Initialize MPI err := mpi.Init() if err != nil { log.Fatal("error initializing: ", err) } defer mpi.Finalize() // Second check that things started okay rank := mpi.Rank() if rank < 0 { log.Fatal("Incorrect initialization") } evenRank := rank%2 == 0 size := mpi.Size() if size%2 != 0 { log.Fatal("Must have an even number of nodes for this example") } if rank == 0 { fmt.Println("Number of nodes = ", size) } // Make a random vector of bytes maxsize := msgLengths[len(msgLengths)-1] message := make([]byte, maxsize) //fmt.Println("...") for i := 0; i < maxsize/8; i++ { v := rand.Int63() binary.LittleEndian.PutUint64(message[i*8:], uint64(v)) } receive := make([]byte, maxsize) // Do a call and response between the even and the odd nodes // and record the time. The even nodes will send a message to the next // node. The odd nodes will send that message back, which will be received // by the even node. times := make([]int64, len(msgLengths)) for i, l := range msgLengths { for j := int64(0); j < nRepeats; j++ { msg := message[:l] rcv := receive[:l] start := time.Now() if evenRank { mpi.Send(msg, rank+1, 0) } else { mpi.Receive(&rcv, rank-1, 0) } if evenRank { mpi.Receive(&rcv, rank+1, 0) } else { mpi.Send(rcv, rank-1, 0) } times[i] += time.Since(start).Nanoseconds() // verify that the received message is the same as the sent message if evenRank { /* if !floats.Equal(msg, rcv) { log.Fatal("message not the same") } */ if !bytes.Equal(msg, rcv) { log.Fatal("message not the same") } } // Zero out the buffer so we don't get false positives next time for i := range rcv { rcv[i] = 0 } } } // Convert the times to microseconds for i := range times { times[i] /= time.Microsecond.Nanoseconds() times[i] /= nRepeats } // Have the even nodes print their trip time in microseconds if evenRank { fmt.Printf("Average trip time in µs between node %d and %d: %v\n", rank, rank+1, times) } }