FreeNOS
MpiPing.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2020 Niek Linnenbank
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include <Log.h>
19#include <mpi.h>
20#include "MpiPing.h"
21
22MpiPing::MpiPing(int argc, char **argv)
23 : POSIXApplication(argc, argv)
24 , m_mpiInitResult(MPI_Init(&m_argc, &m_argv))
25 , m_id(0)
26{
27 parser().setDescription("Send ping message to cores via MPI");
28}
29
31{
32 DEBUG("");
33}
34
36{
38 {
39 ERROR("failed to initialize MPI: result = " << m_mpiInitResult);
40 return IOError;
41 }
42
43 int result = MPI_Comm_rank(MPI_COMM_WORLD, &m_id);
44 if (result != MPI_SUCCESS)
45 {
46 ERROR("failed to lookup MPI rank: result = " << result);
47 return IOError;
48 }
49
50 return Success;
51}
52
54{
55 int result, cores;
56
57 if (m_id == 0)
58 {
59 result = MPI_Comm_size(MPI_COMM_WORLD, &cores);
60 if (result != MPI_SUCCESS)
61 {
62 ERROR("failed to lookup MPI core count: result = " << result);
63 return IOError;
64 }
65 NOTICE("ping " << (cores - 1) << " cores");
66
67 // Master send a ping and receives a pong from each node
68 for (int i = 1; i < cores; i++)
69 {
70 const Result pingResult = sendNumber(i, PingMagicNumber);
71 if (pingResult != Success)
72 {
73 ERROR("failed to send ping to core" << i << ": result = " << (int) pingResult);
74 return pingResult;
75 }
76
77 const Result pongResult = receiveNumber(i, PongMagicNumber);
78 if (pongResult != Success)
79 {
80 ERROR("failed to receive pong from core" << i << ": result = " << (int) pongResult);
81 return pongResult;
82 }
83
84 NOTICE("pong received from core" << i);
85 }
86 }
87 else
88 {
89 // Slaves first receive a ping from the master, then reply with a pong
90 const Result recvResult = receiveNumber(0, PingMagicNumber);
91 if (recvResult != Success)
92 {
93 ERROR("failed to receive ping from core0: result = " << (int) recvResult);
94 return recvResult;
95 }
96
97 const Result sendResult = sendNumber(0, PongMagicNumber);
98 if (sendResult != Success)
99 {
100 ERROR("failed to send message to core0: result = " << (int) sendResult);
101 return sendResult;
102 }
103 }
104
105 result = MPI_Finalize();
106 if (result != MPI_SUCCESS)
107 {
108 ERROR("failed to finalize MPI: result = " << result);
109 return IOError;
110 }
111
112 return Success;
113}
114
116 const int number) const
117{
118 int buf = number;
119
120 DEBUG("coreId = " << coreId << " number = " << Number::Hex << number);
121
122 int result = MPI_Send(&buf, 1, MPI_INT, coreId, 0, MPI_COMM_WORLD);
123 if (result != MPI_SUCCESS)
124 {
125 ERROR("failed to send message to core" << coreId << ": result = " << (int) result);
126 return IOError;
127 }
128
129 return Success;
130}
131
133 const int expectedNumber) const
134{
135 int buf = 0;
136 MPI_Status status;
137
138 DEBUG("coreId = " << coreId << " expectedNumber = " << Number::Hex << expectedNumber);
139
140 int result = MPI_Recv(&buf, 1, MPI_INT, coreId, 0, MPI_COMM_WORLD, &status);
141 if (result != MPI_SUCCESS)
142 {
143 ERROR("failed to receive message from core" << coreId << ": result = " << (int) result);
144 return IOError;
145 }
146
147 if (buf != expectedNumber)
148 {
149 ERROR("invalid message " << Number::Hex << buf << " != " << Number::Hex << expectedNumber <<
150 " received from core" << coreId);
151 return IOError;
152 }
153
154 return Success;
155}
u8 coreId
Definition IntelACPI.h:1
Result
Result codes.
Definition Application.h:54
ArgumentParser & parser()
Get program arguments parser.
void setDescription(const String &desc)
Set program description.
int m_mpiInitResult
Result of MPI initialization.
Definition MpiPing.h:97
virtual Result initialize()
Initialize the application.
Definition MpiPing.cpp:35
virtual Result exec()
Execute the application.
Definition MpiPing.cpp:53
static const int PingMagicNumber
Magic number to send as ping message.
Definition MpiPing.h:36
Result receiveNumber(const Size coreId, const int expectedNumber) const
Receive a message containing a number.
Definition MpiPing.cpp:132
Result sendNumber(const Size coreId, const int number) const
Send a message containing a number.
Definition MpiPing.cpp:115
int m_id
MPI core identifier (rank) of the current process.
Definition MpiPing.h:100
MpiPing(int argc, char **argv)
Constructor.
Definition MpiPing.cpp:22
virtual ~MpiPing()
Destructor.
Definition MpiPing.cpp:30
static const int PongMagicNumber
Magic number send for the pong message.
Definition MpiPing.h:39
POSIX-compatible application.
C int MPI_Send(const void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm)
Definition mpi.cpp:36
C int MPI_Comm_rank(MPI_Comm comm, int *rank)
Definition mpi.cpp:59
C int MPI_Comm_size(MPI_Comm comm, int *size)
Definition mpi.cpp:66
C int MPI_Recv(void *buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status *status)
Definition mpi.cpp:47
C int MPI_Init(int *argc, char ***argv)
Definition mpi.cpp:24
uint MPI_Status
Status holder.
Definition mpi.h:41
C int MPI_Finalize(void)
Definition mpi.cpp:30
@ MPI_INT
Definition mpi.h:51
@ MPI_COMM_WORLD
Definition mpi.h:64
@ MPI_SUCCESS
Definition mpi.h:73
#define ERROR(msg)
Output an error message.
Definition Log.h:61
#define NOTICE(msg)
Output a notice message.
Definition Log.h:75
unsigned int Size
Any sane size indicator cannot go negative.
Definition Types.h:128
#define DEBUG(msg)
Output a debug message to standard output.
Definition Log.h:89
@ Hex
Decimal: 0-10.
Definition Types.h:171