%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
\chapter{C++ Source for POSSE Test Programs}\label{ch:POSSE_test}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
\section{Single Client Performance Test}
\label{ch:scp}
\subsection{Server-side program}
\label{ch:scp_server}
\begin{scriptsize}
\begin{verbatim}
//**************************************************************************
#include <math.h>
#include <string.h>
#include <iomanip.h>
#include "alloc.h"
#include "misc.h"
#include "dataserver.h"
//**************************************************************************
// Define all data that has to be registered for being served as "global"
int run_flag = 1;
double *dyn1D;
int n1;
int dim1;
//**************************************************************************
// Callback function to change the dimension of 1D array to "dim1".
void UpdateDimension()
        { FREE1D(&dyn1D, n1); n1 = dim1; ALLOC1D(&dyn1D, n1); }
//**************************************************************************
// Register all the variables/data here along with their handles/keywords
REGISTER_DATA_BLOCK()
{
REGISTER_VARIABLE("run_flag", "rw", run_flag);
REGISTER_VARIABLE("dimension", "rw", dim1);
REGISTER_DYNAMIC_1D_ARRAY("dyn1D", "ro", dyn1D, n1);
}
//**************************************************************************
int main(int argc, char *argv[])
{
int port = 4096;
if (argc > 1)
      port = atoi(argv[1]);

DataServer *Server = new DataServer;

n1 = 1;
ALLOC1D(&dyn1D, n1);

// Fill the Array with some values
for (int i = 0; i < n1; i++)
      dyn1D[i] = i*1.0;

// Start the server
while (Server->Start(port) != CSL_SUCCESS) { }
Server->RegisterCallback("dimension", (void(*)(void*)) UpdateDimension, NULL);
int start_time = myTimer();

// Sleep while run_flag is true
while (run_flag) mySleep(10*1000);            // Sleep for 10 ms

// Stop the server
Server->Stop();

double bytes_sent = Server->BytesSent();
delete Server;
int uptime = myTimer()-start_time;      // in ms

cout << "Effective network bandwidth = " << setprecision(4) 
      << 8.0*bytes_sent/(1000.0*uptime) << " Mbps." << endl;

FREE1D(&dyn1D, n1);
}
/****************************************************************************/
\end{verbatim}
\end{scriptsize}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
\subsection{Client-side program}
\label{ch:scp_client}
\begin{scriptsize}
\begin{verbatim}
//**************************************************************************
#include <math.h>
#include <iomanip.h>
#include "dataclient.h"
//**************************************************************************
int parseArg(int argc, char *argv[], char *tag);
//**************************************************************************
int main(int argc, char *argv[])
{
char servername[100];
int port = 4096;
if (argc < 2)
      {
       cout << "Usage: client <server-name>" << endl;
       exit(-1);
      }
strcpy(servername, argv[1]);

if (int index = parseArg(argc, argv, "-port"))
      port = atoi(argv[index]);

DataClient *client = new DataClient;

// Connect to the server
if (client->Connect(servername, port) != CSL_SUCCESS)
      {
       cout << "Connection to " << servername << ":" << port << " failed!" << endl;
       delete client;
       exit(-1);
      }


int start = 0;
int end = 1000000;
int interval = 1000;      // in ms

if (int index = parseArg(argc, argv, "-start"))
      start = atoi(argv[index]);
if (int index = parseArg(argc, argv, "-end"))
      end = atoi(argv[index]);
if (int index = parseArg(argc, argv, "-interval"))
      interval = atoi(argv[index]);

// Loop to receive Array with different sizes ranging from "start"
// to "end" elements with "interval" interval.
for (int i = start; i <= end; i += interval)
      {
       double *dyn1D;
       // Set dimension of the 1D array 
       client->SendVariable("dimension", i);
       // Receive dimension for verification
       int n1 = client->getArrayDim("dyn1D", 1);
       // Make sure that dimensions match
       assert(n1 == i);

       // Allocate appropriate memory and receive array and 
       // time the communication.
       ALLOC1D(&dyn1D, n1);
       int starttime = myTimer();
       client->RecvArray1D("dyn1D", dyn1D);
       int commtime = myTimer()-starttime;
       FREE1D(&dyn1D, n1);

       cout << n1*8 << " " << commtime << " " << setprecision(4) 
            << 8.0*8.0*n1/(1000.0*commtime) <<  endl << flush;
      }
// Print statistics
cout << "Total Bytes sent = " << setprecision(5) << client->BytesSent() 
      << " at the rate of " << client->SendRate() << " Mbps." << endl;
cout << "Total Bytes recd = " << setprecision(5) << client->BytesRecd() 
      << " at the rate of " << client->RecvRate() << " Mbps." << endl;

delete client;
}
/****************************************************************************/
int parseArg(int argc, char *argv[], char *tag)
{
for (int i = 1; i < argc; i++)
      if (strstr(argv[i], tag) == argv[i] && strlen(tag) == strlen(argv[i]))
                 return i+1;
return 0;
}
/****************************************************************************/
\end{verbatim}
\end{scriptsize}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
\section{Multiple Client Performance Test}
\label{ch:mcp}
\subsection{Server-side program}
\label{ch:mcp_server}
\begin{scriptsize}
\begin{verbatim}
//**************************************************************************
#include <math.h>
#include <string.h>
#include <iomanip.h>
#include "alloc.h"
#include "misc.h"
#include "dataserver.h"
//**************************************************************************
// Define all data that has to be registered for being served as "global"
int run_flag = 1;
double ****dyn4D;
int n1, n2, n3, n4;
//**************************************************************************
// Register all the variables/data here along with their handles/keywords
REGISTER_DATA_BLOCK()
{
REGISTER_VARIABLE("run_flag", "rw", run_flag);
REGISTER_DYNAMIC_4D_ARRAY("dyn4D", "rw", dyn4D, n1, n2, n3, n4);
}
//**************************************************************************
int main(int argc, char *argv[])
{
int port = 4096;
if (argc > 1)
      port = atoi(argv[1]);

DataServer *Server = new DataServer;

n1 = 8;
n2 = 66;
n3 = 55;
n4 = 7;

// Allocate memory to the 4D array
ALLOC4D(&dyn4D, n1, n2, n3, n4);

// Fill the array with some values
for (int i = 0; i < n1; i++)
for (int j = 0; j < n2; j++)
for (int k = 0; k < n3; k++)
for (int l = 0; l < n4; l++)
      dyn4D[i][j][k][l] = (i+1)*100+(j+1)*10+(k+1)*1+(l+1)/10.0;

// Start the server
while (Server->Start(port) != CSL_SUCCESS) { }
int start_time = myTimer();

// Sleep while run_flag is true
while (run_flag) mySleep(10*1000);            // Sleep for 10 ms

// Stop the server
Server->Stop();

double bytes_sent = Server->BytesSent();
delete Server;
int uptime = myTimer()-start_time;      // in ms

cout << "Effective network bandwidth = " << setprecision(4) 
      << 8.0*bytes_sent/(1000.0*uptime) << " Mbps." << endl;

FREE4D(&dyn4D, n1, n2, n3, n4);
}
/****************************************************************************/
\end{verbatim}
\end{scriptsize}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
\subsection{Client-side program}
\label{ch:mcp_client}
\begin{scriptsize}
\begin{verbatim}
//**************************************************************************
#include <math.h>
#include <iomanip.h>
#include "dataclient.h"
//**************************************************************************
int main(int argc, char *argv[])
{
char servername[100];
int port = 4096;
if (argc < 2)
      {
       cout << "Usage: client <server-name> [port-#]" << endl;
       exit(-1);
      }
strcpy(servername, argv[1]);
if (argc > 2)
      port = atoi(argv[2]);

DataClient *client = new DataClient;

// Connect to the server
if (client->Connect(servername, port) != CSL_SUCCESS)
      {
       cout << "Connection to " << servername << ":" << port << " failed!" << endl;
       delete client;
       exit(-1);
      }

double ****dyn4D;
// Get the dimensions of the 4D array and allocate memory for it
int n1 = client->getArrayDim("dyn4D", 1);
int n2 = client->getArrayDim("dyn4D", 2);
int n3 = client->getArrayDim("dyn4D", 3);
int n4 = client->getArrayDim("dyn4D", 4);
ALLOC4D(&dyn4D, n1, n2, n3, n4);

int numrequests = 1;
int interval = 500;      // in ms
// Request data for "dyn4D" array numrequests times with a wait 
// of "interval" ms between consecutive requests
for (int i = 0; i < numrequests; i++)
      {
       int oldtime = myTimer();
       client->RecvArray4D("dyn4D", dyn4D);
       int commtime = myTimer()-oldtime;
       if (numrequests > 1)
            {
              int delay = interval-commtime;
              if (delay > 0) mySleep(delay);
            }
      }

// Free the memory for thr 4D array
FREE4D(&dyn4D, n1, n2, n3, n4);

delete client;
}
/****************************************************************************/
\end{verbatim}
\end{scriptsize}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
\section{SMP vs. UP Performance Test}
\label{ch:smp}
\subsection{Server-side program}
\label{ch:smp_server}
\begin{scriptsize}
\begin{verbatim}
//**************************************************************************
#include <math.h>
#include <string.h>
#include <iomanip.h>
#include "alloc.h"
#include "misc.h"
#include "dataserver.h"
//**************************************************************************
// Define all data that has to be registered for being served as "global"
int run_flag = 0;
double ****dyn4D;
int n1, n2, n3, n4;
//**************************************************************************
// Register all the variables/data here along with their handles/keywords
REGISTER_DATA_BLOCK()
{
REGISTER_VARIABLE("run_flag", "rw", run_flag);
REGISTER_DYNAMIC_4D_ARRAY("dyn4D", "rw", dyn4D, n1, n2, n3, n4);
}
//**************************************************************************
int main(int argc, char *argv[])
{
int port = 4096;
if (argc > 1)
      port = atoi(argv[1]);

DataServer *Server = new DataServer;

n1 = 8;
n2 = 66;
n3 = 55;
n4 = 7;

// Allocate memory to the 4D array
ALLOC4D(&dyn4D, n1, n2, n3, n4);

// Fill the array with some values
for (int i = 0; i < n1; i++)
for (int j = 0; j < n2; j++)
for (int k = 0; k < n3; k++)
for (int l = 0; l < n4; l++)
      dyn4D[i][j][k][l] = (i+1)*100+(j+1)*10+(k+1)*1+(l+1)/10.0;

// Start the server
while (Server->Start(port) != POSSE_SUCCESS) { }

int count = 0;
while (!run_flag) mySleep(1000); // Sleep while run_flag is false

int start_time = myTimer();
while (run_flag)
      {
       ++count;
       for (int i = 0; i < n1; i++)
       for (int j = 0; j < n2; j++)
       for (int k = 0; k < n3; k++)
       for (int l = 0; l < n4; l++)
            dyn4D[i][j][k][l] = sin(dyn4D[i][j][k][l]*1.0)*
                              (i+1)*100+(j+1)*10+(k+1)*1+(l+1)/10.0;
      }

// Stop the server
Server->Stop();

double bytes_sent = Server->BytesSent();
delete Server;
int uptime = myTimer()-start_time;      // in ms

cout << "Number of computations = " << count << endl;
cout << "Uptime = " << uptime << " ms" << endl;
cout << "Effective network bandwidth = " << setprecision(4) 
      << 8.0*bytes_sent/(1000.0*uptime) << " Mbps." << endl;

FREE4D(&dyn4D, n1, n2, n3, n4);
}
/****************************************************************************/
\end{verbatim}
\end{scriptsize}
\subsection{Client-side script}
\label{ch:smp_client}
\begin{scriptsize}
\begin{verbatim}
//**************************************************************************
#!/bin/sh
if [ $# != 2 ]
then
        name=`basename $0 .base`
        echo Usage: ${name} \<server-name\> \<number-of-simultaneous-clients\>
      exit
fi
server=$1
n=$2

# Start the computation
printf "run_flag = 1 \n quit \n" | key_client ${server}

# Spawn "n" client requests simultaneously
while test $n -gt 0; do
      n=`echo $n | awk '{print $1-1}'`
      ./client ${server} &
done

# Wait till all client requests are completed
flag=1
while test $flag -gt 0; do
      flag=`ps auwx | grep client | grep -v grep | wc -l`
done

# Stop the server
printf "run_flag = 0 \n quit \n" | key_client ${server}
\end{verbatim}
\end{scriptsize}
