help-octave
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: How could octave use pvm library pvm_spawn ?


From: Riccardo Corradini
Subject: Re: How could octave use pvm library pvm_spawn ?
Date: Thu, 8 Mar 2007 11:26:31 +0100 (CET)


Hi all,
I am trying to use the strategy suggested by John for pvm_spawn ...

Te mex function works perfectly under octave2.9.9+ and is
#include "mex.h"
#include <pvm3.h>

/* [numt,tid]=pvm_spawn(task,argv,flag,where,ntask) */
void m2pvm_spawn(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]){
    char *task,**argv,*where;
    int flag,ntask,*tids,numt,i,buflen,nargv;
    mxArray *tmp;
    double *pr;

    buflen=mxGetNumberOfElements(prhs[0])+1;
    task=(char *)mxCalloc(buflen,sizeof(char));
    mxGetString(prhs[0],task,buflen);
#ifdef DEBUG
    mexPrintf("buflen:%d task:%s\n",buflen,task);
#endif

    nargv=mxGetNumberOfElements(prhs[1])+1;
    argv=(char **)mxCalloc(nargv,sizeof(char *));
    for (i=0;i<nargv-1;i++){
    tmp=mxGetCell(prhs[1],i);
    buflen=mxGetNumberOfElements(tmp)+1;
    argv[i]=(char *)mxCalloc(buflen,sizeof(char));
    mxGetString(tmp,argv[i],buflen);
    }
    argv[nargv-1]=NULL;
#ifdef DEBUG
    for (i=0;i<nargv;i++)
    mexPrintf("argv[%d]:%s\n",i,argv[i]);
#endif

    flag=mxGetScalar(prhs[2]);
#ifdef DEBUG
    mexPrintf("flag:%d\n",flag);
#endif

    buflen=mxGetNumberOfElements(prhs[3])+1;
    where=(char *)mxCalloc(buflen,sizeof(char));
    mxGetString(prhs[3],where,buflen);
#ifdef DEBUG
    mexPrintf("buflen:%d where:%s\n",buflen,where);
#endif

    ntask=mxGetScalar(prhs[4]);
#ifdef DEBUG
    mexPrintf("ntask:%d\n",ntask);
#endif

    tids=(int *)mxCalloc(ntask,sizeof(int));

    numt=pvm_spawn(task,argv,flag,where,ntask,tids);

    plhs[0]=mxCreateDoubleScalar(numt);
   
    plhs[1]=mxCreateDoubleMatrix(ntask,1,mxREAL);
    pr=mxGetPr(plhs[1]);
    for (i=0;i<ntask;i++){
    *pr=(double)tids[i];
    pr++;
    }
}


The pure octave c++ version doesn't work...


// mkoctfile -g -lpvm3 pvm_spawn.cc

/*

Copyright (C) 7 february , 2007
Riccardo Corradini
email:address@hidden

This file is not part of Octave.

Octave is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.

Octave is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with Octave; see the file COPYING.  If not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.

*/

#include <octave/oct.h>
#include <octave/Cell.h>
#include <pvm3.h>



