Newsgroups: comp.parallel.pvm
From: mal@aurora.nscee.edu (Lixing Ma)
Subject: need help
Organization: UNLV National Supercomputing Center for Energy and the Environment
Date: 15 Aug 1995 00:23:33 -0700
Message-ID: <40pi1l$lgu@aurora.nscee.edu>

Hi, I have a trouble now. It would be greatly appreciated if somebody could help me to figure out what is wrong with the program.  I input the One-dimensional Heat Transfer Equation program in the PVM book, but it always has the error informatin coming when I running it, I do not know why. the Error message is:



nye % heat
libpvm [t40002]: pvm_send(): Bad parameter
libpvm [t40002]: pvm_send(): Bad parameter
libpvm [t40002]: pvm_send(): Bad parameter
libpvm [t40002]: pvm_send(): Bad parameter
libpvm [t40002]: pvm_send(): Bad parameter


the pvm configration is pvm> conf
3 hosts, 1 data format
                    HOST     DTID     ARCH   SPEED
                     nye    40000 SUN4SOL2    1000
                  aurora    80000     CNVX    1000
                  saturn    c0000     SGI5    1000

Could you plese give me some clue. Thanks again.




Below are source files:

$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
/*
heat.c

  Use PVM to solve a simple heat diffusion differential equation.
  using 1 master program and 5 slaves.

  The master program sets up the data, communicates it to the slaves
  and waits for the results to be sents from the slaves.
  produces xgraph ready files of the results.

*/

#include "pvm3.h"
#include <stdio.h>
#include <math.h>
#include <time.h>
#define SLAVENAME "heatslv"
#define NPROC 5
#define TIMESTEP 100
#define PLOTINC 10
#define SIZE 1000

int num_data = SIZE/NPROC;

main()
{   int mytid, task_ids[NPROC], i, j;
    int left, right, k, l;
    int step = TIMESTEP;
    int info;

    double init[SIZE], solution[TIMESTEP][SIZE];
    double result[TIMESTEP*SIZE/NPROC], deltax2;
    FILE *filenum;
    char *filename[4][7];
    double deltat[4];
    time_t t0;
    int etime[4];

    filename[0][0] = "graph1";
    filename[1][0] = "graph2";
    filename[2][0] = "graph3";
    filename[3][0] = "graph4";

    deltat[0] = 5.0e-1;
    deltat[1] = 5.0e-3;
    deltat[2] = 5.0e-6;
    deltat[3] = 5.0e-9;

 /* enroll in pvm */
    mytid = pvm_mytid();

 /* spawn the slave tasks */
    info = pvm_spawn(SLAVENAME,(char **)0,PvmTaskDefault,"",NPROC,task_ids);

 /* create the initial data set */
    for (i = 0; i< SIZE; i++)
        init[i] = sin(M_PI * ( (double)i / (double) (SIZE-1) ));
    init[0] = 0.0;
    init[SIZE-1] = 0.0;

 /* run the program 4 times for different values of delta t */
    for (l = 0; l < 4; l++) {
        deltax2 = (deltat[1]/pow(1.0/(double)SIZE,2.0));
        /* start timing for this run */
        time(&t0);
        etime[1] = t0;
 /* send the initial data to the slaves. */
 /* include neighbor info for exchanging boundary data */
        for (i=0; i < NPROC; i++) {
            pvm_initsend(PvmDataDefault);
            left = (i == 0) ? 0 : task_ids[i-1];
            pvm_pkint(&left, 1, 1);
            right = (i == (NPROC-1)) ? 0 : task_ids[i+1];
            pvm_pkint(&right, 1, 1);
            pvm_pkint(&step, 1, 1);
            pvm_pkdouble(&deltax2, 1, 1);
            pvm_pkint(&num_data, 1, 1);
            pvm_pkdouble(&init[num_data*i], num_data, 1);
            pvm_send(task_ids[i], 4);
            }

 /* wait for the results */
        for (i = 0; i < NPROC; i++) {
            pvm_recv(task_ids[i], 7);
            pvm_upkdouble(&result[0], num_data*TIMESTEP, 1);
 /* update the solution */
            for (j = 0; j < TIMESTEP; j++)
                for (k = 0; k < num_data; k++)
                    solution[j][num_data*i+k] = result[wh(j,k)];
            }

 /* stop timing */
        time(&t0);
        etime[1] = t0 - etime[1];

 /* produce the output */
        filenum = fopen(filename[1][0],"w");
        fprintf(filenum,"TitleText: Wire Heat over Delta Time: %e\n", deltat[1]);
        fprintf(filenum,"XUnitText: Distance\nYUnitText: Heat\n");
        for (i = 0; i < TIMESTEP; i = i + PLOTINC) {
            fprintf(filenum,"\"TIME index: %d\n",i);
            for (j = 0; j < SIZE; j++)
                fprintf(filenum,"%d %e\n",j, solution[i][j]);
            fprintf(filenum,"\n");
            }
        fclose (filenum);
    }

/* print the timing information */
   printf("program size: %d\n",SIZE);
   for (i = 0; i < 4; i++)
       printf("Time for run %d: %d sec\n",i,etime[i]);

/* kill the slave process */
   for (i = 0; i < NPROC; i++) pvm_kill(task_ids[i]);
   pvm_exit();
}

