Example #1
0
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()
}
Example #2
0
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)
	}
}