DEFUN_DLD(pvm_spawn,args,, "This function emulates the C function of pvm3 library \n starts [ntask] copies of the \nexecutable named [task].  The tids are returned in a list.\n")
{
// Example
// [numt,tids(i)]=pvm_spawn('/usr/bin/xterm',{'-display',display,'-e','octave','-q',runcommand},1,host,1);


  octave_value_list retval;
  int nargin = args.length ();

  if (nargin != 5)
    {
      error ("expecting 5 input arguments");
      return retval;
    }


  charNDArray cNDtask= args(0).char_array_value();
  char *fptask = cNDtask.fortran_vec();

  if (error_state)
    {
      error ("expecting first argument to be a string");
      return retval;
    }

  Cell cargv (args(1).cell_value());
  if (error_state)
    {
      error ("expecting second argument to be a cell array");
      return retval;
    }

    char *argv[cargv.nelem()];
   for (octave_idx_type i = 0; i < cargv.nelem()-1; i++)
     {
       charNDArray tmp = cargv(i).char_array_value();
       argv[i] = tmp.fortran_vec();
      
     }
  argv[cargv.nelem()]=NULL;
  int flag = args(2).int_value();
  if (error_state)
    {
      error ("expecting third argument to be a scalar");
      return retval;
    }

  charNDArray where = args(3).char_array_value();
 char *fpwhere = where.fortran_vec();

  if (error_state)
    {
      error ("expecting fourth argument to be a string");
      return retval;
    }
   
  int ntasks = args(4).int_value();
  if (error_state)
    {
      error ("expecting fifth argument to be a scalar");
      return retval;
    }

// // OCTAVE_LOCAL_BUFFER( T , v , len) is a handy macro, defined in config.h. It creates a Standard Template Library vector v of type T, where T is double in this case, and length len. Its advantage is that a clean-up is effected, even if an exception is thrown outside of current scope, thus preventing "memory leakage".
//
   OCTAVE_LOCAL_BUFFER (int, tids, ntasks);
//
//


      int numt = pvm_spawn (fptask, argv,flag, fpwhere,ntasks,tids);
  retval(0) = numt;
  ColumnVector mtids(ntasks);
  for (int i = 0; i < ntasks; i++)
    mtids(i) = static_cast<int>(tids[i]);
  retval(1) = mtids;

  return retval;
}

If you use pvm fromm the console
pvm
and then quit you start the Parallel Virtual machine
So if you do for istance
on octave
    display=:0.0;
    c=rand(8);
    runcommand=['cd ',pwd,';',c]
   myhost='knoppix'
    pop= {'--noclose','-display',display,...
        '-e','octave','--persist',runcommand}
    [numt,tids(i)]=pvm_spawn('/usr/bin/konsole',pop,...
        1,myhost,1)
the mex version works while the other doesn't ... I have no errors even in the other but doesn't spawn .. I wonder why?
Are there any hints?
Cheers
Riccardo

"John W. Eaton" <address@hidden> ha scritto:
On 28-Feb-2007, Riccardo Corradini wrote:

| DEFUN_DLD(pvm_pkcharMAT,args,, "This function emulates the C function pvm_pkbyte of pvm3 library, but packs any char matrixes with any dimensions \n")
| {
|
|
|
| octave_value_list retval;
| double nargin = args.length ();
|
| if (nargin != 2)
| {
| error ("expecting 2 input arguments");
| return retval;
| }
|
| const charNDArray tarray = args(0).char_array_value();
| int nitem = tarray.capacity();
| char *p = const_cast( tarray.data() );

I dont' think you should be using const_cast here. Octave is not
designed for you to be modifying arguments passed to functions. If
you need to do that, you need to make a copy, and return the copy to
the caller. To do that, write

charNDArray tarray = args(0).char_array_value ();
char *p = tarray.fortran_vec ();

Or, if it is just that

| int info2 = pvm_pkbyte (p, nitem, stride);

has the wrong declaration for the first arg (char* instead of const
char*), and it really doesn't ever modify the contents of the vector,
then maybe you should fix the declaration of pvm_pkbyte?

| // Could I use an octave_local_buffer macro if so .. how?
| charNDArray oar (dv);
| if( (n != oar.capacity()) )
| {
| error ("errors with dims");
| return retval;
| }
|
| char *preal = const_cast( oar.data() );

Again, I dont' think you want a const_cast here. Use

char *preal = oar.fortran_vec ();

| int info1 = pvm_upkbyte (preal, n, stride);
| retval(0) = static_cast(info1);

It looks like the type of info1 is already an int, so why do you use a
cast here?

| return octave_value_list(retval);

The variable retval is already an octave_value_list, so you can just
write

return retval;

jwe


L'email della prossima generazione? Puoi averla con la nuova Yahoo! Mail
reply via email to

[Prev in Thread] Current Thread [Next in Thread]