Hi Søren, thanks for your quick reply. The code is general-purpose, but as I told you I would love to use it for econometrics. So the first step will be to install the following tarball from http://www.open-mpi.org/software/ompi/v1.3/downloads/openmpi-1.3.3.tar.bz2 possibly in a multi-core computer to run my simple examples and configure it for instance in the following way (/home/user is your $HOME) ./configure --enable-mpirun-prefix-by-default --enable-heterogeneous --prefix=/home/user/openmpi-1.3.3/ --enable-static
and modify .bashrc in your home OMPIBIN=`$ompi_info -path bindir -parsable | cut -d: -f3` OMPILIB=`$ompi_info -path libdir -parsable | cut -d: -f3` OMPISCD=`$ompi_info -path sysconfdir -parsable | cut -d:
-f3`
OSCBIN=~/oompi-1.0.4/bin
export PATH=$OMPIBIN:$PATH export PATH=$OSCBIN:$PATH export LD_LIBRARY_PATH=:$OMPILIB:$LD_LIBRARY_PATH
unset ompi_info OMPIBIN OMPILIB OMPISCD OSCBIN
After this type in a terminal mpiCC --showme In my case I will have something like
g++ -I/home/user/openmpi-1.3.3/include -pthread -L/home/user/openmpi-1.3.3/lib -lmpi_cxx -lmpi -lopen-rte -lopen-pal -ldl -Wl,--export-dynamic -lnsl -lutil -lm -ldl
This will be useful for mkoctfile
Now I will include the basic functions
// mkoctfile -I/home/corradin/openmpi-1.3.3/include -lpthread -L/home/corradin/openmpi-1.3.3/lib -lmpi_cxx -lmpi -lopen-rte -lopen-pal -ldl -lnsl -lutil -lm -ldl MPI_Init.cc /* ## Copyright (C) 2004-2007 Javier Fernández Baldomero, Mancia Anguita López ## ## This
program is free software ## ---------------------------------------------------- ## Author: Javier Fernández Baldomero <jfernand@...>, Mancia Anguita López ## Keywords: parallel MPI ## tested on octave 3.2.3 by Riccardo Corradini ## ---------------------------------------------------- */ #define NAME MPI_Init /* * ---------------------------------------------------- * Initialize the MPI execution environment * info = MPI_Init [ ( 'arg' [, 'arg']... ) ] * ---------------------------------------------------- */ #include "mpi.h" // mpi.h, oct.h #include <octave/oct.h>
DEFUN_DLD(NAME, args, nargout, "MPI_Init Initialize the MPI execution environment\n\ \n\ info = MPI_Init [ ( 'arg' [, 'arg']... )
]\n\ \n\ arg (str) arguments to pass\n\ info(int) return code\n\ 0 MPI_SUCCESS No error\n\ 16 MPI_ERR_OTHER Attempt was made to call MPI_INIT a second time\n\ MPI_INIT may only be called once in a program\n\ \n\ \n\ SEE ALSO: MPI_Finalize, MPI_Initialized, MPI_Finalized\n\ misc\n\ \n\ ") { int nargin = args.length(); // Too flexible to use NARGCHK /* * info = MPI_Init [ ( 'arg' [,
'arg']... ) ] */ for (int i=0; i<nargin; i++){ if( ! args(i).is_string() ) { error("MPI_Init: args must be strings"); return octave_value (MPI_ERR_ARG); // error returns nothing } }
string_vector argvec = args.make_argv("MPI_Init"); char **argve= argvec.c_str_vec(); char **argv =&argve[1];
// printf("args: "); for (int i=0; i<nargin; i++) printf("%s ",argv[i]); // printf("\n");
int info = MPI_Init(&nargin, &argv); // int info = MPI::Init(); free(argve); return octave_value (info); }
#define NAME
MPI_Comm_rank /* * ---------------------------------------------------- * Determines the rank of the calling process in the communicator * [info rank] = MPI_Comm_rank (comm) * ---------------------------------------------------- */
#include <octave/oct.h> #include "mpi.h"
DEFUN_DLD(NAME, args, nargout, "MPI_Comm_rank Determines rank of calling process in communicator\n\ \n\ [info rank] = MPI_Comm_rank (comm)\n\ \n\ comm (int) communicator handle. MPI_COMM_NULL not valid\n\ rank (int) rank of the calling process in group of comm\n\ \n\ info (int) return code\n\ 0 MPI_SUCCESS No error\n\ 5 MPI_ERR_COMM Invalid communicator
(NULL?)\n\ 13 MPI_ERR_ARG Invalid argument (typically a NULL pointer?)\n\ \n\ SEE ALSO: MPI_Comm_size\n\ comms\n\ \n\ ")
{ octave_value_list results; int my_rank; int info = MPI_Comm_rank(MPI_COMM_WORLD,&my_rank); results(0) = info; results(1) = my_rank;
/* [info rank] = MPI_Comm_rank (comm) */ return results; }
#define NAME MPI_Comm_size /* * ---------------------------------------------------- * Determines the size of the calling process in the communicator * [info rank] = MPI_Comm_size (comm) *
---------------------------------------------------- */
#include <octave/oct.h> #include "mpi.h"
DEFUN_DLD(NAME, args, nargout, "MPI_Comm_size Determines rank of calling process in communicator\n\ \n\ [info rank] = MPI_Comm_size (comm)\n\ \n\ comm (int) communicator handle. MPI_COMM_NULL not valid\n\ size (int) size of the calling process in group of comm\n\ \n\ info (int) return code\n\ 0 MPI_SUCCESS No error\n\ 5 MPI_ERR_COMM Invalid communicator (NULL?)\n\ 13 MPI_ERR_ARG Invalid argument (typically a NULL pointer?)\n\ \n\ SEE ALSO: MPI_Comm_rank\n\
comms\n\ \n\ ")
{ octave_value_list results; int my_size; int info = MPI_Comm_size(MPI_COMM_WORLD,&my_size); results(0) = info; results(1) = my_size;
/* [info rank] = MPI_Comm_size (comm) */ return results; }
#define NAME MPI_Finalize /* * ---------------------------------------------------- * Terminates MPI execution environment * info = MPI_Finalize * ---------------------------------------------------- */ #include "mpi.h" #include <octave/oct.h>
DEFUN_DLD(NAME, args, nargout, "MPI_Finalize Terminates MPI execution environment\n\ \n\
info = MPI_Finalize\n\ \n\ info(int) return code\n\ 0 MPI_SUCCESS No error\n\ 17 MPI_ERR_INTERN This is fatal. Please send bug report to LAM\n\ 16 MPI_ERR_OTHER A different thread attempts to finalize MPI than\n\ the thread that initialized MPI\n\ \n\ SEE ALSO: MPI_Init, MPI_Initialized, MPI_Finalized\n\ misc\n\ \n\ ") {
int info = MPI_Finalize(); return octave_value(info); }
#define NAME MPI_Finalized /* * ---------------------------------------------------- * Indicates whether
MPI_Finalize has completed * [info flag] = MPI_Finalized * ---------------------------------------------------- */ #include "mpi.h" #include <octave/oct.h>
DEFUN_DLD(NAME, args, nargout, "MPI_Finalized Indicates whether MPI_Finalize has completed\n\ \n\ [info flag] = MPI_Finalized\n\ \n\ flag(int) 0 false\n\ 1 true\n\ \n\ info(int) return code\n\ 0 MPI_SUCCESS This function always returns MPI_SUCCESS\n\ \n\ SEE ALSO: MPI_Init, MPI_Finalize, MPI_Initialized\n\ misc\n\ \n\ ") { octave_value_list results; int flag;
// Too flexible to use NARGCHK
int info = MPI_Finalized(&flag); results(0) = info; results(1) = flag; return results;
/* [info flag] = MPI_Finalized */ }
// mkoctfile -lpthread -L/home/user/openmpi-1.3.3/lib -lmpi_cxx -lmpi -lopen-rte -lopen-pal -ldl -lnsl -lutil -lm -ldl MPI_Initialized.cc
#define NAME MPI_Initialized /* * ---------------------------------------------------- * Indicates whether MPI_Init has been called * [info flag] = MPI_Initialized * ---------------------------------------------------- */ #include "mpi.h" #include <octave/oct.h>
DEFUN_DLD(NAME, args, nargout, "MPI_Initialized
Indicates whether MPI_Init has been called\n\ \n\ [info flag] = MPI_Initialized\n\ \n\ flag(int) 0 false\n\ 1 true\n\ \n\ info(int) return code\n\ 0 MPI_SUCCESS This function always returns MPI_SUCCESS\n\ \n\ SEE ALSO: MPI_Init, MPI_Finalize,\n\ misc\n\ \n\ ") { octave_value_list results; int flag; // Too flexible to use NARGCHK
int info = MPI_Initialized(&flag); results(0) = info; results(1) = flag; return results; }
The following two functions MPI_Send and MPI_Recv are my real simple original
contribution (I will report some test script as well)
MPI_Send.cc
// mkoctfile -lpthread -I/home/user/openmpi-1.3.3/include/ -L/home/user/openmpi-1.3.3/lib -lmpi_cxx -lmpi -lopen-rte -lopen-pal -ldl -lnsl -lutil -lm -ldl MPI_Send.cc
// mkoctfile -lpthread -I/home/corradin/openmpi-1.3.3/include/ -L/home/corradin/openmpi-1.3.3/lib -lmpi_cxx -lmpi -lopen-rte -lopen-pal -ldl -lnsl -lutil -lm -ldl MPI_Send.cc
/* * sends most Octave datatypes into contiguous memory * using derived datatypes * info = MPI_Send(var,rank) */ #include "mpi.h" #include <octave/oct.h> #include <ov-cell.h> // avoid errmsg "cell -- incomplete datatype" #include <oct-map.h> // avoid errmsg "Oct.map -- invalid use undef type"
enum ov_t_id {
ov_unknown=0, ov_cell,
// 1 ov_scalar, // 2 ov_complex_scalar, // 3 ov_matrix, // 4 ov_diagonal_matrix, // 5 ov_complex_matrix, // 6 ov_complex_diagonal_matrix, // 7 ov_range, // 8 ov_bool, // 9 ov_bool_matrix, // 10 ov_char_matrix, // 11 ov_string, // 12 ov_sq_string, // 13 ov_int8_scalar,
// 14 ov_int16_scalar, // 15 ov_int32_scalar, // 16 ov_int64_scalar, // 17 ov_uint8_scalar, // 18 ov_uint16_scalar, // 19 ov_uint32_scalar, // 20 ov_uint64_scalar, // 21 ov_int8_matrix, // 22 ov_int16_matrix, // 23 ov_int32_matrix, // 24 ov_int64_matrix, // 25 ov_uint8_matrix, // 26 ov_uint16_matrix, // 27 ov_uint32_matrix, //
28 ov_uint64_matrix, // 29 ov_sparse_bool_matrix, // 30 ov_sparse_matrix, // 31 ov_sparse_complex_matrix, // 32 ov_struct, // 33 ov_class, // 34 ov_list, // 35 ov_cs_list, // 36 ov_magic_colon, // 37 ov_built_in_function, // 38 ov_user_defined_function, // 39 ov_dynamically_linked_function, // 40 ov_function_handle, // 41 ov_inline_function, //
42 ov_float_scalar, // 43 ov_float_complex_scalar, // 44 ov_float_matrix, // 45 ov_float_diagonal_matrix, // 46 ov_float_complex_matrix, // 47 ov_float_complex_diagonal_matrix, // 48 ov_permutation_matrix, // 49 ov_null_matrix, // 50 ov_null_string, // 51 ov_null_sq_string, // 52 };
/*----------------------------------*/ /* forward declaration */
int send_class( octave_value ov, ColumnVector rankrec, int mytag);
/* along the datatype */ /*----------------------------------*/ /* to send any octave_value */ int send_scalar( double d, ColumnVector rankrec, int mytag){ /* directly MPI_Send it, */ /*-----------------------------*/ /* it's just a double value */ int info; int t_id = ov_scalar; int tanktag[2]; tanktag[0] = mytag; tanktag[1] = mytag+1; for (octave_idx_type i = 0; i< rankrec.nelem(); i++) { info = MPI_Send(&t_id, 1, MPI_INT, rankrec(i), tanktag[0], MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; info = MPI_Send((&d), 1,MPI_DOUBLE, rankrec(i), tanktag[1], MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return
info; } return(MPI_SUCCESS); }
int send_float_scalar( float d, ColumnVector rankrec, int mytag){ /* directly MPI_Send it, */ /*-----------------------------*/ /* it's just a double value */ int info; int t_id = ov_float_scalar; int tanktag[2]; tanktag[0] = mytag; tanktag[1] = mytag+1; for (octave_idx_type i = 0; i< rankrec.nelem(); i++) { info = MPI_Send(&t_id, 1, MPI_INT, rankrec(i), tanktag[0], MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; info = MPI_Send((&d), 1,MPI_FLOAT, rankrec(i), tanktag[1], MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; }
return(MPI_SUCCESS); }
int send_i8( octave_int8 d, ColumnVector rankrec, int mytag){ /* directly MPI_Send it, */ /*-----------------------------*/ /* it's just a double value */ int info; int t_id = ov_int8_scalar; int tanktag[2]; tanktag[0] = mytag; tanktag[1] = mytag+1; for (octave_idx_type i = 0; i< rankrec.nelem(); i++) { info = MPI_Send(&t_id, 1, MPI_INT, rankrec(i), tanktag[0], MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; info = MPI_Send((&d), 1,MPI_BYTE, rankrec(i), tanktag[1], MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; } return(MPI_SUCCESS); }
int send_i16( octave_int16 d,
ColumnVector rankrec, int mytag){ /* directly MPI_Send it, */ /*-----------------------------*/ /* it's just a double value */ int info; int t_id = ov_int16_scalar; OCTAVE_LOCAL_BUFFER(int,tanktag,2); // int tanktag[2]; tanktag[0] = mytag; tanktag[1] = mytag+1; for (octave_idx_type i = 0; i< rankrec.nelem(); i++) { info = MPI_Send(&t_id, 1, MPI_INT, rankrec(i), tanktag[0], MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; info = MPI_Send((&d), 1,MPI_SHORT, rankrec(i), tanktag[1], MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; } return(MPI_SUCCESS); }
int send_i32( octave_int32 d,
ColumnVector rankrec, int mytag){ /* directly MPI_Send it, */ /*-----------------------------*/ /* it's just a double value */ int info; int t_id = ov_int32_scalar; OCTAVE_LOCAL_BUFFER(int,tanktag,2); // int tanktag[2]; tanktag[0] = mytag; tanktag[1] = mytag+1; for (octave_idx_type i = 0; i< rankrec.nelem(); i++) { info = MPI_Send(&t_id, 1, MPI_INT, rankrec(i), tanktag[0], MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; info = MPI_Send((&d), 1,MPI_INT, rankrec(i), tanktag[1], MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; } return(MPI_SUCCESS); }
int send_i64( octave_int64 d,
ColumnVector rankrec, int mytag){ /* directly MPI_Send it, */ /*-----------------------------*/ /* it's just a value */ int info; int t_id = ov_int64_scalar; OCTAVE_LOCAL_BUFFER(int,tanktag,2); // int tanktag[2]; tanktag[0] = mytag; tanktag[1] = mytag+1; for (octave_idx_type i = 0; i< rankrec.nelem(); i++) { info = MPI_Send(&t_id, 1, MPI_INT, rankrec(i), tanktag[0], MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; info = MPI_Send((&d), 1,MPI_LONG_LONG, rankrec(i), tanktag[1], MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; } return(MPI_SUCCESS); }
int send_ui64( octave_uint64 d,
ColumnVector rankrec, int mytag){ /* directly MPI_Send it, */ /*-----------------------------*/ /* it's just a value */ int info; int t_id = ov_uint64_scalar; OCTAVE_LOCAL_BUFFER(int,tanktag,2); // int tanktag[2]; tanktag[0] = mytag; tanktag[1] = mytag+1; for (octave_idx_type i = 0; i< rankrec.nelem(); i++) { info = MPI_Send(&t_id, 1, MPI_INT, rankrec(i), tanktag[0], MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; info = MPI_Send((&d), 1,MPI_UNSIGNED_LONG_LONG, rankrec(i), tanktag[1], MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; } return(MPI_SUCCESS); }
int send_ui32(
octave_uint32 d, ColumnVector rankrec, int mytag){ /* directly MPI_Send it, */ /*-----------------------------*/ /* it's just a value */ int info; int t_id = ov_uint32_scalar; OCTAVE_LOCAL_BUFFER(int,tanktag,2); // int tanktag[2]; tanktag[0] = mytag; tanktag[1] = mytag+1; for (octave_idx_type i = 0; i< rankrec.nelem(); i++) { info = MPI_Send(&t_id, 1, MPI_INT, rankrec(i), tanktag[0], MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; info = MPI_Send((&d), 1,MPI_UNSIGNED, rankrec(i), tanktag[1], MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; } return(MPI_SUCCESS); }
int send_ui16(
octave_uint16 d, ColumnVector rankrec, int mytag){ /* directly MPI_Send it, */ /*-----------------------------*/ /* it's just a value */ int info; int t_id = ov_uint16_scalar; OCTAVE_LOCAL_BUFFER(int,tanktag,2); // int tanktag[2]; tanktag[0] = mytag; tanktag[1] = mytag+1; for (octave_idx_type i = 0; i< rankrec.nelem(); i++) { info = MPI_Send(&t_id, 1, MPI_INT, rankrec(i), tanktag[0], MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; info = MPI_Send((&d), 1,MPI_UNSIGNED_SHORT, rankrec(i), tanktag[1], MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; } return(MPI_SUCCESS); }
int
send_ui8( octave_uint8 d, ColumnVector rankrec, int mytag){ /* directly MPI_Send it, */ /*-----------------------------*/ /* it's just a value */ int info; int t_id = ov_uint8_scalar; OCTAVE_LOCAL_BUFFER(int,tanktag,2); // int tanktag[2]; tanktag[0] = mytag; tanktag[1] = mytag+1; for (octave_idx_type i = 0; i< rankrec.nelem(); i++) { info = MPI_Send(&t_id, 1, MPI_INT, rankrec(i), tanktag[0], MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; info = MPI_Send((&d), 1,MPI_UNSIGNED_CHAR, rankrec(i), tanktag[1], MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; } return(MPI_SUCCESS); }
int
send_bool( int d, ColumnVector rankrec, int mytag){ /* directly MPI_Send it, */ /*-----------------------------*/ /* it's just a value */ int info; int t_id = ov_bool; int tanktag[2]; tanktag[0] = mytag; tanktag[1] = mytag+1; for (octave_idx_type i = 0; i< rankrec.nelem(); i++) { info = MPI_Send(&t_id, 1, MPI_INT, rankrec(i), tanktag[0], MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; info = MPI_Send((&d), 1,MPI_DOUBLE, rankrec(i), tanktag[1], MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; } return(MPI_SUCCESS); }
int send_complex_scalar( Complex c, ColumnVector rankrec, int
mytag){ /* directly MPI_Send it, */ /*-----------------------------*/ /* it's just a value */ int info; int t_id = ov_complex_scalar; OCTAVE_LOCAL_BUFFER(int,tanktag,2); tanktag[0] = mytag; tanktag[1] = mytag+1; OCTAVE_LOCAL_BUFFER(double,d,2); d[0] = real(c); d[1] = imag(c); for (octave_idx_type i = 0; i< rankrec.nelem(); i++) { info = MPI_Send(&t_id, 1, MPI_INT, rankrec(i), tanktag[0], MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; info = MPI_Send((&d), 2,MPI_DOUBLE, rankrec(i), tanktag[1], MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; } return(MPI_SUCCESS); }
int
send_float_complex_scalar( std::complex<float> c, ColumnVector rankrec, int mytag){ /* directly MPI_Send it, */ /*-----------------------------*/ /* it's just a double value */ int info; int t_id = ov_float_complex_scalar; OCTAVE_LOCAL_BUFFER(int,tanktag,2); tanktag[0] = mytag; tanktag[1] = mytag+1; OCTAVE_LOCAL_BUFFER(float,d,2); d[0] = real(c); d[1] = imag(c); for (octave_idx_type i = 0; i< rankrec.nelem(); i++) { info = MPI_Send(&t_id, 1, MPI_INT, rankrec(i), tanktag[0], MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; info = MPI_Send((&d), 2,MPI_FLOAT, rankrec(i), tanktag[1], MPI_COMM_WORLD); if
(info !=MPI_SUCCESS) return info; } return(MPI_SUCCESS); }
int send_string(std::string oi8,ColumnVector rankrec, int mytag){ /* directly pvm_pkbyte it, */ /*----------------------------------*/ /* just a char value */ int info; int nitem = oi8.length(); int tanktag[3]; tanktag[0] = mytag; tanktag[1] = mytag+1; tanktag[2] = mytag+2; // OCTAVE_LOCAL_BUFFER(char,i8,nitem+1); char i8[nitem+1]; strcpy(i8, oi8.c_str()); int t_id = ov_string;
// Here we declare a contiguous derived datatype // Create a contiguous datatype for the fortranvec MPI_Datatype fortvec; MPI_Type_contiguous(nitem,MPI_CHAR, &fortvec); MPI_Type_commit(&fortvec);
for (octave_idx_type i = 0; i<
rankrec.nelem(); i++) { printf("Sending block to %i \n",rankrec(i)); printf("Sending block with tag to %i \n",mytag); info = MPI_Send(&t_id, 1, MPI_INT, rankrec(i), mytag, MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; printf("Sending type of object %i \n",t_id); info = MPI_Send(&nitem, 1, MPI_INT, rankrec(i), tanktag[1], MPI_COMM_WORLD); printf("Sending nitem %i \n",nitem); if (info !=MPI_SUCCESS) return info; info =
MPI_Send(&i8,1,fortvec,rankrec(i),tanktag[2],MPI_COMM_WORLD); printf("Info for sending fortvec %i \n",info); if (info !=MPI_SUCCESS) return info; }
return(info);
} /*-----------------------------------*/ /* to pack a struct */ int send_struct(Octave_map map,ColumnVector rankrec, int mytag){ /* we store nkeys, */
int n = map.nfields(); int info; int t_id; int tanktag[3]; tanktag[0] = mytag; tanktag[1] = mytag+1; tanktag[2] = mytag+2; int newtag = mytag+3;
// Create 3 contiguous derived datatype // one for dim_vector struc_dims
dim_vector struc_dims = map.dims(); // struct array dimensions (ND) dim_vector
conts_dims; // each key stores ND field-values
int nd = map.ndims();
// Declare here the octave_local_buffers OCTAVE_LOCAL_BUFFER(int,dimV,nd); for (octave_idx_type i=0; i<nd; i++) { dimV[i] = struc_dims(i) ; }
// Now create the contiguos derived datatype MPI_Datatype dimvec; MPI_Type_contiguous(nd,MPI_INT, &dimvec); MPI_Type_commit(&dimvec);
// Create a derived datatype containing three integer; // n nd maxlenght typedef struct { int sn, snd,smlenght; } Particle;
Particle part; MPI_Datatype particletype, oldtypes[1]; int blockcounts[1];
MPI_Aint offsets[1]; // MPI_Status
/* Setup description of 3 MPI_INT fields */ offsets[0] =0; oldtypes[0] = MPI_INT; blockcounts[0] = 3; /* Now define structured type and commit
*/ MPI_Type_struct(1,blockcounts, offsets, oldtypes, &particletype); MPI_Type_commit(&particletype);
/* Initialize the particle */ part.sn = n; part.snd = nd;
octave_idx_type maxlen;
Octave_map::const_iterator p = map.begin(); // iterate through keys(fnames) for (octave_idx_type i=0; p!=map.end(); p++, i++){ std::string key = map.key (p); // field name
int len = key.length()+1; /* fieldname len, works for len==0 */ if (len> maxlen) maxlen = len; Cell conts = map.contents(p); conts_dims = conts.dims(); /* each elemt should have same ND
*/ if (struc_dims != conts_dims){ printf("MPI_Send: inconsistent map dims\n"); return(MPI_ERR_UNKNOWN); } if (n != map.nfields()){ printf("MPI_Send: inconsistent map length\n");return(MPI_ERR_UNKNOWN); } }
part.smlenght = maxlen;
MPI_Datatype fortvec; MPI_Type_contiguous(maxlen,MPI_CHAR, &fortvec); MPI_Type_commit(&fortvec);
// Now we start the big loop for (octave_idx_type i = 0; i< rankrec.nelem(); i++) { info = MPI_Send(&t_id, 1, MPI_INT, rankrec(i), tanktag[0], MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; // Send the particle struct derived datatype info =
MPI_Send(&part,1,particletype,rankrec(i),tanktag[1],MPI_COMM_WORLD); // Dimension vector info = MPI_Send(dimV, 1, dimvec, rankrec(i), tanktag[2], MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info;
} Octave_map::const_iterator b = map.begin(); // iterate through keys(fnames) for (octave_idx_type i=0; b!=map.end(); b++, i++){ Cell conts = map.contents(p); // Cell w/ND contents newtag = newtag + conts.capacity(); int info =send_class(conts,rankrec,newtag); if (info !=MPI_SUCCESS) return info;
}
return(MPI_SUCCESS); }
int send_cell(Cell cell, ColumnVector rankrec, int mytag){ /* we first store nelems and then */ /*----------------------------*/ /* recursively the elements themselves */
// Lists of items to send // type_id to identify octave_value // n for the cell capacity // nd for number of dimensions // dimvec derived datatype // item of cell int t_id = ov_cell; int n = cell.capacity(); int info; int tanktag[5]; tanktag[0] = mytag; tanktag[1] = mytag+1; tanktag[2] = mytag+2; tanktag[3] = mytag+3; tanktag[4] = mytag+4; int newtag = tanktag[4]; dim_vector vdim = cell. dims(); int nd = cell.ndims();
// Declare here the octave_local_buffers OCTAVE_LOCAL_BUFFER(int,dimV,nd); for
(octave_idx_type i=0; i<nd; i++) { dimV[i] = vdim(i) ; }
// Now create the contiguos derived datatype MPI_Datatype dimvec; MPI_Type_contiguous(nd,MPI_INT, &dimvec); MPI_Type_commit(&dimvec);
// Now start the big loop
for (octave_idx_type i = 0; i< rankrec.nelem(); i++) { info = MPI_Send(&t_id, 1, MPI_INT, rankrec(i), tanktag[0], MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; // send cell capacity info = MPI_Send(&n, 1, MPI_INT, rankrec(i), tanktag[1], MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; info = MPI_Send(&nd, 1, MPI_INT, rankrec(i), tanktag[2],
MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; // send the dim vector info = MPI_Send(dimV,1,dimvec,rankrec(i),tanktag[3],MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; }
// Now focus on every single octave_value for (octave_idx_type i=0; i<n; i++){ octave_value ov = cell.data()[i]; newtag = newtag +ov.capacity(); info=send_class(ov,rankrec,newtag); if (info !=MPI_SUCCESS) return info; }
return(MPI_SUCCESS);
}
int send_sp_mat(SparseMatrix m ,ColumnVector rankrec, int mytag
){
int info; int t_id = ov_sparse_matrix; int tanktag[5]; tanktag[0] = mytag; tanktag[1] = mytag+1; tanktag[2] = mytag+2; tanktag[3] = mytag+3; tanktag[4] = mytag+4; // octave_idx_type nr = m.rows (); // octave_idx_type nc = m.cols (); // octave_idx_type nz = m.nnz ();
OCTAVE_LOCAL_BUFFER(int,s,3); s[0]= m.rows(); s[1]= m.cols(); s[2]= m.capacity();// int n = m.capacity();
// Create a contiguous derived datatype// OCTAVE_LOCAL_BUFFER( double ,data,n); MPI_Datatype sintsparse;// OCTAVE_LOCAL_BUFFER( int ,ridx,n); MPI_Type_contiguous(3,MPI_INT, &sintsparse); MPI_Type_commit(&sintsparse);
MPI_Datatype rowindex; MPI_Type_contiguous(m.capacity(),MPI_INT, &rowindex); MPI_Type_commit(&rowindex);
MPI_Datatype columnindex; MPI_Type_contiguous(m.cols()+1,MPI_INT, &columnindex); MPI_Type_commit(&columnindex);
MPI_Datatype
numnnz; MPI_Type_contiguous(m.capacity(),MPI_DOUBLE, &numnnz); MPI_Type_commit(&numnnz);
OCTAVE_LOCAL_BUFFER( int ,sridx,m.capacity()); OCTAVE_LOCAL_BUFFER( int ,scidx,m.cols()+1); OCTAVE_LOCAL_BUFFER( double ,sdata,m.capacity()); // Fill them with their respective value for (octave_idx_type ix = 0; ix < m.capacity(); ix++) { sdata[ix]=m.data(ix); // printf("sending %d \n",sdata[ix]); sridx[ix]= m.ridx(ix); // printf("sending %i \n",sridx[ix]); } NDArray buf (dim_vector (m.capacity(), 1)); for (int ix = 0; ix < m.capacity(); ix++) { buf(ix)=m.data(ix); sdata[ix] = buf(ix); // printf("sending buffer %d
\n",sdata[ix]); } for (octave_idx_type ix = 0; ix < m.cols()+1; ix++) { scidx[ix]= m.cidx(ix); // printf("sending %i \n",scidx[ix]);
}
for (octave_idx_type i = 0; i< rankrec.nelem(); i++) { info = MPI_Send(&t_id, 1, MPI_INT, rankrec(i), tanktag[0], MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; // send the sintsparse vector named s info = MPI_Send(s, 1, sintsparse, rankrec(i), tanktag[1], MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; // send the vector with row indexes info =
MPI_Send(sridx,1,rowindex,rankrec(i),tanktag[2],MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; // send the vector with column indexes info = MPI_Send(scidx,1,columnindex,rankrec(i),tanktag[3],MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; // send the vector of non zero elements info = MPI_Send(sdata,1,numnnz,rankrec(i),tanktag[4],MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; }
return(info); }
int send_sp_bl_mat(SparseBoolMatrix m ,ColumnVector rankrec, int mytag ){
int info; int t_id = ov_sparse_matrix; int tanktag[5]; tanktag[0] = mytag; tanktag[1] = mytag+1; tanktag[2] = mytag+2; tanktag[3] = mytag+3; tanktag[4] = mytag+4; // octave_idx_type nr = m.rows (); // octave_idx_type nc =
m.cols (); // octave_idx_type nz = m.nnz ();
OCTAVE_LOCAL_BUFFER(int,s,3); s[0]= m.rows(); s[1]= m.cols(); s[2]= m.capacity();// int n = m.capacity();
// Create a contiguous derived datatype// OCTAVE_LOCAL_BUFFER( double ,data,n); MPI_Datatype sintsparse;// OCTAVE_LOCAL_BUFFER( int ,ridx,n); MPI_Type_contiguous(3,MPI_INT, &sintsparse); MPI_Type_commit(&sintsparse);
MPI_Datatype rowindex; MPI_Type_contiguous(m.capacity(),MPI_INT, &rowindex); MPI_Type_commit(&rowindex);
MPI_Datatype columnindex; MPI_Type_contiguous(m.cols()+1,MPI_INT, &columnindex); MPI_Type_commit(&columnindex);
MPI_Datatype numnnz; MPI_Type_contiguous(m.capacity(),MPI_INT, &numnnz); MPI_Type_commit(&numnnz);
OCTAVE_LOCAL_BUFFER( int ,sridx,m.capacity()); OCTAVE_LOCAL_BUFFER( int ,scidx,m.cols()+1); OCTAVE_LOCAL_BUFFER( int
,sdata,m.capacity()); // Fill them with their respective value for (octave_idx_type ix = 0; ix < m.capacity(); ix++) { sdata[ix]=m.data(ix); // printf("sending %d \n",sdata[ix]); sridx[ix]= m.ridx(ix); // printf("sending %i \n",sridx[ix]); } for (octave_idx_type ix = 0; ix < m.cols()+1; ix++) { scidx[ix]= m.cidx(ix); // printf("sending %i \n",scidx[ix]);
}
for (octave_idx_type i = 0; i< rankrec.nelem(); i++) { info = MPI_Send(&t_id, 1, MPI_INT, rankrec(i), tanktag[0], MPI_COMM_WORLD); if
(info !=MPI_SUCCESS) return info; // send the sintsparse vector named s info = MPI_Send(s, 1, sintsparse, rankrec(i), tanktag[1], MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; // send the vector with row indexes info = MPI_Send(sridx,1,rowindex,rankrec(i),tanktag[2],MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; // send the vector with column indexes info = MPI_Send(scidx,1,columnindex,rankrec(i),tanktag[3],MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; // send the vector of non zero elements info = MPI_Send(sdata,1,numnnz,rankrec(i),tanktag[4],MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info;
}
return(info); }
int send_sp_cx_mat(SparseComplexMatrix m ,ColumnVector rankrec, int mytag ){
int info; int t_id = ov_sparse_complex_matrix; OCTAVE_LOCAL_BUFFER(int,tanktag,6); // int tanktag[5]; tanktag[0] = mytag; tanktag[1] = mytag+1; tanktag[2] = mytag+2; tanktag[3] = mytag+3; tanktag[4] = mytag+4; tanktag[5] = mytag+5;
OCTAVE_LOCAL_BUFFER(int,s,3); s[0]= m.rows(); s[1]= m.cols(); s[2]= m.capacity();// int n = m.capacity();
// Create a contiguous derived datatype// OCTAVE_LOCAL_BUFFER( double ,data,n); MPI_Datatype sintsparse;// OCTAVE_LOCAL_BUFFER( int ,ridx,n); MPI_Type_contiguous(3,MPI_INT, &sintsparse); MPI_Type_commit(&sintsparse);
MPI_Datatype rowindex; MPI_Type_contiguous(m.capacity(),MPI_INT, &rowindex); MPI_Type_commit(&rowindex);
MPI_Datatype
columnindex; MPI_Type_contiguous(m.cols()+1,MPI_INT, &columnindex); MPI_Type_commit(&columnindex);
MPI_Datatype numnnz; MPI_Type_contiguous(m.capacity(),MPI_DOUBLE, &numnnz); MPI_Type_commit(&numnnz);
OCTAVE_LOCAL_BUFFER( int ,sridx,m.capacity()); OCTAVE_LOCAL_BUFFER( int ,scidx,m.cols()+1); OCTAVE_LOCAL_BUFFER( double ,rsdata,m.capacity()); OCTAVE_LOCAL_BUFFER( double ,isdata,m.capacity()); // Fill them with their respective value for (octave_idx_type ix = 0; ix < m.capacity(); ix++) { rsdata[ix]=real(m.data(ix)); isdata[ix]=imag(m.data(ix)); // printf("sending %d \n",sdata[ix]); sridx[ix]= m.ridx(ix); // printf("sending %i \n",sridx[ix]); } for (octave_idx_type ix =
0; ix < m.cols()+1; ix++) { scidx[ix]= m.cidx(ix); // printf("sending %i \n",scidx[ix]);
}
for (octave_idx_type i = 0; i< rankrec.nelem(); i++) { info = MPI_Send(&t_id, 1, MPI_INT, rankrec(i), tanktag[0], MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; // send the sintsparse vector named s info = MPI_Send(s, 1, sintsparse, rankrec(i), tanktag[1], MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; // send the vector with row indexes info = MPI_Send(sridx,1,rowindex,rankrec(i),tanktag[2],MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return
info; // send the vector with column indexes info = MPI_Send(scidx,1,columnindex,rankrec(i),tanktag[3],MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; // send the vector of non zero elements // real info = MPI_Send(rsdata,1,numnnz,rankrec(i),tanktag[4],MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; // img info = MPI_Send(isdata,1,numnnz,rankrec(i),tanktag[5],MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info;
}
return(info); }
int send_complex_matrix(ComplexNDArray myCNDA,ColumnVector rankrec, int mytag){ int info; int nitem = myCNDA.nelem(); dim_vector dv = myCNDA.dims();
OCTAVE_LOCAL_BUFFER(int,tanktag,6); // int tanktag[5]; tanktag[0] = mytag; tanktag[1]= tanktag[0]+1; tanktag[2]= tanktag[1]+1; tanktag[3]= tanktag[2]+1; tanktag[4]= tanktag[3]+1; tanktag[5]= tanktag[4]+1;
int nd = myCNDA.ndims (); int t_id = ov_complex_matrix; // Declare here the octave_local_buffers OCTAVE_LOCAL_BUFFER(int,dimV,nd); for (octave_idx_type i=0; i<nd; i++) { dimV[i] = dv(i) ; }
// Now create the contiguos derived datatype MPI_Datatype dimvec; MPI_Type_contiguous(nd,MPI_INT, &dimvec); MPI_Type_commit(&dimvec);
NDArray rarray = real(myCNDA); NDArray imarray = imag(myCNDA); double *preal = rarray.fortran_vec(); double *pimag = imarray.fortran_vec();
// two fortran_vec one for the real part and other one for the
complex part OCTAVE_LOCAL_BUFFER(double,LBNDA,nitem); OCTAVE_LOCAL_BUFFER(double,CLBNDA,nitem);
for (octave_idx_type i=0; i<nitem; i++) { LBNDA[i] = rarray(i) ; CLBNDA[i] = imarray(i) ; }
// Now create the contiguous derived datatype MPI_Datatype fortvec; MPI_Type_contiguous(nitem,MPI_DOUBLE, &fortvec); MPI_Type_commit(&fortvec);
for (octave_idx_type i = 0; i< rankrec.nelem(); i++) { // t_id is the identifier of octave NDArray printf("Sending block to %i \n",rankrec(i)); info = MPI_Send(&t_id, 1, MPI_INT, rankrec(i), tanktag[0], MPI_COMM_WORLD); printf("I
have sent %i \n",t_id); if (info !=MPI_SUCCESS) return info; // nitem is the total number of elements info = MPI_Send(&nitem, 1, MPI_INT, rankrec(i), tanktag[1], MPI_COMM_WORLD); printf("I have sent %i \n",nitem); if (info !=MPI_SUCCESS) return info; // ndims is number of dimensions info = MPI_Send(&nd, 1, MPI_INT, rankrec(i), tanktag[2], MPI_COMM_WORLD); printf("I have sent %i \n",nd); if (info !=MPI_SUCCESS) return info; // vector of dimensions sending info = MPI_Send(dimV, 1, dimvec, rankrec(i),
tanktag[3], MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; // data matrix sending info = MPI_Send(LBNDA,1,fortvec,rankrec(i),tanktag[4],MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; info = MPI_Send(CLBNDA,1,fortvec,rankrec(i),tanktag[5],MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info;
} // printf("info for sending scalar matrix is = %i \n",info); return(info); }
int send_float_complex_matrix(FloatComplexNDArray myCNDA,ColumnVector rankrec, int mytag){ int info; int nitem = myCNDA.nelem(); dim_vector dv = myCNDA.dims(); OCTAVE_LOCAL_BUFFER(int,tanktag,6); // int tanktag[5]; tanktag[0] =
mytag; tanktag[1]= tanktag[0]+1; tanktag[2]= tanktag[1]+1; tanktag[3]= tanktag[2]+1; tanktag[4]= tanktag[3]+1; tanktag[5]= tanktag[4]+1;
int nd = myCNDA.ndims (); int t_id = ov_float_complex_matrix; // Declare here the octave_local_buffers OCTAVE_LOCAL_BUFFER(int,dimV,nd); for (octave_idx_type i=0; i<nd; i++) { dimV[i] = dv(i) ; }
// Now create the contiguos derived datatype MPI_Datatype dimvec; MPI_Type_contiguous(nd,MPI_INT, &dimvec); MPI_Type_commit(&dimvec);
FloatNDArray rarray = real(myCNDA); FloatNDArray imarray = imag(myCNDA); float *preal = rarray.fortran_vec(); float *pimag = imarray.fortran_vec();
// two fortran_vec one for the real part and other one for the complex part
OCTAVE_LOCAL_BUFFER(float,LBNDA,nitem); OCTAVE_LOCAL_BUFFER(float,CLBNDA,nitem);
for (octave_idx_type i=0; i<nitem; i++) { LBNDA[i] = rarray(i) ; CLBNDA[i] = imarray(i) ; }
// Now create the contiguous derived datatype MPI_Datatype fortvec; MPI_Type_contiguous(nitem,MPI_FLOAT, &fortvec); MPI_Type_commit(&fortvec);
for (octave_idx_type i = 0; i< rankrec.nelem(); i++) { // t_id is the identifier of octave NDArray printf("Sending block to %i \n",rankrec(i)); info = MPI_Send(&t_id, 1, MPI_INT, rankrec(i), tanktag[0], MPI_COMM_WORLD); printf("I have sent %i
\n",t_id); if (info !=MPI_SUCCESS) return info; // nitem is the total number of elements info = MPI_Send(&nitem, 1, MPI_INT, rankrec(i), tanktag[1], MPI_COMM_WORLD); printf("I have sent %i \n",nitem); if (info !=MPI_SUCCESS) return info; // ndims is number of dimensions info = MPI_Send(&nd, 1, MPI_INT, rankrec(i), tanktag[2], MPI_COMM_WORLD); printf("I have sent %i \n",nd); if (info !=MPI_SUCCESS) return info; // vector of dimensions sending info = MPI_Send(dimV, 1, dimvec, rankrec(i), tanktag[3],
MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; // data matrix sending info = MPI_Send(LBNDA,1,fortvec,rankrec(i),tanktag[4],MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; info = MPI_Send(CLBNDA,1,fortvec,rankrec(i),tanktag[5],MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info;
} // printf("info for sending scalar matrix is = %i \n",info); return(info); }
int send_range(Range range,ColumnVector rankrec, int mytag){ /* put base,limit,incr,nelem */ /*-------------------------------*/ /* just 3 doubles + 1 int */ // octave_range (double base, double limit, double inc)
OCTAVE_LOCAL_BUFFER(double,d,3); d[0]= range.base(); d[1]= range.limit(); d[2]= range.inc(); int info; for (octave_idx_type i = 0; i< rankrec.nelem(); i++) { info = MPI_Send(d, 3, MPI_INT, rankrec(i), mytag, MPI_COMM_WORLD); } if (info !=MPI_SUCCESS) return info; return(MPI_SUCCESS); }
int send_matrix(NDArray myNDA,ColumnVector rankrec, int mytag){ int info; int nitem = myNDA.nelem(); dim_vector dv = myNDA.dims(); OCTAVE_LOCAL_BUFFER(int,tanktag,5); // int tanktag[5]; tanktag[0] = mytag; tanktag[1]= mytag+1; tanktag[2]= mytag+2; tanktag[3]= mytag+3; tanktag[4]= mytag+4;
int nd = myNDA.ndims (); int t_id = ov_matrix; // Declare here the octave_local_buffers
OCTAVE_LOCAL_BUFFER(int,dimV,nd); for (octave_idx_type i=0; i<nd; i++) { dimV[i] = dv(i) ; }
// Now create the contiguos derived datatype MPI_Datatype dimvec; MPI_Type_contiguous(nd,MPI_INT, &dimvec); MPI_Type_commit(&dimvec);
OCTAVE_LOCAL_BUFFER(double,LBNDA,nitem); double *p = myNDA.fortran_vec();
for (octave_idx_type i=0; i<nitem; i++) { // *LBNDA = *p; // LBNDA++; // p++; LBNDA[i] = myNDA(i) ; }
// Now create the contiguous derived datatype MPI_Datatype fortvec; MPI_Type_contiguous(nitem,MPI_DOUBLE, &fortvec); MPI_Type_commit(&fortvec);
for
(octave_idx_type i = 0; i< rankrec.nelem(); i++) { // t_id is the identifier of octave NDArray printf("Sending block to %i \n",rankrec(i)); info = MPI_Send(&t_id, 1, MPI_INT, rankrec(i), tanktag[0], MPI_COMM_WORLD); printf("I have sent %i \n",t_id); if (info !=MPI_SUCCESS) return info; // nitem is the total number of elements info = MPI_Send(&nitem, 1, MPI_INT, rankrec(i), tanktag[1], MPI_COMM_WORLD); printf("I have sent %i \n",nitem); if (info !=MPI_SUCCESS) return info; // ndims is number of dimensions
info = MPI_Send(&nd, 1, MPI_INT, rankrec(i), tanktag[2], MPI_COMM_WORLD); printf("I have sent %i \n",nd); if (info !=MPI_SUCCESS) return info; // vector of dimensions sending info = MPI_Send(dimV, 1, dimvec, rankrec(i), tanktag[3], MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; // data matrix sending info = MPI_Send(LBNDA,1,fortvec,rankrec(i),tanktag[4],MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; } // printf("info for sending scalar matrix is = %i \n",info); return(info); }
// Here we have float_matrix int send_float_matrix(FloatNDArray myNDA,ColumnVector rankrec,
int mytag){ int info; int nitem = myNDA.nelem(); dim_vector dv = myNDA.dims();
int tanktag[5]; tanktag[0] = mytag; tanktag[1]= tanktag[0]+1; tanktag[2]= tanktag[1]+1; tanktag[3]= tanktag[2]+1; tanktag[4]= tanktag[3]+1;
int nd = myNDA.ndims (); int t_id = ov_float_matrix; // Declare here the octave_local_buffers OCTAVE_LOCAL_BUFFER(int,dimV,nd); for (octave_idx_type i=0; i<nd; i++) { dimV[i] = dv(i) ; }
// Now create the contiguos derived datatype MPI_Datatype dimvec; MPI_Type_contiguous(nd,MPI_INT, &dimvec); MPI_Type_commit(&dimvec);
OCTAVE_LOCAL_BUFFER(float,LBNDA,nitem); float *p = myNDA.fortran_vec();
for (octave_idx_type i=0; i<nitem;
i++) { // *LBNDA = *p; // LBNDA++; // p++; LBNDA[i] = myNDA(i) ; }
// Now create the contiguous derived datatype MPI_Datatype fortvec; MPI_Type_contiguous(nitem,MPI_FLOAT, &fortvec); MPI_Type_commit(&fortvec);
for (octave_idx_type i = 0; i< rankrec.nelem(); i++) { // t_id is the identifier of octave NDArray printf("Sending block to %i \n",rankrec(i)); info = MPI_Send(&t_id, 1, MPI_INT, rankrec(i), tanktag[0], MPI_COMM_WORLD); printf("I have sent %i \n",t_id); if (info !=MPI_SUCCESS)
return info; // nitem is the total number of elements info = MPI_Send(&nitem, 1, MPI_INT, rankrec(i), tanktag[1], MPI_COMM_WORLD); printf("I have sent %i \n",nitem); if (info !=MPI_SUCCESS) return info; // ndims is number of dimensions info = MPI_Send(&nd, 1, MPI_INT, rankrec(i), tanktag[2], MPI_COMM_WORLD); printf("I have sent %i \n",nd); if (info !=MPI_SUCCESS) return info; // vector of dimensions sending info = MPI_Send(dimV, 1, dimvec, rankrec(i), tanktag[3], MPI_COMM_WORLD); if (info !=MPI_SUCCESS)
return info; // data matrix sending info = MPI_Send(LBNDA,1,fortvec,rankrec(i),tanktag[4],MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; } // printf("info for sending scalar matrix is = %i \n",info); return(info); }
int send_i8_mat(int8NDArray myNDA,ColumnVector rankrec, int mytag){ int info; int nitem = myNDA.nelem(); dim_vector dv = myNDA.dims();
int tanktag[5]; tanktag[0] = mytag; tanktag[1]= tanktag[0]+1; tanktag[2]= tanktag[1]+1; tanktag[3]= tanktag[2]+1; tanktag[4]= tanktag[3]+1;
int nd = myNDA.ndims (); int t_id = ov_int8_matrix; // Declare here the octave_local_buffers OCTAVE_LOCAL_BUFFER(int,dimV,nd); for (octave_idx_type i=0; i<nd;
i++) { dimV[i] = dv(i) ; }
// Now create the contiguos derived datatype MPI_Datatype dimvec; MPI_Type_contiguous(nd,MPI_INT, &dimvec); MPI_Type_commit(&dimvec);
OCTAVE_LOCAL_BUFFER(octave_int8,LBNDA,nitem);
for (octave_idx_type i=0; i<nitem; i++) { LBNDA[i] = myNDA(i) ; }
// Now create the contiguous derived datatype MPI_Datatype fortvec; MPI_Type_contiguous(nitem,MPI_BYTE, &fortvec); MPI_Type_commit(&fortvec);
for (octave_idx_type i = 0; i< rankrec.nelem(); i++) { // t_id is the identifier of octave NDArray printf("Sending block to %i \n",rankrec(i)); info =
MPI_Send(&t_id, 1, MPI_INT, rankrec(i), tanktag[0], MPI_COMM_WORLD); printf("I have sent %i \n",t_id); if (info !=MPI_SUCCESS) return info; // nitem is the total number of elements info = MPI_Send(&nitem, 1, MPI_INT, rankrec(i), tanktag[1], MPI_COMM_WORLD); printf("I have sent %i \n",nitem); if (info !=MPI_SUCCESS) return info; // ndims is number of dimensions info = MPI_Send(&nd, 1, MPI_INT, rankrec(i), tanktag[2], MPI_COMM_WORLD); printf("I have sent %i \n",nd); if (info !=MPI_SUCCESS) return info; // vector of
dimensions sending info = MPI_Send(dimV, 1, dimvec, rankrec(i), tanktag[3], MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; // data matrix sending info = MPI_Send(LBNDA,1,fortvec,rankrec(i),tanktag[4],MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; } // printf("info for sending scalar matrix is = %i \n",info); return(info); }
int send_i16_mat(int16NDArray myNDA,ColumnVector rankrec, int mytag){ int info; int nitem = myNDA.nelem(); dim_vector dv = myNDA.dims();
int tanktag[5]; tanktag[0] = mytag; tanktag[1]= tanktag[0]+1; tanktag[2]= tanktag[1]+1; tanktag[3]= tanktag[2]+1; tanktag[4]= tanktag[3]+1;
int nd = myNDA.ndims (); int t_id = ov_int16_matrix; // Declare here the octave_local_buffers OCTAVE_LOCAL_BUFFER(int,dimV,nd); for (octave_idx_type i=0; i<nd; i++) { dimV[i] = dv(i) ; }
// Now create the contiguos derived datatype MPI_Datatype dimvec; MPI_Type_contiguous(nd,MPI_INT, &dimvec); MPI_Type_commit(&dimvec);
OCTAVE_LOCAL_BUFFER(octave_int16,LBNDA,nitem);
for (octave_idx_type i=0; i<nitem; i++) { LBNDA[i] = myNDA(i) ; }
// Now create the contiguous derived datatype MPI_Datatype fortvec; MPI_Type_contiguous(nitem,MPI_SHORT, &fortvec); MPI_Type_commit(&fortvec);
for (octave_idx_type i = 0; i< rankrec.nelem(); i++) { //
t_id is the identifier of octave NDArray printf("Sending block to %i \n",rankrec(i)); info = MPI_Send(&t_id, 1, MPI_INT, rankrec(i), tanktag[0], MPI_COMM_WORLD); printf("I have sent %i \n",t_id); if (info !=MPI_SUCCESS) return info; // nitem is the total number of elements info = MPI_Send(&nitem, 1, MPI_INT, rankrec(i), tanktag[1], MPI_COMM_WORLD); printf("I have sent %i \n",nitem); if (info !=MPI_SUCCESS) return info; // ndims is number of dimensions info =
MPI_Send(&nd, 1, MPI_INT, rankrec(i), tanktag[2], MPI_COMM_WORLD); printf("I have sent %i \n",nd); if (info !=MPI_SUCCESS) return info; // vector of dimensions sending info = MPI_Send(dimV, 1, dimvec, rankrec(i), tanktag[3], MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; // data matrix sending info = MPI_Send(LBNDA,1,fortvec,rankrec(i),tanktag[4],MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; } // printf("info for sending scalar matrix is = %i \n",info); return(info); }
int send_i32_mat(int32NDArray myNDA,ColumnVector rankrec, int mytag){ int info; int nitem =
myNDA.nelem(); dim_vector dv = myNDA.dims();
int tanktag[5]; tanktag[0] = mytag; tanktag[1]= tanktag[0]+1; tanktag[2]= tanktag[1]+1; tanktag[3]= tanktag[2]+1; tanktag[4]= tanktag[3]+1;
int nd = myNDA.ndims (); int t_id = ov_int32_matrix; // Declare here the octave_local_buffers OCTAVE_LOCAL_BUFFER(int,dimV,nd); for (octave_idx_type i=0; i<nd; i++) { dimV[i] = dv(i) ; }
// Now create the contiguos derived datatype MPI_Datatype dimvec; MPI_Type_contiguous(nd,MPI_INT, &dimvec); MPI_Type_commit(&dimvec);
OCTAVE_LOCAL_BUFFER(octave_int32,LBNDA,nitem);
for (octave_idx_type i=0; i<nitem; i++) { LBNDA[i] = myNDA(i) ; }
// Now create the contiguous derived datatype
MPI_Datatype fortvec; MPI_Type_contiguous(nitem,MPI_INT, &fortvec); MPI_Type_commit(&fortvec);
for (octave_idx_type i = 0; i< rankrec.nelem(); i++) { // t_id is the identifier of octave NDArray printf("Sending block to %i \n",rankrec(i)); info = MPI_Send(&t_id, 1, MPI_INT, rankrec(i), tanktag[0], MPI_COMM_WORLD); printf("I have sent %i \n",t_id); if (info !=MPI_SUCCESS) return info; // nitem is the total number of elements info = MPI_Send(&nitem, 1, MPI_INT, rankrec(i), tanktag[1], MPI_COMM_WORLD); printf("I have sent
%i \n",nitem); if (info !=MPI_SUCCESS) return info; // ndims is number of dimensions info = MPI_Send(&nd, 1, MPI_INT, rankrec(i), tanktag[2], MPI_COMM_WORLD); printf("I have sent %i \n",nd); if (info !=MPI_SUCCESS) return info; // vector of dimensions sending info = MPI_Send(dimV, 1, dimvec, rankrec(i), tanktag[3], MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; // data matrix sending info = MPI_Send(LBNDA,1,fortvec,rankrec(i),tanktag[4],MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; } // printf("info for sending scalar matrix
is = %i \n",info); return(info); }
int send_i64_mat(int64NDArray myNDA,ColumnVector rankrec, int mytag){ int info; int nitem = myNDA.nelem(); dim_vector dv = myNDA.dims();
int tanktag[5]; tanktag[0] = mytag; tanktag[1]= tanktag[0]+1; tanktag[2]= tanktag[1]+1; tanktag[3]= tanktag[2]+1; tanktag[4]= tanktag[3]+1;
int nd = myNDA.ndims (); int t_id = ov_int64_matrix; // Declare here the octave_local_buffers OCTAVE_LOCAL_BUFFER(int,dimV,nd); for (octave_idx_type i=0; i<nd; i++) { dimV[i] = dv(i) ; }
// Now create the contiguos derived datatype MPI_Datatype dimvec; MPI_Type_contiguous(nd,MPI_INT, &dimvec); MPI_Type_commit(&dimvec);
OCTAVE_LOCAL_BUFFER(octave_int64,LBNDA,nitem);
for (octave_idx_type i=0; i<nitem; i++) { LBNDA[i] = myNDA(i) ; }
// Now create the contiguous derived datatype MPI_Datatype fortvec; MPI_Type_contiguous(nitem,MPI_LONG_LONG, &fortvec); MPI_Type_commit(&fortvec);
for (octave_idx_type i = 0; i< rankrec.nelem(); i++) { // t_id is the identifier of octave NDArray printf("Sending block to %i \n",rankrec(i)); info = MPI_Send(&t_id, 1, MPI_INT, rankrec(i), tanktag[0], MPI_COMM_WORLD); printf("I have sent %i \n",t_id); if (info !=MPI_SUCCESS) return info; // nitem is
the total number of elements info = MPI_Send(&nitem, 1, MPI_INT, rankrec(i), tanktag[1], MPI_COMM_WORLD); printf("I have sent %i \n",nitem); if (info !=MPI_SUCCESS) return info; // ndims is number of dimensions info = MPI_Send(&nd, 1, MPI_INT, rankrec(i), tanktag[2], MPI_COMM_WORLD); printf("I have sent %i \n",nd); if (info !=MPI_SUCCESS) return info; // vector of dimensions sending info = MPI_Send(dimV, 1, dimvec, rankrec(i), tanktag[3], MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; // data
matrix sending info = MPI_Send(LBNDA,1,fortvec,rankrec(i),tanktag[4],MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; } // printf("info for sending scalar matrix is = %i \n",info); return(info); } int send_ui8_mat(uint8NDArray myNDA,ColumnVector rankrec, int mytag){ int info; int nitem = myNDA.nelem(); dim_vector dv = myNDA.dims();
int tanktag[5]; tanktag[0] = mytag; tanktag[1]= tanktag[0]+1; tanktag[2]= tanktag[1]+1; tanktag[3]= tanktag[2]+1; tanktag[4]= tanktag[3]+1;
int nd = myNDA.ndims (); int t_id = ov_uint8_matrix; // Declare here the octave_local_buffers OCTAVE_LOCAL_BUFFER(int,dimV,nd); for (octave_idx_type i=0; i<nd; i++) { dimV[i] = dv(i)
; }
// Now create the contiguos derived datatype MPI_Datatype dimvec; MPI_Type_contiguous(nd,MPI_INT, &dimvec); MPI_Type_commit(&dimvec);
OCTAVE_LOCAL_BUFFER(octave_uint8,LBNDA,nitem);
for (octave_idx_type i=0; i<nitem; i++) { LBNDA[i] = myNDA(i) ; }
// Now create the contiguous derived datatype MPI_Datatype fortvec; MPI_Type_contiguous(nitem,MPI_UNSIGNED_CHAR, &fortvec); MPI_Type_commit(&fortvec);
for (octave_idx_type i = 0; i< rankrec.nelem(); i++) { // t_id is the identifier of octave NDArray printf("Sending block to %i \n",rankrec(i)); info = MPI_Send(&t_id, 1, MPI_INT,
rankrec(i), tanktag[0], MPI_COMM_WORLD); printf("I have sent %i \n",t_id); if (info !=MPI_SUCCESS) return info; // nitem is the total number of elements info = MPI_Send(&nitem, 1, MPI_INT, rankrec(i), tanktag[1], MPI_COMM_WORLD); printf("I have sent %i \n",nitem); if (info !=MPI_SUCCESS) return info; // ndims is number of dimensions info = MPI_Send(&nd, 1, MPI_INT, rankrec(i), tanktag[2], MPI_COMM_WORLD); printf("I have sent %i \n",nd); if (info !=MPI_SUCCESS) return info; // vector of dimensions
sending info = MPI_Send(dimV, 1, dimvec, rankrec(i), tanktag[3], MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; // data matrix sending info = MPI_Send(LBNDA,1,fortvec,rankrec(i),tanktag[4],MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; } // printf("info for sending scalar matrix is = %i \n",info); return(info); }
int send_ui16_mat(uint16NDArray myNDA,ColumnVector rankrec, int mytag){ int info; int nitem = myNDA.nelem(); dim_vector dv = myNDA.dims();
int tanktag[5]; tanktag[0] = mytag; tanktag[1]= tanktag[0]+1; tanktag[2]= tanktag[1]+1; tanktag[3]= tanktag[2]+1; tanktag[4]= tanktag[3]+1;
int nd =
myNDA.ndims (); int t_id = ov_uint16_matrix; // Declare here the octave_local_buffers OCTAVE_LOCAL_BUFFER(int,dimV,nd); for (octave_idx_type i=0; i<nd; i++) { dimV[i] = dv(i) ; }
// Now create the contiguos derived datatype MPI_Datatype dimvec; MPI_Type_contiguous(nd,MPI_INT, &dimvec); MPI_Type_commit(&dimvec);
OCTAVE_LOCAL_BUFFER(octave_uint16,LBNDA,nitem);
for (octave_idx_type i=0; i<nitem; i++) { LBNDA[i] = myNDA(i) ; }
// Now create the contiguous derived datatype MPI_Datatype fortvec; MPI_Type_contiguous(nitem,MPI_UNSIGNED_SHORT, &fortvec); MPI_Type_commit(&fortvec);
for (octave_idx_type i = 0; i< rankrec.nelem(); i++) { //
t_id is the identifier of octave NDArray printf("Sending block to %i \n",rankrec(i)); info = MPI_Send(&t_id, 1, MPI_INT, rankrec(i), tanktag[0], MPI_COMM_WORLD); printf("I have sent %i \n",t_id); if (info !=MPI_SUCCESS) return info; // nitem is the total number of elements info = MPI_Send(&nitem, 1, MPI_INT, rankrec(i), tanktag[1], MPI_COMM_WORLD); printf("I have sent %i \n",nitem); if (info !=MPI_SUCCESS) return info; // ndims is number of dimensions info = MPI_Send(&nd, 1, MPI_INT,
rankrec(i), tanktag[2], MPI_COMM_WORLD); printf("I have sent %i \n",nd); if (info !=MPI_SUCCESS) return info; // vector of dimensions sending info = MPI_Send(dimV, 1, dimvec, rankrec(i), tanktag[3], MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; // data matrix sending info = MPI_Send(LBNDA,1,fortvec,rankrec(i),tanktag[4],MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; } // printf("info for sending scalar matrix is = %i \n",info); return(info); } int send_ui32_mat(uint32NDArray myNDA,ColumnVector rankrec, int mytag){ int info; int nitem = myNDA.nelem(); dim_vector dv =
myNDA.dims();
int tanktag[5]; tanktag[0] = mytag; tanktag[1]= tanktag[0]+1; tanktag[2]= tanktag[1]+1; tanktag[3]= tanktag[2]+1; tanktag[4]= tanktag[3]+1;
int nd = myNDA.ndims (); int t_id = ov_uint32_matrix; // Declare here the octave_local_buffers OCTAVE_LOCAL_BUFFER(int,dimV,nd); for (octave_idx_type i=0; i<nd; i++) { dimV[i] = dv(i) ; }
// Now create the contiguos derived datatype MPI_Datatype dimvec; MPI_Type_contiguous(nd,MPI_INT, &dimvec); MPI_Type_commit(&dimvec);
OCTAVE_LOCAL_BUFFER(octave_uint32,LBNDA,nitem);
for (octave_idx_type i=0; i<nitem; i++) { LBNDA[i] = myNDA(i) ; }
// Now create the contiguous derived datatype MPI_Datatype fortvec;
MPI_Type_contiguous(nitem,MPI_UNSIGNED, &fortvec); MPI_Type_commit(&fortvec);
for (octave_idx_type i = 0; i< rankrec.nelem(); i++) { // t_id is the identifier of octave NDArray printf("Sending block to %i \n",rankrec(i)); info = MPI_Send(&t_id, 1, MPI_INT, rankrec(i), tanktag[0], MPI_COMM_WORLD); printf("I have sent %i \n",t_id); if (info !=MPI_SUCCESS) return info; // nitem is the total number of elements info = MPI_Send(&nitem, 1, MPI_INT, rankrec(i), tanktag[1], MPI_COMM_WORLD); printf("I have sent %i
\n",nitem); if (info !=MPI_SUCCESS) return info; // ndims is number of dimensions info = MPI_Send(&nd, 1, MPI_INT, rankrec(i), tanktag[2], MPI_COMM_WORLD); printf("I have sent %i \n",nd); if (info !=MPI_SUCCESS) return info; // vector of dimensions sending info = MPI_Send(dimV, 1, dimvec, rankrec(i), tanktag[3], MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; // data matrix sending info = MPI_Send(LBNDA,1,fortvec,rankrec(i),tanktag[4],MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; } // printf("info for sending scalar matrix is =
%i \n",info); return(info); }
int send_ui64_mat(uint64NDArray myNDA,ColumnVector rankrec, int mytag){ int info; int nitem = myNDA.nelem(); dim_vector dv = myNDA.dims();
int tanktag[5]; tanktag[0] = mytag; tanktag[1]= tanktag[0]+1; tanktag[2]= tanktag[1]+1; tanktag[3]= tanktag[2]+1; tanktag[4]= tanktag[3]+1;
int nd = myNDA.ndims (); int t_id = ov_uint64_matrix; // Declare here the octave_local_buffers OCTAVE_LOCAL_BUFFER(int,dimV,nd); for (octave_idx_type i=0; i<nd; i++) { dimV[i] = dv(i) ; }
// Now create the contiguos derived datatype MPI_Datatype dimvec; MPI_Type_contiguous(nd,MPI_INT, &dimvec); MPI_Type_commit(&dimvec);
OCTAVE_LOCAL_BUFFER(octave_uint64,LBNDA,nitem);
for (octave_idx_type i=0; i<nitem; i++) { LBNDA[i] = myNDA(i) ; }
// Now create the contiguous derived datatype MPI_Datatype fortvec; MPI_Type_contiguous(nitem,MPI_UNSIGNED_LONG_LONG, &fortvec); MPI_Type_commit(&fortvec);
for (octave_idx_type i = 0; i< rankrec.nelem(); i++) { // t_id is the identifier of octave NDArray printf("Sending block to %i \n",rankrec(i)); info = MPI_Send(&t_id, 1, MPI_INT, rankrec(i), tanktag[0], MPI_COMM_WORLD); printf("I have sent %i \n",t_id); if (info !=MPI_SUCCESS) return info; //
nitem is the total number of elements info = MPI_Send(&nitem, 1, MPI_INT, rankrec(i), tanktag[1], MPI_COMM_WORLD); printf("I have sent %i \n",nitem); if (info !=MPI_SUCCESS) return info; // ndims is number of dimensions info = MPI_Send(&nd, 1, MPI_INT, rankrec(i), tanktag[2], MPI_COMM_WORLD); printf("I have sent %i \n",nd); if (info !=MPI_SUCCESS) return info; // vector of dimensions sending info = MPI_Send(dimV, 1, dimvec, rankrec(i), tanktag[3], MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; //
data matrix sending info = MPI_Send(LBNDA,1,fortvec,rankrec(i),tanktag[4],MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; } // printf("info for sending scalar matrix is = %i \n",info); return(info); }
int send_ch_mat(charNDArray myNDA,ColumnVector rankrec, int mytag){ int info; int nitem = myNDA.nelem(); dim_vector dv = myNDA.dims(); OCTAVE_LOCAL_BUFFER(int,tanktag,5); // int tanktag[5]; tanktag[0] = mytag; tanktag[1]= tanktag[0]+1; tanktag[2]= tanktag[1]+1; tanktag[3]= tanktag[2]+1; tanktag[4]= tanktag[3]+1;
int nd = myNDA.ndims (); int t_id = ov_char_matrix; // Declare here the octave_local_buffers OCTAVE_LOCAL_BUFFER(int,dimV,nd); for (octave_idx_type i=0;
i<nd; i++) { dimV[i] = dv(i) ; }
// Now create the contiguos derived datatype MPI_Datatype dimvec; MPI_Type_contiguous(nd,MPI_INT, &dimvec); MPI_Type_commit(&dimvec);
OCTAVE_LOCAL_BUFFER(char,LBNDA,nitem);
for (octave_idx_type i=0; i<nitem; i++) { // *LBNDA = *p; // LBNDA++; // p++; LBNDA[i] = myNDA(i) ; }
// Now create the contiguous derived datatype MPI_Datatype fortvec; MPI_Type_contiguous(nitem,MPI_CHAR, &fortvec); MPI_Type_commit(&fortvec);
for (octave_idx_type i = 0; i< rankrec.nelem(); i++) { // t_id is the identifier of octave
NDArray printf("Sending block to %i \n",rankrec(i)); info = MPI_Send(&t_id, 1, MPI_INT, rankrec(i), tanktag[0], MPI_COMM_WORLD); printf("I have sent %i \n",t_id); if (info !=MPI_SUCCESS) return info; // nitem is the total number of elements info = MPI_Send(&nitem, 1, MPI_INT, rankrec(i), tanktag[1], MPI_COMM_WORLD); printf("I have sent %i \n",nitem); if (info !=MPI_SUCCESS) return info; // ndims is number of dimensions info = MPI_Send(&nd, 1, MPI_INT, rankrec(i), tanktag[2],
MPI_COMM_WORLD); printf("I have sent %i \n",nd); if (info !=MPI_SUCCESS) return info; // vector of dimensions sending info = MPI_Send(dimV, 1, dimvec, rankrec(i), tanktag[3], MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; // data matrix sending info = MPI_Send(LBNDA,1,fortvec,rankrec(i),tanktag[4],MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; } // printf("info for sending scalar matrix is = %i \n",info); return(info); }
int send_bl_mat(boolNDArray myNDA,ColumnVector rankrec, int mytag){ int info; int nitem = myNDA.nelem(); dim_vector dv =
myNDA.dims();
int tanktag[5]; tanktag[0] = mytag; tanktag[1]= tanktag[0]+1; tanktag[2]= tanktag[1]+1; tanktag[3]= tanktag[2]+1; tanktag[4]= tanktag[3]+1;
int nd = myNDA.ndims (); int t_id = ov_matrix; // Declare here the octave_local_buffers OCTAVE_LOCAL_BUFFER(int,dimV,nd); for (octave_idx_type i=0; i<nd; i++) { dimV[i] = dv(i) ; }
// Now create the contiguos derived datatype MPI_Datatype dimvec; MPI_Type_contiguous(nd,MPI_INT, &dimvec); MPI_Type_commit(&dimvec);
OCTAVE_LOCAL_BUFFER(int,LBNDA,nitem);
for (octave_idx_type i=0; i<nitem; i++) { LBNDA[i] = myNDA(i) ; }
// Now create the contiguous derived datatype MPI_Datatype fortvec;
MPI_Type_contiguous(nitem,MPI_INT, &fortvec); MPI_Type_commit(&fortvec);
for (octave_idx_type i = 0; i< rankrec.nelem(); i++) { // t_id is the identifier of octave NDArray printf("Sending block to %i \n",rankrec(i)); info = MPI_Send(&t_id, 1, MPI_INT, rankrec(i), tanktag[0], MPI_COMM_WORLD); printf("I have sent %i \n",t_id); if (info !=MPI_SUCCESS) return info; // nitem is the total number of elements info = MPI_Send(&nitem, 1, MPI_INT, rankrec(i), tanktag[1], MPI_COMM_WORLD); printf("I have sent %i
\n",nitem); if (info !=MPI_SUCCESS) return info; // ndims is number of dimensions info = MPI_Send(&nd, 1, MPI_INT, rankrec(i), tanktag[2], MPI_COMM_WORLD); printf("I have sent %i \n",nd); if (info !=MPI_SUCCESS) return info; // vector of dimensions sending info = MPI_Send(dimV, 1, dimvec, rankrec(i), tanktag[3], MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; // data matrix sending info = MPI_Send(LBNDA,1,fortvec,rankrec(i),tanktag[4],MPI_COMM_WORLD); if (info !=MPI_SUCCESS) return info; } // printf("info for sending scalar matrix is =
%i \n",info); return(info); }
int send_class(octave_value ov, ColumnVector rankrec,int mytag){ /* varname-strlength 1st, dims[ndim] */ /*----------------------------------*/ /* and then appropriate specific info */ int t_id = ov.type_id(); // printf("t_id =%i\n",t_id);
// The T_id would be the tag
switch (t_id) { case ov_cell: return(send_cell (ov.cell_value (),rankrec,mytag)); case ov_scalar: return(send_scalar (ov.scalar_value (),rankrec,mytag)); case ov_complex_scalar: return(send_complex_scalar(ov.complex_value(),rankrec,mytag)); case ov_matrix: return(send_matrix
(ov.array_value (),rankrec,mytag)); case ov_sparse_matrix: return(send_sp_mat (ov.sparse_matrix_value (),rankrec,mytag)); case ov_complex_matrix: return(send_complex_matrix(ov.complex_array_value(),rankrec,mytag)); case ov_sparse_complex_matrix: return(send_sp_cx_mat(ov.sparse_complex_matrix_value (),rankrec,mytag));
case ov_float_scalar: return(send_float_scalar (ov.float_scalar_value (),rankrec,mytag)); case ov_float_complex_scalar: return(send_float_complex_scalar(ov.float_complex_value(),rankrec,mytag));
case ov_float_matrix: return(send_float_matrix (ov.array_value (),rankrec,mytag)); case
ov_float_complex_matrix: return(send_float_complex_matrix(ov.float_complex_array_value(),rankrec,mytag));
case ov_range: return(send_range (ov.range_value (),rankrec,mytag));
case ov_bool: return(send_bool (ov.bool_value (),rankrec,mytag)); case ov_bool_matrix: return(send_bl_mat (ov.bool_array_value(),rankrec,mytag)); case ov_sparse_bool_matrix: return(send_sp_bl_mat (ov.sparse_bool_matrix_value (),rankrec,mytag)); case ov_char_matrix: return(send_ch_mat (ov.char_array_value(),rankrec,mytag)); case ov_string: return(send_string (ov.string_value(),rankrec,mytag)); case ov_sq_string:
return(send_string (ov.string_value(),rankrec,mytag));
case ov_int8_scalar: return(send_i8 (ov.int8_scalar_value(),rankrec,mytag)); case ov_int16_scalar: return(send_i16 (ov.int16_scalar_value(),rankrec,mytag)); case ov_int32_scalar: return(send_i32 (ov.int32_scalar_value (),rankrec,mytag)); case ov_int64_scalar: return(send_i64 (ov.int32_scalar_value (),rankrec,mytag));
case ov_uint8_scalar: return(send_ui8 (ov.uint8_scalar_value(),rankrec,mytag)); case ov_uint16_scalar: return(send_ui16
(ov.uint16_scalar_value(),rankrec,mytag)); case ov_uint64_scalar: return(send_ui64 (ov.uint32_scalar_value(),rankrec,mytag));
case ov_int8_matrix: return(send_i8_mat (ov.int8_array_value(),rankrec,mytag)); case ov_int16_matrix: return(send_i16_mat(ov.int16_array_value(),rankrec,mytag)); case ov_int32_matrix: return(send_i32_mat(ov.int32_array_value(),rankrec,mytag)); case ov_int64_matrix: return(send_i32_mat(ov.int64_array_value(),rankrec,mytag));
case ov_uint8_matrix: return(send_ui8_mat (ov.uint8_array_value(),rankrec,mytag)); case ov_uint16_matrix: return(send_ui16_mat(ov.uint16_array_value(),rankrec,mytag)); case
ov_uint32_matrix: return(send_ui32_mat(ov.uint32_array_value(),rankrec,mytag)); case ov_uint64_matrix: return(send_ui64_mat(ov.int64_array_value(),rankrec,mytag));
case ov_struct: return(send_struct (ov.map_value (),rankrec,mytag));
case ov_unknown: printf("MPI_Send: unknown class\n"); return(MPI_ERR_UNKNOWN );
case ov_class: case ov_list: case ov_cs_list: case ov_magic_colon: case ov_built_in_function: case
ov_user_defined_function: case ov_dynamically_linked_function: case ov_function_handle: case ov_inline_function: case ov_float_diagonal_matrix: case ov_float_complex_diagonal_matrix: case ov_diagonal_matrix: case ov_complex_diagonal_matrix: case ov_permutation_matrix: case ov_null_matrix: case ov_null_string: case ov_null_sq_string: default: printf("MPI_Send: unsupported class
%s\n", ov.type_name().c_str()); return(MPI_ERR_UNKNOWN ); } }
DEFUN_DLD(MPI_Send,args,, "MPI_Send sends almost any Octave datatypes into contiguous memory using openmpi library even over an hetherogeneous cluster i.e 32 bits CPUs and 64 bits CPU \n") { octave_value retval; // Check if MPI environment is initialized // first argument octave_value we want to send // second argument columnv vector rank of the receivers // for tag we use the type of octave_value ( see enum above ) // if alternative comunicator is provided select predefined MPI_COMM_WORLD // Put the rank of the receiver into a columnvector int nargin = args.length (); if
(nargin != 3) { error ("expecting 3 input arguments"); return retval; } ColumnVector tankrank = args(1).column_vector_value(); if (error_state) { error ("expecting second argument to be a column vector"); return retval; } int mytag = args(2).int_value(); if (error_state) { error ("expecting third vector argument to be an integer value"); return retval; }
int info = send_class (args(0), tankrank, mytag); retval=info; //
retval(1) = tanktag; return retval; } MPI_Recv.cc
// mkoctfile -lpthread -I/home/user/openmpi-1.3.3/include/ -L/home/user/openmpi-1.3.3/lib -lmpi_cxx -lmpi -lopen-rte -lopen-pal -ldl -lnsl -lutil -lm -ldl MPI_Send.cc // mkoctfile -lpthread -I/home/corradin/openmpi-1.3.3/include/ -L/home/corradin/openmpi-1.3.3/lib -lmpi_cxx -lmpi -lopen-rte -lopen-pal -ldl -lnsl -lutil -lm -ldl MPI_Recv.cc
/* * Receives most Octave datatypes into contiguous memory * using derived datatypes * info = MPI_Send(var,rank) */ #include "mpi.h" #include <octave/oct.h> #include <ov-cell.h> // avoid errmsg "cell -- incomplete datatype" #include <oct-map.h> // avoid errmsg "Oct.map -- invalid use undef type"
// tested on Octave 3.2.3 // Octave 3.2.X
enum
ov_t_id {
ov_unknown=0, // t_id=0 ov_cell, // t_id=1 ov_scalar, // t_id=2 ov_complex_scalar, // t_id=3 ov_matrix, // t_id=4 ov_diagonal_matrix, // t_id=5 ov_complex_matrix, // t_id=6 ov_complex_diagonal_matrix, // t_id=7 ov_range, // t_id=8 ov_bool, //
t_id=9 ov_bool_matrix, // t_id=10 ov_char_matrix, // t_id=11 ov_string, // t_id=12 ov_sq_string, // t_id=13 ov_int8_scalar, // t_id=14 ov_int16_scalar, // t_id=15 ov_int32_scalar, // t_id=16 ov_int64_scalar, // t_id=17 ov_uint8_scalar, // t_id=18 ov_uint16_scalar, //
t_id=19 ov_uint32_scalar, // t_id=20 ov_uint64_scalar, // t_id=21 ov_int8_matrix, // t_id=22 ov_int16_matrix, // t_id=23 ov_int32_matrix, // t_id=24 ov_int64_matrix, // t_id=25 ov_uint8_matrix, // t_id=26 ov_uint16_matrix, // t_id=27 ov_uint32_matrix, // t_id=28 ov_uint64_matrix, //
t_id=29 ov_sparse_bool_matrix, // t_id=30
ov_sparse_matrix, // t_id=31 ov_sparse_complex_matrix, ov_struct, ov_class, ov_list, ov_cs_list, ov_magic_colon, ov_built_in_function, ov_user_defined_function, ov_dynamically_linked_function, ov_function_handle, ov_inline_function, ov_float_scalar, ov_float_complex_scalar, ov_float_matrix, ov_float_diagonal_matrix, ov_float_complex_matrix, ov_float_complex_diagonal_matrix, ov_permutation_matrix, ov_null_matrix, ov_null_string, ov_null_sq_string, };
/*----------------------------------*/ /* forward declaration */
int recv_class( octave_value &ov, int source, int mytag);
/* along the datatype */ /*----------------------------------*/ /* to send any octave_value */
int recv_string( octave_value &ov, int source, int mytag){ /* directly MPI_Send it, */ /*-----------------------------*/ /* it's just a double value */
OCTAVE_LOCAL_BUFFER(int, tanktag, 2); tanktag[0]=mytag; tanktag[1]=mytag+1; tanktag[2]=mytag+2;
int info,nitem; MPI_Status stat; info = MPI_Recv((&nitem), 1,MPI_INT, source, tanktag[1] , MPI_COMM_WORLD,&stat); printf("I have received number of elements %i \n",nitem); OCTAVE_LOCAL_BUFFER(char,mess,nitem+1); if (info !=MPI_SUCCESS) return info; MPI_Datatype fortvec; MPI_Type_contiguous(nitem,MPI_CHAR, &fortvec);
MPI_Type_commit(&fortvec);
info = MPI_Recv(mess, 1,fortvec, source, tanktag[2] , MPI_COMM_WORLD,&stat); printf("Flag for string received %i \n",info); std::string cpp_string; cpp_string = mess; ov = cpp_string; if (info !=MPI_SUCCESS) return info; return(MPI_SUCCESS); }
int recv_matrix(octave_value &ov,int source, int mytag){
OCTAVE_LOCAL_BUFFER(int, tanktag, 5); tanktag[0] = mytag; tanktag[1] = mytag+1; tanktag[2] = mytag+2; tanktag[3] = mytag+3; tanktag[4] = mytag+4;
int info; int nitem,nd; MPI_Status stat; dim_vector dv; // nitem is the total number of elements info = MPI_Recv((&nitem), 1,MPI_INT,
source, tanktag[1] , MPI_COMM_WORLD,&stat); printf("I have received number of elements %i \n",nitem); if (info !=MPI_SUCCESS) return info; // ndims is number of dimensions info = MPI_Recv((&nd), 1,MPI_INT, source, tanktag[2] , MPI_COMM_WORLD,&stat); printf("I have received number of dimensions %i \n",nd); if (info !=MPI_SUCCESS) return info; // Now create contiguos datatype for dim vector dv.resize(nd); OCTAVE_LOCAL_BUFFER(int,dimV,nd); MPI_Datatype dimvec; MPI_Type_contiguous(nd,MPI_INT, &dimvec); MPI_Type_commit(&dimvec);
info = MPI_Recv((dimV), 1,dimvec,
source, tanktag[3] , MPI_COMM_WORLD,&stat); if (info !=MPI_SUCCESS) return info;
// Now reverse the content of int vector into dim vector for (octave_idx_type i=0; i<nd; i++) { dv(i) = dimV[i] ; printf("I am printing dimvector %i \n",dimV[i]); } NDArray myNDA(dv); // double *p = myNDA.fortran_vec(); OCTAVE_LOCAL_BUFFER(double,LBNDA,nitem); // printf("BUFFER CREATED \n"); // Now create the contiguous derived datatype MPI_Datatype fortvec; MPI_Type_contiguous(nitem,MPI_DOUBLE, &fortvec); MPI_Type_commit(&fortvec); printf("I am printing dimvector %i \n",tanktag[4]); info = MPI_Recv((LBNDA), 1,fortvec,
source, tanktag[4] , MPI_COMM_WORLD,&stat); printf("info for receiving data is = %i \n",info); if (info !=MPI_SUCCESS) return info; for (octave_idx_type i=0; i<nitem; i++) { // *LBNDA = *p; // LBNDA++; // p++; myNDA(i)=LBNDA[i]; } ov = myNDA; // printf("info for receiving scalar matrix is = %i \n",info);
}
int recv_float_matrix(octave_value &ov,int source, int mytag){
OCTAVE_LOCAL_BUFFER(int, tanktag, 5); tanktag[0] = mytag; tanktag[1] = mytag+1; tanktag[2] = mytag+2; tanktag[3] = mytag+3; tanktag[4] = mytag+4; int info; int
nitem,nd; MPI_Status stat; dim_vector dv; // nitem is the total number of elements info = MPI_Recv((&nitem), 1,MPI_INT, source, tanktag[1] , MPI_COMM_WORLD,&stat); // printf("I have received number of elements %i \n",nitem); if (info !=MPI_SUCCESS) return info; // ndims is number of dimensions info = MPI_Recv((&nd), 1,MPI_INT, source, tanktag[2] , MPI_COMM_WORLD,&stat); // printf("I have received number of dimensions %i \n",nd); if (info !=MPI_SUCCESS) return info; // Now create contiguos datatype for dim vector dv.resize(nd);
OCTAVE_LOCAL_BUFFER(int,dimV,nd); MPI_Datatype dimvec; MPI_Type_contiguous(nd,MPI_INT, &dimvec); MPI_Type_commit(&dimvec);
info = MPI_Recv((dimV), 1,dimvec, source, tanktag[3] , MPI_COMM_WORLD,&stat); if (info !=MPI_SUCCESS) return info;
// Now reverse the content of int vector into dim vector for (octave_idx_type i=0; i<nd; i++) { printf("I am printing dimvector %i \n",dimV[i]); dv(i) = dimV[i] ; } FloatNDArray myNDA(dv); float *p = myNDA.fortran_vec(); OCTAVE_LOCAL_BUFFER(float,LBNDA,nitem); // printf("BUFFER CREATED \n"); // Now create the contiguous derived datatype MPI_Datatype fortvec; MPI_Type_contiguous(nitem,MPI_FLOAT,
&fortvec); MPI_Type_commit(&fortvec);
info = MPI_Recv((LBNDA), 1,fortvec, source, tanktag[4] , MPI_COMM_WORLD,&stat); // printf("info for receiving data is = %i \n",info); if (info !=MPI_SUCCESS) return info; for (octave_idx_type i=0; i<nitem; i++) { // *LBNDA = *p; // LBNDA++; // p++; myNDA(i)=LBNDA[i]; } ov = myNDA; // printf("info for receiving scalar matrix is = %i \n",info);
}
int recv_complex_matrix(octave_value &ov,int source, int mytag){
OCTAVE_LOCAL_BUFFER(int, tanktag,
6); tanktag[0] = mytag; tanktag[1] = mytag+1; tanktag[2] = mytag+2; tanktag[3] = mytag+3; tanktag[4] = mytag+4; tanktag[5] = mytag+5;
int info; int nitem,nd; MPI_Status stat; dim_vector dv; // nitem is the total number of elements info = MPI_Recv((&nitem), 1,MPI_INT, source, tanktag[1] , MPI_COMM_WORLD,&stat); // printf("I have received number of elements %i \n",nitem); if (info !=MPI_SUCCESS) return info; // ndims is number of dimensions info = MPI_Recv((&nd), 1,MPI_INT, source, tanktag[2] , MPI_COMM_WORLD,&stat); // printf("I have received number of
dimensions %i \n",nd); if (info !=MPI_SUCCESS) return info; // Now create contiguos datatype for dim vector dv.resize(nd); OCTAVE_LOCAL_BUFFER(int,dimV,nd); MPI_Datatype dimvec; MPI_Type_contiguous(nd,MPI_INT, &dimvec); MPI_Type_commit(&dimvec);
info = MPI_Recv((dimV), 1,dimvec, source, tanktag[3] , MPI_COMM_WORLD,&stat); if (info !=MPI_SUCCESS) return info;
// Now reverse the content of int vector into dim vector for (octave_idx_type i=0; i<nd; i++) { // printf("I am printing dimvector %i \n",i); dv(i) = dimV[i] ; } NDArray rmyNDA(dv); // for the real part NDArray imyNDA(dv); // for the img part
ComplexNDArray oa (dv); /* Create->Delete on ret?!? */
double *p = rmyNDA.fortran_vec(); double *ip = imyNDA.fortran_vec(); OCTAVE_LOCAL_BUFFER(double,LBNDA,nitem); OCTAVE_LOCAL_BUFFER(double,CLBNDA,nitem);
// printf("BUFFER CREATED \n"); // Now create the contiguous derived datatype MPI_Datatype fortvec; MPI_Type_contiguous(nitem,MPI_DOUBLE, &fortvec); MPI_Type_commit(&fortvec);
info = MPI_Recv((LBNDA), 1,fortvec, source, tanktag[4] , MPI_COMM_WORLD,&stat); // printf("info for receiving data is = %i \n",info); if (info !=MPI_SUCCESS) return
info;
info = MPI_Recv((CLBNDA), 1,fortvec, source, tanktag[5] , MPI_COMM_WORLD,&stat); // printf("info for receiving data is = %i \n",info); if (info !=MPI_SUCCESS) return info;
for (octave_idx_type i=0; i<nitem; i++) { // *LBNDA = *p; // LBNDA++; // p++; rmyNDA(i)=LBNDA[i]; imyNDA(i)=CLBNDA[i]; oa(i) = Complex (rmyNDA (i), imyNDA (i)); } ov = oa;
return(MPI_SUCCESS); }
int recv_float_complex_matrix(octave_value &ov,int source, int mytag){
OCTAVE_LOCAL_BUFFER(int, tanktag, 6); tanktag[0] = mytag; tanktag[1] = mytag+1; tanktag[2] = mytag+2; tanktag[3] = mytag+3; tanktag[4] = mytag+4; tanktag[5] = mytag+5;
int info; int nitem,nd; MPI_Status stat; dim_vector dv; // nitem is the total number of elements info = MPI_Recv((&nitem), 1,MPI_INT, source, tanktag[1] , MPI_COMM_WORLD,&stat); // printf("I have received number of elements %i \n",nitem); if (info !=MPI_SUCCESS) return info; // ndims is number of dimensions info = MPI_Recv((&nd), 1,MPI_INT, source, tanktag[2] ,
MPI_COMM_WORLD,&stat); // printf("I have received number of dimensions %i \n",nd); if (info !=MPI_SUCCESS) return info; // Now create contiguos datatype for dim vector dv.resize(nd); OCTAVE_LOCAL_BUFFER(int,dimV,nd); MPI_Datatype dimvec; MPI_Type_contiguous(nd,MPI_INT, &dimvec); MPI_Type_commit(&dimvec);
info = MPI_Recv((dimV), 1,dimvec, source, tanktag[3] , MPI_COMM_WORLD,&stat); if (info !=MPI_SUCCESS) return info;
// Now reverse the content of int vector into dim vector for (octave_idx_type i=0; i<nd; i++) { // printf("I am printing dimvector %i \n",i); dv(i) = dimV[i] ; }
FloatNDArray rmyNDA(dv); // for the real part FloatNDArray imyNDA(dv); // for the img part
FloatComplexNDArray oa (dv); /* Create->Delete on ret?!? */
float *p = rmyNDA.fortran_vec(); float *ip = imyNDA.fortran_vec(); OCTAVE_LOCAL_BUFFER(float,LBNDA,nitem); OCTAVE_LOCAL_BUFFER(float,CLBNDA,nitem);
// printf("BUFFER CREATED \n"); // Now create the contiguous derived datatype MPI_Datatype fortvec; MPI_Type_contiguous(nitem,MPI_DOUBLE, &fortvec); MPI_Type_commit(&fortvec);
info = MPI_Recv((LBNDA), 1,fortvec, source, tanktag[4] ,
MPI_COMM_WORLD,&stat); // printf("info for receiving data is = %i \n",info); if (info !=MPI_SUCCESS) return info;
info = MPI_Recv((CLBNDA), 1,fortvec, source, tanktag[5] , MPI_COMM_WORLD,&stat); // printf("info for receiving data is = %i \n",info); if (info !=MPI_SUCCESS) return info;
for (octave_idx_type i=0; i<nitem; i++) { // *LBNDA = *p; // LBNDA++; // p++; rmyNDA(i)=LBNDA[i]; imyNDA(i)=CLBNDA[i]; std::complex<float> c =
real(rmyNDA(i))+imag(imyNDA(i)); oa(i) = c; } ov = oa;
return(MPI_SUCCESS); }
int recv_sp_mat(octave_value &ov,int source, int mytag){ int info; /* int nr = m.rows(); int nc = m.cols (); int nnzm = m.nzmax ();*/ // tag[0] ----> type of octave_value // tag[1] ----> array of three elements 1) num of rows 2) number of columns 3) number of non zero elements // tag[2] ----> vector of rowindex // tag[3] ----> vector of columnindex // tag[5] ----> vector of number of non zero elements OCTAVE_LOCAL_BUFFER(int, tanktag,6); tanktag[0] = mytag; tanktag[1] = mytag+1; tanktag[2] = mytag+2; tanktag[3] = mytag+3; tanktag[4] = mytag+4; tanktag[5] =
mytag+5;
MPI_Status stat;
OCTAVE_LOCAL_BUFFER(int,s,3);
// Create a contiguous derived datatype MPI_Datatype sintsparse; MPI_Type_contiguous(3,MPI_INT, &sintsparse); MPI_Type_commit(&sintsparse);
// receive the sintsparse vector named s info = MPI_Recv(s, 1, sintsparse, source, tanktag[1], MPI_COMM_WORLD, &stat); if (info !=MPI_SUCCESS) return info;
// int appo1, appo2, appo3; // appo1 = s[0]; // appo2 = s[1]; // appo3 = s[2]; // // printf("appo 1 is %i \n",appo1); // printf("appo 2 is %i \n",appo2); // printf("appo 3 is %i \n",appo3);
SparseMatrix m(s[0],s[1],s[2]);
// Create a contiguous derived datatype for row index OCTAVE_LOCAL_BUFFER(int,sridx,s[2]); OCTAVE_LOCAL_BUFFER(double,sdata,s[2]); // Create a contiguous derived datatype for column index OCTAVE_LOCAL_BUFFER(int,scidx,s[1]+1);
MPI_Datatype rowindex; MPI_Type_contiguous(s[2],MPI_INT, &rowindex); MPI_Type_commit(&rowindex); MPI_Datatype datavect; MPI_Type_contiguous(s[2],MPI_DOUBLE, &datavect); MPI_Type_commit(&datavect); MPI_Datatype columnindex; MPI_Type_contiguous(s[1]+1,MPI_INT, &columnindex); MPI_Type_commit(&columnindex);
// Now receive the two vectors
// receive the vector with row indexes info = MPI_Recv(sridx,1,rowindex,source,tanktag[2],MPI_COMM_WORLD,&stat); // printf("Hope everything is fine here with ridx %i =\n",info); if (info !=MPI_SUCCESS) return info;
// receive the vector with column indexes info = MPI_Recv(scidx,1,columnindex,source,tanktag[3],MPI_COMM_WORLD, &stat); // printf("Hope everything is fine here with scidx %i
=\n",info); if (info !=MPI_SUCCESS) return info;
info = MPI_Recv(sdata,1,datavect,source,tanktag[4],MPI_COMM_WORLD,&stat); // printf("Hope everything is fine here with data vect %i =\n",info);
// int appoc; NDArray buf (dim_vector (m.capacity(), 1)); for (octave_idx_type i = 0; i < s[2]; i++) { m.ridx(i) = sridx[i]; m.data(i) = sdata[i]; buf(i) = sdata[i]; // appoc = m.ridx(i); // printf("apporow is %i \n",appoc); // printf("appodata is %d \n",sdata[i]); } for (octave_idx_type i = 0; i < s[1]+1; i++) { m.cidx(i) = scidx[i]; // appoc=m.cidx(i); // printf("appocol is %i \n",appoc); }
ov =
m; return(info);
}
//here ! int matrixes int recv_int8_matrix(octave_value &ov,int source, int mytag){
OCTAVE_LOCAL_BUFFER(int, tanktag, 5); tanktag[0] = mytag; tanktag[1] = mytag+1; tanktag[2] = mytag+2; tanktag[3] = mytag+3; tanktag[4] = mytag+4; int info; int nitem,nd; MPI_Status stat; dim_vector dv; // nitem is the total number of elements info = MPI_Recv((&nitem), 1,MPI_INT, source, tanktag[1] , MPI_COMM_WORLD,&stat); // printf("I have received number of elements %i \n",nitem); if (info !=MPI_SUCCESS) return info; // ndims is number of dimensions info =
MPI_Recv((&nd), 1,MPI_INT, source, tanktag[2] , MPI_COMM_WORLD,&stat); // printf("I have received number of dimensions %i \n",nd); if (info !=MPI_SUCCESS) return info; // Now create contiguos datatype for dim vector dv.resize(nd); OCTAVE_LOCAL_BUFFER(int,dimV,nd); MPI_Datatype dimvec; MPI_Type_contiguous(nd,MPI_INT, &dimvec); MPI_Type_commit(&dimvec);
info = MPI_Recv((dimV), 1,dimvec, source, tanktag[3] , MPI_COMM_WORLD,&stat); if (info !=MPI_SUCCESS) return info;
// Now reverse the content of int vector into dim vector for (octave_idx_type i=0; i<nd; i++) { // printf("I am printing dimvector %i \n",i); dv(i) =
dimV[i] ; } int8NDArray myNDA(dv); // double *p = myNDA.fortran_vec(); OCTAVE_LOCAL_BUFFER(octave_int8,LBNDA,nitem); // printf("BUFFER CREATED \n"); // Now create the contiguous derived datatype MPI_Datatype fortvec; MPI_Type_contiguous(nitem,MPI_BYTE, &fortvec); MPI_Type_commit(&fortvec);
info = MPI_Recv((LBNDA), 1,fortvec, source, tanktag[4] , MPI_COMM_WORLD,&stat); // printf("info for receiving data is = %i \n",info); if (info !=MPI_SUCCESS) return info; for (octave_idx_type i=0; i<nitem; i++) { // *LBNDA = *p; //
LBNDA++; // p++; myNDA(i)=LBNDA[i]; } ov = myNDA; // printf("info for receiving scalar matrix is = %i \n",info);
}
int recv_int16_matrix(octave_value &ov,int source, int mytag){
OCTAVE_LOCAL_BUFFER(int, tanktag, 5); tanktag[0] = mytag; tanktag[1] = mytag+1; tanktag[2] = mytag+2; tanktag[3] = mytag+3; tanktag[3] = mytag+4; int info; int nitem,nd; MPI_Status stat; dim_vector dv; // nitem is the total number of elements info = MPI_Recv((&nitem), 1,MPI_INT, source, tanktag[1] , MPI_COMM_WORLD,&stat); // printf("I have received number of elements %i
\n",nitem); if (info !=MPI_SUCCESS) return info; // ndims is number of dimensions info = MPI_Recv((&nd), 1,MPI_INT, source, tanktag[2] , MPI_COMM_WORLD,&stat); // printf("I have received number of dimensions %i \n",nd); if (info !=MPI_SUCCESS) return info; // Now create contiguos datatype for dim vector dv.resize(nd); OCTAVE_LOCAL_BUFFER(int,dimV,nd); MPI_Datatype dimvec; MPI_Type_contiguous(nd,MPI_INT, &dimvec); MPI_Type_commit(&dimvec);
info = MPI_Recv((dimV), 1,dimvec, source, tanktag[3] , MPI_COMM_WORLD,&stat); if (info !=MPI_SUCCESS) return info;
// Now
reverse the content of int vector into dim vector for (octave_idx_type i=0; i<nd; i++) { // printf("I am printing dimvector %i \n",i); dv(i) = dimV[i] ; } int16NDArray myNDA(dv); // double *p = myNDA.fortran_vec(); OCTAVE_LOCAL_BUFFER(octave_int16,LBNDA,nitem); // printf("BUFFER CREATED \n"); // Now create the contiguous derived datatype MPI_Datatype fortvec; MPI_Type_contiguous(nitem,MPI_SHORT, &fortvec); MPI_Type_commit(&fortvec);
info = MPI_Recv((LBNDA), 1,fortvec, source, tanktag[4] , MPI_COMM_WORLD,&stat); // printf("info for receiving data is = %i \n",info); if (info !=MPI_SUCCESS) return
info; for (octave_idx_type i=0; i<nitem; i++) { // *LBNDA = *p; // LBNDA++; // p++; myNDA(i)=LBNDA[i]; } ov = myNDA; // printf("info for receiving scalar matrix is = %i \n",info); return(info); }
int recv_int32_matrix(octave_value &ov,int source, int mytag){
OCTAVE_LOCAL_BUFFER(int, tanktag, 5); tanktag[0] = mytag; tanktag[1] = mytag+1; tanktag[2] = mytag+2; tanktag[3] = mytag+3; tanktag[3] = mytag+4;
int info; int nitem,nd; MPI_Status stat; dim_vector dv; // nitem is the total number of elements
info = MPI_Recv((&nitem), 1,MPI_INT, source, tanktag[1] , MPI_COMM_WORLD,&stat); // printf("I have received number of elements %i \n",nitem); if (info !=MPI_SUCCESS) return info; // ndims is number of dimensions info = MPI_Recv((&nd), 1,MPI_INT, source, tanktag[2] , MPI_COMM_WORLD,&stat); // printf("I have received number of dimensions %i \n",nd); if (info !=MPI_SUCCESS) return info; // Now create contiguos datatype for dim vector dv.resize(nd); OCTAVE_LOCAL_BUFFER(int,dimV,nd); MPI_Datatype dimvec; MPI_Type_contiguous(nd,MPI_INT, &dimvec);
MPI_Type_commit(&dimvec);
info = MPI_Recv((dimV), 1,dimvec, source, tanktag[3] , MPI_COMM_WORLD,&stat); if (info !=MPI_SUCCESS) return info;
// Now reverse the content of int vector into dim vector for (octave_idx_type i=0; i<nd; i++) { // printf("I am printing dimvector %i \n",i); dv(i) = dimV[i] ; } int32NDArray myNDA(dv); // double *p = myNDA.fortran_vec(); OCTAVE_LOCAL_BUFFER(octave_int32,LBNDA,nitem); // printf("BUFFER CREATED \n"); // Now create the contiguous derived datatype MPI_Datatype fortvec; MPI_Type_contiguous(nitem,MPI_INT, &fortvec); MPI_Type_commit(&fortvec);
info =
MPI_Recv((LBNDA), 1,fortvec, source, tanktag[4] , MPI_COMM_WORLD,&stat); // printf("info for receiving data is = %i \n",info); if (info !=MPI_SUCCESS) return info; for (octave_idx_type i=0; i<nitem; i++) { // *LBNDA = *p; // LBNDA++; // p++; myNDA(i)=LBNDA[i]; } ov = myNDA; // printf("info for receiving scalar matrix is = %i \n",info); return(info); }
int recv_int64_matrix(octave_value &ov,int source, int mytag){
OCTAVE_LOCAL_BUFFER(int, tanktag, 5); tanktag[0] = mytag; tanktag[1] = mytag+1; tanktag[2] = mytag+2; tanktag[3] =
mytag+3; tanktag[3] = mytag+4;
int info; int nitem,nd; MPI_Status stat; dim_vector dv; // nitem is the total number of elements info = MPI_Recv((&nitem), 1,MPI_INT, source, tanktag[1] , MPI_COMM_WORLD,&stat); // printf("I have received number of elements %i \n",nitem); if (info !=MPI_SUCCESS) return info; // ndims is number of dimensions info = MPI_Recv((&nd), 1,MPI_INT, source, tanktag[2] , MPI_COMM_WORLD,&stat); // printf("I have received number of dimensions %i \n",nd); if (info !=MPI_SUCCESS) return info; // Now create
contiguos datatype for dim vector dv.resize(nd); OCTAVE_LOCAL_BUFFER(int,dimV,nd); MPI_Datatype dimvec; MPI_Type_contiguous(nd,MPI_INT, &dimvec); MPI_Type_commit(&dimvec);
info = MPI_Recv((dimV), 1,dimvec, source, tanktag[3] , MPI_COMM_WORLD,&stat); if (info !=MPI_SUCCESS) return info;
// Now reverse the content of int vector into dim vector for (octave_idx_type i=0; i<nd; i++) { // printf("I am printing dimvector %i \n",i); dv(i) = dimV[i] ; } int64NDArray myNDA(dv); // double *p = myNDA.fortran_vec(); OCTAVE_LOCAL_BUFFER(octave_int64,LBNDA,nitem); // printf("BUFFER CREATED \n"); // Now create the contiguous derived
datatype MPI_Datatype fortvec; MPI_Type_contiguous(nitem,MPI_INT, &fortvec); MPI_Type_commit(&fortvec);
info = MPI_Recv((LBNDA), 1,fortvec, source, tanktag[4] , MPI_COMM_WORLD,&stat); // printf("info for receiving data is = %i \n",info); if (info !=MPI_SUCCESS) return info; for (octave_idx_type i=0; i<nitem; i++) { // *LBNDA = *p; // LBNDA++; // p++; myNDA(i)=LBNDA[i]; } ov = myNDA; // printf("info for receiving scalar matrix is = %i \n",info); return(info); }
int recv_uint64_matrix(octave_value
&ov,int source, int mytag){
OCTAVE_LOCAL_BUFFER(int, tanktag, 5); tanktag[0] = mytag; tanktag[1] = mytag+1; tanktag[2] = mytag+2; tanktag[3] = mytag+3; tanktag[3] = mytag+4;
int info; int nitem,nd; MPI_Status stat; dim_vector dv; // nitem is the total number of elements info = MPI_Recv((&nitem), 1,MPI_INT, source, tanktag[1] , MPI_COMM_WORLD,&stat); // printf("I have received number of elements %i \n",nitem); if (info !=MPI_SUCCESS) return info; // ndims is number of dimensions info = MPI_Recv((&nd), 1,MPI_INT, source, tanktag[2] ,
MPI_COMM_WORLD,&stat); // printf("I have received number of dimensions %i \n",nd); if (info !=MPI_SUCCESS) return info; // Now create contiguos datatype for dim vector dv.resize(nd); OCTAVE_LOCAL_BUFFER(int,dimV,nd); MPI_Datatype dimvec; MPI_Type_contiguous(nd,MPI_INT, &dimvec); MPI_Type_commit(&dimvec);
info = MPI_Recv((dimV), 1,dimvec, source, tanktag[3] , MPI_COMM_WORLD,&stat); if (info !=MPI_SUCCESS) return info;
// Now reverse the content of int vector into dim vector for (octave_idx_type i=0; i<nd; i++) { // printf("I am printing dimvector %i \n",i); dv(i) = dimV[i] ; }
uint64NDArray myNDA(dv); // double *p = myNDA.fortran_vec(); OCTAVE_LOCAL_BUFFER(octave_uint64,LBNDA,nitem); // printf("BUFFER CREATED \n"); // Now create the contiguous derived datatype MPI_Datatype fortvec; MPI_Type_contiguous(nitem,MPI_UNSIGNED_LONG_LONG, &fortvec); MPI_Type_commit(&fortvec);
info = MPI_Recv((LBNDA), 1,fortvec, source, tanktag[4] , MPI_COMM_WORLD,&stat); // printf("info for receiving data is = %i \n",info); if (info !=MPI_SUCCESS) return info; for (octave_idx_type i=0; i<nitem; i++) { // *LBNDA = *p; // LBNDA++; //
p++; myNDA(i)=LBNDA[i]; } ov = myNDA; // printf("info for receiving scalar matrix is = %i \n",info); return(info); }
int recv_uint8_matrix(octave_value &ov,int source, int mytag){
OCTAVE_LOCAL_BUFFER(int, tanktag, 5); tanktag[0] = mytag; tanktag[1] = mytag+1; tanktag[2] = mytag+2; tanktag[3] = mytag+3; tanktag[3] = mytag+4;
int info; int nitem,nd; MPI_Status stat; dim_vector dv; // nitem is the total number of elements info = MPI_Recv((&nitem), 1,MPI_INT, source, tanktag[1] , MPI_COMM_WORLD,&stat); // printf("I have received number of elements %i \n",nitem);
if (info !=MPI_SUCCESS) return info; // ndims is number of dimensions info = MPI_Recv((&nd), 1,MPI_INT, source, tanktag[2] , MPI_COMM_WORLD,&stat); // printf("I have received number of dimensions %i \n",nd); if (info !=MPI_SUCCESS) return info; // Now create contiguos datatype for dim vector dv.resize(nd); OCTAVE_LOCAL_BUFFER(int,dimV,nd); MPI_Datatype dimvec; MPI_Type_contiguous(nd,MPI_INT, &dimvec); MPI_Type_commit(&dimvec);
info = MPI_Recv((dimV), 1,dimvec, source, tanktag[3] , MPI_COMM_WORLD,&stat); if (info !=MPI_SUCCESS) return info;
// Now reverse the content of int vector into
dim vector for (octave_idx_type i=0; i<nd; i++) { // printf("I am printing dimvector %i \n",i); dv(i) = dimV[i] ; } uint8NDArray myNDA(dv); // double *p = myNDA.fortran_vec(); OCTAVE_LOCAL_BUFFER(octave_uint8,LBNDA,nitem); // printf("BUFFER CREATED \n"); // Now create the contiguous derived datatype MPI_Datatype fortvec; MPI_Type_contiguous(nitem,MPI_UNSIGNED_CHAR, &fortvec); MPI_Type_commit(&fortvec);
info = MPI_Recv((LBNDA), 1,fortvec, source, tanktag[4] , MPI_COMM_WORLD,&stat); // printf("info for receiving data is = %i \n",info); if (info !=MPI_SUCCESS) return info; for
(octave_idx_type i=0; i<nitem; i++) { // *LBNDA = *p; // LBNDA++; // p++; myNDA(i)=LBNDA[i]; } ov = myNDA; // printf("info for receiving scalar matrix is = %i \n",info); return(info); }
int recv_uint16_matrix(octave_value &ov,int source, int mytag){
OCTAVE_LOCAL_BUFFER(int, tanktag, 5); tanktag[0] = mytag; tanktag[1] = mytag+1; tanktag[2] = mytag+2; tanktag[3] = mytag+3; tanktag[3] = mytag+4;
int info; int nitem,nd; MPI_Status stat; dim_vector dv; // nitem is the total number of elements info
= MPI_Recv((&nitem), 1,MPI_INT, source, tanktag[1] , MPI_COMM_WORLD,&stat); // printf("I have received number of elements %i \n",nitem); if (info !=MPI_SUCCESS) return info; // ndims is number of dimensions info = MPI_Recv((&nd), 1,MPI_INT, source, tanktag[2] , MPI_COMM_WORLD,&stat); // printf("I have received number of dimensions %i \n",nd); if (info !=MPI_SUCCESS) return info; // Now create contiguos datatype for dim vector dv.resize(nd); OCTAVE_LOCAL_BUFFER(int,dimV,nd); MPI_Datatype dimvec; MPI_Type_contiguous(nd,MPI_INT, &dimvec); MPI_Type_commit(&dimvec);
info = MPI_Recv((dimV), 1,dimvec, source, tanktag[3] , MPI_COMM_WORLD,&stat); if (info !=MPI_SUCCESS) return info;
// Now reverse the content of int vector into dim vector for (octave_idx_type i=0; i<nd; i++) { // printf("I am printing dimvector %i \n",i); dv(i) = dimV[i] ; } uint16NDArray myNDA(dv); // double *p = myNDA.fortran_vec(); OCTAVE_LOCAL_BUFFER(octave_uint16,LBNDA,nitem); // printf("BUFFER CREATED \n"); // Now create the contiguous derived datatype MPI_Datatype fortvec; MPI_Type_contiguous(nitem,MPI_UNSIGNED_SHORT, &fortvec); MPI_Type_commit(&fortvec);
info = MPI_Recv((LBNDA),
1,fortvec, source, tanktag[4] , MPI_COMM_WORLD,&stat); // printf("info for receiving data is = %i \n",info); if (info !=MPI_SUCCESS) return info; for (octave_idx_type i=0; i<nitem; i++) { // *LBNDA = *p; // LBNDA++; // p++; myNDA(i)=LBNDA[i]; } ov = myNDA; // printf("info for receiving scalar matrix is = %i \n",info); return(info); }
int recv_uint32_matrix(octave_value &ov,int source, int mytag){
OCTAVE_LOCAL_BUFFER(int, tanktag, 5); tanktag[0] = mytag; tanktag[1] = mytag+1; tanktag[2] = mytag+2; tanktag[3] = mytag+3; tanktag[3] =
mytag+4;
int info; int nitem,nd; MPI_Status stat; dim_vector dv; // nitem is the total number of elements info = MPI_Recv((&nitem), 1,MPI_INT, source, tanktag[1] , MPI_COMM_WORLD,&stat); // printf("I have received number of elements %i \n",nitem); if (info !=MPI_SUCCESS) return info; // ndims is number of dimensions info = MPI_Recv((&nd), 1,MPI_INT, source, tanktag[2] , MPI_COMM_WORLD,&stat); // printf("I have received number of dimensions %i \n",nd); if (info !=MPI_SUCCESS) return info; // Now create contiguos datatype for dim
vector dv.resize(nd); OCTAVE_LOCAL_BUFFER(int,dimV,nd); MPI_Datatype dimvec; MPI_Type_contiguous(nd,MPI_INT, &dimvec); MPI_Type_commit(&dimvec);
info = MPI_Recv((dimV), 1,dimvec, source, tanktag[3] , MPI_COMM_WORLD,&stat); if (info !=MPI_SUCCESS) return info;
// Now reverse the content of int vector into dim vector for (octave_idx_type i=0; i<nd; i++) { // printf("I am printing dimvector %i \n",i); dv(i) = dimV[i] ; } uint32NDArray myNDA(dv); // double *p = myNDA.fortran_vec(); OCTAVE_LOCAL_BUFFER(octave_uint32,LBNDA,nitem); // printf("BUFFER CREATED \n"); // Now create the contiguous derived datatype MPI_Datatype
fortvec; MPI_Type_contiguous(nitem,MPI_UNSIGNED, &fortvec); MPI_Type_commit(&fortvec);
info = MPI_Recv((LBNDA), 1,fortvec, source, tanktag[4] , MPI_COMM_WORLD,&stat); // printf("info for receiving data is = %i \n",info); if (info !=MPI_SUCCESS) return info; for (octave_idx_type i=0; i<nitem; i++) { // *LBNDA = *p; // LBNDA++; // p++; myNDA(i)=LBNDA[i]; } ov = myNDA; // printf("info for receiving scalar matrix is = %i \n",info); return(info); }
int recv_complex_sp_mat(octave_value &ov,int source, int
mytag){ int info; /* int nr = m.rows(); int nc = m.cols (); int nnzm = m.nzmax ();*/ // tag[0] ----> type of octave_value // tag[1] ----> array of three elements 1) num of rows 2) number of columns 3) number of non zero elements // tag[2] ----> vector of rowindex // tag[3] ----> vector of columnindex // tag[5] ----> vector of number of non zero elements OCTAVE_LOCAL_BUFFER(int, tanktag,6); tanktag[0] = mytag; tanktag[1] = mytag+1; tanktag[2] = mytag+2; tanktag[3] = mytag+3; tanktag[4] = mytag+4; tanktag[5] = mytag+5;
MPI_Status stat;
OCTAVE_LOCAL_BUFFER(int,s,3);
// Create a contiguous derived datatype MPI_Datatype sintsparse; MPI_Type_contiguous(3,MPI_INT,
&sintsparse); MPI_Type_commit(&sintsparse);
// receive the sintsparse vector named s info = MPI_Recv(s, 1, sintsparse, source, tanktag[1], MPI_COMM_WORLD, &stat); if (info !=MPI_SUCCESS) return info;
// int appo1, appo2, appo3; // appo1 = s[0]; // appo2 = s[1]; // appo3 = s[2]; // // printf("appo 1 is %i \n",appo1); // printf("appo 2 is %i \n",appo2); // printf("appo 3 is %i \n",appo3);
SparseMatrix m(s[0],s[1],s[2]);
// Create a contiguous derived datatype for row index OCTAVE_LOCAL_BUFFER(int,sridx,s[2]); OCTAVE_LOCAL_BUFFER(double,sdata,s[2]); // Create a contiguous derived datatype for column index OCTAVE_LOCAL_BUFFER(int,scidx,s[1]+1); MPI_Datatype rowindex; MPI_Type_contiguous(s[2],MPI_INT, &rowindex); MPI_Type_commit(&rowindex); MPI_Datatype datavect; MPI_Type_contiguous(s[2],MPI_DOUBLE,
&datavect); MPI_Type_commit(&datavect); MPI_Datatype columnindex; MPI_Type_contiguous(s[1]+1,MPI_INT, &columnindex); MPI_Type_commit(&columnindex);
// Now receive the two vectors
// receive the vector with row indexes info = MPI_Recv(sridx,1,rowindex,source,tanktag[2],MPI_COMM_WORLD,&stat); // printf("Hope everything is fine here with ridx %i =\n",info); if (info !=MPI_SUCCESS) return info;
// receive the vector with column indexes info = MPI_Recv(scidx,1,columnindex,source,tanktag[3],MPI_COMM_WORLD, &stat); // printf("Hope everything is fine here with scidx %i =\n",info); if (info !=MPI_SUCCESS) return info;
info =
MPI_Recv(sdata,1,datavect,source,tanktag[4],MPI_COMM_WORLD,&stat); // printf("Hope everything is fine here with data vect %i =\n",info);
// int appoc; NDArray buf (dim_vector (m.capacity(), 1)); for (octave_idx_type i = 0; i < s[2]; i++) { m.ridx(i) = sridx[i]; m.data(i) = sdata[i]; buf(i) = sdata[i]; // appoc = m.ridx(i); // printf("apporow is %i \n",appoc); // printf("appodata is %d \n",sdata[i]); } for (octave_idx_type i = 0; i < s[1]+1; i++) { m.cidx(i) = scidx[i]; // appoc=m.cidx(i); // printf("appocol is %i \n",appoc); }
ov = m; return(info);
}
int recv_scalar( octave_value &ov, int source, int
mytag){ /* directly MPI_Recv it, */ /*-----------------------------*/ /* it's just a double value */ OCTAVE_LOCAL_BUFFER(int,tanktag,2); tanktag[0]=mytag; tanktag[1]=mytag+1; int info; MPI_Status stat; double d = ov.double_value(); info = MPI_Recv((&d), 1,MPI_DOUBLE, source, tanktag[1] , MPI_COMM_WORLD,&stat); ov =d; // printf("info for scalar is = %i \n",info); if (info !=MPI_SUCCESS) return info; return(MPI_SUCCESS); }
int recv_int8_scalar( octave_value &ov, int source, int mytag){ /* directly MPI_Recv it, */ /*-----------------------------*/ /* it's just a double value */ OCTAVE_LOCAL_BUFFER(int,tanktag,2); tanktag[0]=mytag;
tanktag[1]=mytag+1; int info; MPI_Status stat; octave_int8 d = ov.int8_scalar_value(); info = MPI_Recv((&d), 1,MPI_BYTE, source, tanktag[1] , MPI_COMM_WORLD,&stat); ov =d; // printf("info for scalar is = %i \n",info); if (info !=MPI_SUCCESS) return info; return(MPI_SUCCESS); }
int recv_int16_scalar( octave_value &ov, int source, int mytag){ /* directly MPI_Recv it, */ /*-----------------------------*/ /* it's just a double value */ OCTAVE_LOCAL_BUFFER(int,tanktag,2); tanktag[0]=mytag; tanktag[1]=mytag+1; int info; MPI_Status stat; octave_int16 d = ov.int16_scalar_value(); info = MPI_Recv((&d), 1,MPI_SHORT, source, tanktag[1] , MPI_COMM_WORLD,&stat); ov =d; // printf("info
for scalar is = %i \n",info); if (info !=MPI_SUCCESS) return info; return(MPI_SUCCESS); }
int recv_int32_scalar( octave_value &ov, int source, int mytag){ /* directly MPI_Recv it, */ /*-----------------------------*/ /* it's just a double value */ OCTAVE_LOCAL_BUFFER(int,tanktag,2); tanktag[0]=mytag; tanktag[1]=mytag+1; int info; MPI_Status stat; octave_int32 d = ov.int32_scalar_value(); info = MPI_Recv((&d), 1,MPI_INT, source, tanktag[1] , MPI_COMM_WORLD,&stat); ov =d; // printf("info for scalar is = %i \n",info); if (info !=MPI_SUCCESS) return info; return(MPI_SUCCESS); }
int recv_int64_scalar( octave_value &ov, int source, int mytag){ /* directly MPI_Recv it,
*/ /*-----------------------------*/ /* it's just a double value */ OCTAVE_LOCAL_BUFFER(int,tanktag,2); tanktag[0]=mytag; tanktag[1]=mytag+1; int info; MPI_Status stat; octave_int64 d = ov.int64_scalar_value(); info = MPI_Recv((&d), 1,MPI_LONG_LONG, source, tanktag[1] , MPI_COMM_WORLD,&stat); ov =d; // printf("info for scalar is = %i \n",info); if (info !=MPI_SUCCESS) return info; return(MPI_SUCCESS); }
int recv_uint64_scalar( octave_value &ov, int source, int mytag){ /* directly MPI_Recv it, */ /*-----------------------------*/ /* it's just a double value */ OCTAVE_LOCAL_BUFFER(int,tanktag,2); tanktag[0]=mytag; tanktag[1]=mytag+1; int info; MPI_Status
stat; octave_uint64 d = ov.uint64_scalar_value(); info = MPI_Recv((&d), 1,MPI_UNSIGNED_LONG_LONG, source, tanktag[1] , MPI_COMM_WORLD,&stat); ov =d; // printf("info for scalar is = %i \n",info); if (info !=MPI_SUCCESS) return info; return(MPI_SUCCESS); }
int recv_uint32_scalar( octave_value &ov, int source, int mytag){ /* directly MPI_Recv it, */ /*-----------------------------*/ /* it's just a double value */ OCTAVE_LOCAL_BUFFER(int,tanktag,2); tanktag[0]=mytag; tanktag[1]=mytag+1; int info; MPI_Status stat; octave_uint32 d = ov.uint32_scalar_value(); info = MPI_Recv((&d), 1,MPI_UNSIGNED, source, tanktag[1] , MPI_COMM_WORLD,&stat); ov =d; // printf("info for scalar is = %i
\n",info); if (info !=MPI_SUCCESS) return info; return(MPI_SUCCESS); }
int recv_uint16_scalar( octave_value &ov, int source, int mytag){ /* directly MPI_Recv it, */ /*-----------------------------*/ /* it's just a double value */ OCTAVE_LOCAL_BUFFER(int,tanktag,2); tanktag[0]=mytag; tanktag[1]=mytag+1; int info; MPI_Status stat; octave_uint16 d = ov.uint16_scalar_value(); info = MPI_Recv((&d), 1,MPI_UNSIGNED_SHORT, source, tanktag[1] , MPI_COMM_WORLD,&stat); ov =d; // printf("info for scalar is = %i \n",info); if (info !=MPI_SUCCESS) return info; return(MPI_SUCCESS); }
int recv_uint8_scalar( octave_value &ov, int source, int mytag){ /* directly MPI_Recv it,
*/ /*-----------------------------*/ /* it's just a double value */ OCTAVE_LOCAL_BUFFER(int,tanktag,2); tanktag[0]=mytag; tanktag[1]=mytag+1; int info; MPI_Status stat; octave_uint8 d = ov.uint8_scalar_value(); info = MPI_Recv((&d), 1,MPI_UNSIGNED_CHAR, source, tanktag[1] , MPI_COMM_WORLD,&stat); ov =d; // printf("info for scalar is = %i \n",info); if (info !=MPI_SUCCESS) return info; return(MPI_SUCCESS); }
int recv_complex_scalar( octave_value &ov, int source, int mytag){ /* directly MPI_Send it, */ /*-----------------------------*/ /* it's just a double value */ OCTAVE_LOCAL_BUFFER(int,tanktag,2); tanktag[0]=mytag; tanktag[1]=mytag+1;
OCTAVE_LOCAL_BUFFER(double,d,2);
int info; MPI_Status stat; info = MPI_Recv((&d), 2,MPI_DOUBLE, source, tanktag[1] , MPI_COMM_WORLD,&stat);
ov =Complex(d[0],d[1]);; // printf("info for scalar is = %i \n",info); if (info !=MPI_SUCCESS) return info; return(MPI_SUCCESS); }
int recv_complex_float_scalar( octave_value &ov, int source, int mytag){ /* directly MPI_Send it, */ /*-----------------------------*/ /* it's just a double value */ OCTAVE_LOCAL_BUFFER(int,tanktag,2); tanktag[0]=mytag; tanktag[1]=mytag+1;
OCTAVE_LOCAL_BUFFER(float,d,2);
int info; MPI_Status stat; info = MPI_Recv((&d), 2,MPI_FLOAT, source, tanktag[1] , MPI_COMM_WORLD,&stat);
std::complex<float> c = real(d[0])+imag(d[1]); ov =c;; // printf("info for scalar is = %i \n",info); if (info !=MPI_SUCCESS) return info; return(MPI_SUCCESS); }
int recv_float_scalar( octave_value &ov, int source, int mytag){ /* directly MPI_Recv it, */ /*-----------------------------*/ /* it's just a Float value */
OCTAVE_LOCAL_BUFFER(int,tanktag,2); tanktag[0] = mytag; tanktag[1] = mytag+1;
int info; MPI_Status stat; float d = ov.float_value(); info = MPI_Recv((&d), 1,MPI_FLOAT, source, tanktag[1] , MPI_COMM_WORLD,&stat); ov =d; // printf("info for scalar is = %i \n",info); if (info !=MPI_SUCCESS) return info; return(MPI_SUCCESS); }
int
recv_class(octave_value &ov, int source, int mytag ){ /* varname-strlength 1st, dims[ndim] */ /*----------------------------------*/ /* and then appropriate specific info */ int t_id,n; // int mytag = cvtag(0); MPI_Status status; printf("1-> source =%i\n",source); printf("2-> tag for id =%i\n",mytag); int info = MPI_Recv(&t_id,1, MPI_INT, source,mytag,MPI_COMM_WORLD,&status);
printf(" I have received t_id =%i\n",t_id);
if (info !=MPI_SUCCESS) return info;
switch (t_id) {
case ov_scalar: return(recv_scalar (ov,source,mytag)); case ov_int8_scalar: return(recv_int8_scalar (ov,source,mytag)); case ov_int16_scalar: return(recv_int16_scalar
(ov,source,mytag)); case ov_int32_scalar: return(recv_int32_scalar (ov,source,mytag)); case ov_int64_scalar: return(recv_int64_scalar (ov,source,mytag)); case ov_uint8_scalar: return(recv_uint8_scalar (ov,source,mytag)); case ov_uint16_scalar: return(recv_uint16_scalar (ov,source,mytag)); case ov_uint32_scalar: return(recv_uint32_scalar (ov,source,mytag)); case ov_uint64_scalar: return(recv_uint64_scalar (ov,source,mytag)); case ov_float_scalar: return(recv_float_scalar(ov,source,mytag)); case ov_complex_scalar: return(recv_complex_scalar (ov,source,mytag)); case ov_float_complex_scalar:
return(recv_complex_float_scalar(ov,source,mytag));
case ov_string: return(recv_string (ov,source,mytag)); case ov_matrix: return(recv_matrix (ov,source,mytag)); case ov_complex_matrix: return(recv_complex_matrix(ov,source,mytag)); case ov_int8_matrix: return(recv_int8_matrix (ov,source,mytag)); case ov_int16_matrix: return(recv_int16_matrix (ov,source,mytag)); case ov_int32_matrix: return(recv_int32_matrix (ov,source,mytag)); case ov_int64_matrix: return(recv_int64_matrix (ov,source,mytag));
case ov_uint8_matrix: return(recv_uint8_matrix (ov,source,mytag)); case ov_uint16_matrix:
return(recv_uint16_matrix (ov,source,mytag)); case ov_uint32_matrix: return(recv_uint32_matrix (ov,source,mytag)); case ov_uint64_matrix: return(recv_uint64_matrix (ov,source,mytag));
case ov_float_matrix: return(recv_float_matrix (ov,source,mytag)); case ov_float_complex_matrix: return(recv_float_complex_matrix (ov,source,mytag)); case ov_sparse_matrix: return(recv_sp_mat(ov,source,mytag)); case ov_sparse_complex_matrix: return(recv_complex_sp_mat(ov,source,mytag)); case ov_unknown: printf("MPI_Recv: unknown class\n"); return(MPI_ERR_UNKNOWN );
case ov_class:
case ov_list: case ov_cs_list: case ov_magic_colon: case ov_built_in_function: case ov_user_defined_function: case ov_dynamically_linked_function: case ov_function_handle: case ov_inline_function: case ov_float_diagonal_matrix: case ov_float_complex_diagonal_matrix: case ov_diagonal_matrix: case ov_complex_diagonal_matrix: case ov_permutation_matrix: case ov_null_matrix:
case ov_null_string: case ov_null_sq_string:
default: printf("MPI_Recv: unsupported class %s\n", ov.type_name().c_str()); return(MPI_ERR_UNKNOWN ); } }
DEFUN_DLD(MPI_Recv,args,, "MPI_Recv sends almost any Octave datatype into contiguous memory using openmpi library even over an hetherogeneous cluster i.e 32 bits CPUs and 64 bits CPU \n") { octave_value_list retval; // Check if MPI environment is initialized // first argument rank of the receiver // for tag we use the type of
octave_value ( see enum above ) // if alternative comunicator is provided select predefined MPI_COMM_WORLD // Put the rank of the receiver into a columnvector int source = args(0).int_value(); if (error_state) { error ("expecting first argument to be an integer"); return retval; } int mytag = args(1).int_value(); if (error_state) { error ("expecting second argument to be a column vector"); return retval; }/* if (mytags.numel() < 3) { error ("expecting second argument having more than two elements"); return
retval; }*/ octave_value result; int info = recv_class (result,source, mytag ); retval(0)=info; retval(1)=result; return retval; }
Now I may show you some simple helloworld octave scripts if not(MPI_Initialized) info = MPI_Init(); end
[info my_rank] = MPI_Comm_rank(); [info p ] = MPI_Comm_size(); mytag = 48;
message=""; if (my_rank != 0) message = sprintf('Greetings from process: %d!',my_rank); dest = 0; % rankvect is the vector containing the list of rank destination process rankvect = 0; [info] =
MPI_Send(message,rankvect,mytag); info else for source = 1:p-1 disp("We are at rank 0 that is master etc.."); [info message] = MPI_Recv(source,mytag); printf('%s\n', message); endfor end
if not(MPI_Finalized) info = MPI_Finalize(); end
or if not(MPI_Initialized) info = MPI_Init(); end
[info my_rank] = MPI_Comm_rank(); [info p ] = MPI_Comm_size(); mytag = 48;
if (my_rank != 0) % Generate a random matrix
message=rand(90,90); % load message % dest = 0; % rankvect is the vector containing the list of rank destination process rankvect = 0; [info] = MPI_Send(message,rankvect,mytag); else for source = 1:p-1 disp("We are at rank 0 that is master etc.."); [info messager] = MPI_Recv(source,mytag); disp("Rank 0 is the master receiving ... :"); if (info == true) disp('OK!');
endif endfor end
if not(MPI_Finalized) info = MPI_Finalize(); end
or with a sparse matrix if not(MPI_Initialized) info = MPI_Init(); end
[info my_rank] = MPI_Comm_rank(); [info p ] = MPI_Comm_size(); % // tag[0] ----> type of octave_value % // tag[1] ----> array of three elements 1) num of rows 2) number of columns 3) number of non zero elements % // tag[2] ----> vector of rowindex % // tag[3] ----> vector of columnindex % // tag[4] ----> vector of non zero elements
mytag = 48;
M=5; N=5; D=0.9; % message = sprand (M, N, D); load message
if
(my_rank != 0) dest = 0; % rankvect is the vector containing the list of rank destination process rankvect(1,1) = 0; [info] = MPI_Send(message,rankvect,mytag); disp("This is flag for sending the message --") info else for source = 1:p-1 messager=''; disp("We are at rank 0 that is master etc.."); [info messager] = MPI_Recv(source,mytag); disp("Rank 0 is the master receiving ... :"); if
(messager/message) disp('OK!'); endif messager endfor end
if not(MPI_Finalized) info = MPI_Finalize(); end
You could run the examples with mpirun -np 6 octave --eval testhello
I would try to implement MPI_Probe MPI_Iprobe and MPI_ISend and MPI_IRecv using the same strategy implemented above. Please let me know your opinion.
Thanks a lot Riccardo Corradini
--- Mer 4/11/09, Søren Hauberg <soren@...> ha scritto:
Da: Søren Hauberg <soren@...> Oggetto: Re: [OctDev]
Contribution to Octave-forge with a simple Open-MPI Package A: "Riccardo Corradini" <riccardocorradini@...> Cc: octave-dev@... Data: Mercoledì 4 novembre 2009, 15:45
Hi, tir, 03 11 2009 kl. 12:25 +0000, skrev Riccardo Corradini: > for my econometric computations I have built a simple package that > uses the concept of MPI-Derived datatypes > ( see http://static.msi.umn.edu/tutorial/scicomp/general/MPI/content6.html ) to spread octave_values objects over octave instances. > This package gets a lot of ideas from MPI_TB for octave but is > simpler, doesn't use MPI_PACK and MPI_UNPACK and is very easy to > update with newer versions of Octave ( I tested it with octave 3.2.3 , > but I am sure it will work also with
development-version). Cool! I'm currently not using Octave on a cluster, so I don't have any MPI experience. Is your code general-purpose or is it designed for econometrics? > Before doing that I would like to submit the functions to this list to > know your opinions, warnings, improvements and some hints on how to > build an octave forge package with open-mpi bindings. As I said, I don't have any MPI experience, but feel free to send the code to this list. I don't mind given it a quick look to see if I catch anything, and perhaps others will provide their thoughts as well. Søren
|