int wh(x, y)
int x, y;
{
    return(x*num_data+y);
}

$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
/*

heatslv.c

    The slaves receive the initial data from the host,
    exchange boundary information with neighbors,
    and calculate the heat change in the wire.
    This is done for a number of iterations, sent by the master.

*/

#include "pvm3.h"
#include <stdio.h>

int num_data;

main()
{
    int mytid, left, right, i, j, master;
    int timestep;

    double *init, *A;
    double leftdata, rightdata, delta, leftside, rightside;

/* enroll in pvm */
    mytid = pvm_mytid();
    master = pvm_parent();

/* receive my data from the master program */
   while(1) {
     pvm_recv(master, 4);
     pvm_upkint(&left, 1, 1);
     pvm_upkint(&right, 1, 1);
     pvm_upkint(&timestep, 1, 1);
     pvm_upkdouble(&delta, 1, 1);
     pvm_upkint(&num_data, 1, 1);
     init = (double *)malloc(num_data*sizeof(double));
     pvm_upkdouble(init, num_data, 1);

/* copy the initial data into my working array */

     A = (double *) malloc(num_data * timestep * sizeof(double));
     for (i = 0; i< num_data; i++) A[i] = init[i];

/* perform the calculation */

   for (i = 0; i < timestep-1; i++) {
     /* trade boundary info with my neighbors */
     /* send left, receive right    */
     if (left != 0) {
        pvm_initsend(PvmDataDefault);
        pvm_pkdouble(&A[wh(i,0)],1,1);
        pvm_send(left, 5);
        }
     if (right != 0) {
        pvm_recv(right, 5);
        pvm_upkdouble(&rightdata, 1, 1);
     /* send right, receive left */
        pvm_initsend(PvmDataDefault);
        pvm_pkdouble(&A[wh(i,num_data-1)],1,1);
        pvm_send(right,6);
        }
     if (left != 0) {
        pvm_recv(left, 6);
        pvm_upkdouble(&leftdata,1,1);
        }

/* do the calculatons for this iteration */

    for (j = 0; j < num_data; j++) {
        leftside = (j == 0) ? leftdata : A[wh(i,j-1)];
        rightside = (j == (num_data-1)) ? rightdata : A[wh(i,j+1)];
        if ((j==0)&&(left==0))
            A[wh(i+1,j)] = 0.0;
        else if ((j==(num_data-1))&&(right==0))
            A[wh(i=1,j)] = 0.0;
        else
            A[wh(i+1,j)]=
                A[wh(i,j)]+delta*(rightside-2*A[wh(i,j)]+leftside);
        }
    }

/* send the results back to the master program */

   pvm_initsend(PvmDataDefault);
   pvm_pkdouble(&A[0],num_data*timestep,1);
   pvm_send(master,7);
   }

/* just for good measure */
   pvm_exit();
}


int wh(x,y)
int x,y;
{
    return(x*num_data+y);
} 

$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$


