in Benchmarks/Netpipe_cs/Netpipe_cs.cs [40:171]
static void Main(string[] args)
{
// Whether we should use the unsafe, Direct interface to MPI.
// When false, use the normal MPI.NET interface.
bool useDirectInterface = false;
using (MPI.Environment env = new MPI.Environment(ref args))
{
if (args.Length > 0 && args[0] == "/direct")
{
useDirectInterface = true;
System.Console.WriteLine("Using direct MPI interface.");
}
else
System.Console.WriteLine("Using MPI.NET interface.");
comm = MPI.Communicator.world;
if (comm.Size != 2)
{
if (comm.Rank == 0)
System.Console.WriteLine("Only two processes allowed. Rerun with -np 2");
return;
}
else
{
self = comm.Rank;
other = (comm.Rank + 1) % 2;
}
System.Console.WriteLine(comm.Rank + ": " + MPI.Environment.ProcessorName);
bwstats = new Stats[nSamp];
testLatency();
testSyncTime();
comm.Broadcast(ref latency, 0);
if (self == 0)
{
System.Console.WriteLine("Latency: {0:F9}", latency);
System.Console.WriteLine("Sync Time: {0:F9}", synctime);
System.Console.WriteLine("Now starting main loop");
}
int i, j, n, nq;
int inc = 1, len;
int start = 0, end = 1024 * 1024 * 1024;
int bufflen = start;
double tlast = latency;
for (n = nq = 0, len = start; tlast < stopTime && len <= end; len += inc, nq++)
{
if (nq > 2 && (nq % 2 != 0)) inc *= 2;
int ipert, pert;
for (ipert = 0, pert = (inc > PERT + 1) ? -PERT : 0;
pert <= PERT;
ipert++, n++, pert += (inc > PERT + 1) ? PERT : PERT + 1)
{
int nRepeat = bufflen == 0 ?
latencyReps :
(int)Math.Max((RUNTM / ((double)bufflen / (bufflen - inc + 1.0) * tlast)),
TRIALS);
comm.Broadcast(ref nRepeat, 0);
bufflen = len + pert;
byte[] sendBuffer = new byte[bufflen]; // Align the data? Some day. Maybe.
byte[] recvBuffer = new byte[bufflen];
if (self == 0)
System.Console.Write("{0,3:D}: {1,9:D} bytes {2,7:D} times ---> ", n, bufflen, nRepeat);
bwstats[n].t = 1e99;
double t1 = 0, t2 = 0;
for (i = 0; i < TRIALS; i++)
{
sync();
double t0 = when();
if (useDirectInterface)
{
// Use the unsafe, direct interface to MPI via P/Invoke
unsafe
{
fixed (byte* sendPtr = sendBuffer, recvPtr = recvBuffer)
{
for (j = 0; j < nRepeat; j++)
{
if (self == 0)
{
Unsafe.MPI_Send(new IntPtr(sendPtr), bufflen, Unsafe.MPI_BYTE, other, 142, Unsafe.MPI_COMM_WORLD);
Unsafe.MPI_Recv(new IntPtr(recvPtr), bufflen, Unsafe.MPI_BYTE, other, 242, Unsafe.MPI_COMM_WORLD, out *Unsafe.MPI_STATUS_IGNORE);
}
else
{
Unsafe.MPI_Recv(new IntPtr(recvPtr), bufflen, Unsafe.MPI_BYTE, other, 142, Unsafe.MPI_COMM_WORLD, out *Unsafe.MPI_STATUS_IGNORE);
Unsafe.MPI_Send(new IntPtr(sendPtr), bufflen, Unsafe.MPI_BYTE, other, 242, Unsafe.MPI_COMM_WORLD);
}
}
}
}
}
else
{
for (j = 0; j < nRepeat; j++)
{
if (self == 0)
{
comm.Send(sendBuffer, other, 142);
comm.Receive(other, 242, ref recvBuffer);
}
else
{
comm.Receive(other, 142, ref recvBuffer);
comm.Send(sendBuffer, other, 242);
}
}
}
double t = (when() - t0) / (2.0 * nRepeat);
t2 += t*t;
t1 += t;
bwstats[n].t = Math.Min(bwstats[n].t, t);
bwstats[n].variance = t2 / TRIALS - t1 / TRIALS * t1 / TRIALS;
tlast = bwstats[n].t;
bwstats[n].bits = bufflen * sizeof(byte)*8;
bwstats[n].bps = bwstats[n].bits / (bwstats[n].t * 1024 * 1024);
bwstats[n].repeat = nRepeat;
}
if (self == 0)
System.Console.WriteLine("{0,9:F2} Mbps in {1:F9} sec", bwstats[n].bps, tlast);
}
}
}
}