<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=iso-8859-1"></HEAD>
<BODY><PRE>#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;malloc.h&gt;
#include &lt;ctype.h&gt;
#include &lt;string.h&gt;
#include "timers.c"
#include "pvm3.h"

#define HostNode 704
#define NodeHost 1943
#define NodeName "queen-node"
#define HostName "queen-host"

long int Nunique = 0,
         Ntotal  = 0;

int Nnodes, tids[32];;

float *Calc, Lapsed = 0;

void StartNodes()
{
   int MyNum, Idx, Instance, Status;
   int Bytes, MsgType, NodeNum;
   int bufid;

   MyNum = pvm_mytid();
   Idx = pvm_spawn (NodeName, NULL, 0, "", Nnodes, tids);
   if (Idx &lt; Nnodes)
   {
      puts ("\nFailed to initiate all instances.  Aborting . . .");
      pvm_exit();
      exit (1);
   }
 
   for (Idx = 0; Idx &lt; Nnodes; Idx++)
   {
      bufid = pvm_recv (tids[Idx], NodeHost-1);
      pvm_upkint (&amp;Instance, 1, 1);
      pvm_bufinfo (bufid, &amp;Bytes, &amp;MsgType, &amp;NodeNum);
/*    For debugging:  should have tids[Idx] == Instance == NodeNum.  */
   }
}

void Launch (Board, Size, Node)
int Board[], Size, Node;
{
   pvm_initsend (PvmDataRaw);
   pvm_pkint (&amp;Size, 1, 1);
   pvm_pkint (Board, Size, 1);
   pvm_send (tids[Node], HostNode);
}

void Scuttle ()
{
   int Zero = 0;

   pvm_initsend(PvmDataRaw);
   pvm_pkint (&amp;Zero, 1, 1);
   pvm_mcast (tids, Nnodes, HostNode);
   pvm_exit();
}

int Finished()
{
   int   Node;
   long  Count;
   int   bufid;
   int   Bytes, MsgType;
   float JobTime;

   bufid = pvm_recv (-1, NodeHost);
   pvm_bufinfo (bufid, &amp;Bytes, &amp;MsgType, &amp;Node);
   Node = LinSearch (Node, tids, Nnodes);
   pvm_upklong (&amp;Count, 1, 1);
   Nunique += Count;
   pvm_upklong (&amp;Count, 1, 1);
   Ntotal  += Count;
   pvm_upkfloat (&amp;JobTime, 1, 1);
   Calc[Node] += JobTime;
   return Node;
}

int LinSearch (int Item, int X[], int N)
{
   int Idx;

   for (Idx = N-1; Idx &gt;= 0; Idx--)
      if (Item == X[Idx]) break;
   return Idx;
}

void FarmOut (Board, Size)
int Board[], Size;
{
   int
   Active = 0,    /* Number of node processes active        */
   NextUp = 0,    /* Column position for row-0 queen        */
   Node = 0,      /* Node process receiving a configuration */
   Lim = (Size+1)/2; /* We only need do the left half       */


   while (1)
   {
      int Temp;

      while ( NextUp &lt; Lim &amp;&amp; Active &lt; Nnodes )
      {
         if ( NextUp &gt; 0)
         {
            Temp = Board[0];
            Board[0] = Board[NextUp];
            Board[NextUp] = Temp;
         }
      /*    Launch sends the problem to the indicated Node     */
         Launch (Board, Size, Node);
         Node++ ; NextUp++ ; Active++ ;
      }
      if ( Active == 0 ) break;
   /* Finished() processes one node's returned information     */
      Node = Finished();  /* So Node is ready for Launch    */
      Active--; /* if NextUp &lt; Lim, while loop launches one */
   }
   Scuttle();
}

main(argc, argv)
int   argc;
char *argv[];
{
   int  *Board, *Trial, Idx, Lim, Size;
   FILE *fptr;
   float Clock, CPUscr, ClockScr;
   float CPUtot;

   if (argc &lt; 2)
   {
      fputs ("Size:  ", stdout);
      scanf ("%d", &amp;Size);
   }
   else
   {
      Size = atoi(argv[1]);
   }
   if (argc &lt; 3)
   {
      fputs ("Number of node processes:  ", stdout);
      scanf ("%d", &amp;Nnodes);
   }
   else
   {
      Nnodes = atoi(argv[2]);
   }
   if (Nnodes &lt; 1)
   {
      puts ("Need at least 1; setting No. nodes to 1");
      Nnodes = 1;
   }
   StartNodes();

   Board = (int *) calloc (Size, sizeof *Board);
   Calc  = (float *) calloc (Nnodes, sizeof *Calc);
/* Initial permutation generated. */
   for (Idx = 0; Idx &lt; Size; Idx++)
      Board[Idx] = Idx;

   cputime(&amp;CPUscr);                 /* Zero the counter */
   ClockTime(&amp;ClockScr);
   FarmOut (Board, Size);
   Lapsed = CPUtot = cputime(&amp;CPUscr);
   Clock = ClockTime(&amp;ClockScr);

   for (Idx = 0; Idx &lt; Nnodes; Idx++)
      CPUtot += Calc[Idx];

   printf ("%3d ==&gt; %10ld  %10ld  %10.4f  %10.4f\n",
           Size, Nunique, Ntotal, CPUtot, Clock);

   fptr = fopen("Nqueens.out", "a");
   fprintf (fptr, "%3d ==&gt; %10ld  %10ld  %10.4f  %10.4f",
            Size, Nunique, Ntotal, CPUtot, Clock);

   fprintf (fptr, " %8.4f", Lapsed);
   for (Idx = 0; Idx &lt; Nnodes; Idx++)
      fprintf (fptr, " %8.4f", Calc[Idx]);
   
   fputc ('\n', fptr);
   fclose (fptr);

   return 0;
}
</PRE></BODY></HTML>
