almost finised mpi migration
This commit is contained in:
parent
acb40dea35
commit
3b9f0ab14e
@ -3,7 +3,8 @@ AUTOMAKE_OPTIONS = nostdinc
|
|||||||
AM_CPPFLAGS = \
|
AM_CPPFLAGS = \
|
||||||
-I$(top_builddir)/include \
|
-I$(top_builddir)/include \
|
||||||
-I$(top_srcdir)/include \
|
-I$(top_srcdir)/include \
|
||||||
-I$(includedir)
|
-I$(includedir) \
|
||||||
|
-DDEFAULT_MODDIR=\"$(libdir)/qse\"
|
||||||
|
|
||||||
#####################################################################3
|
#####################################################################3
|
||||||
|
|
||||||
@ -18,4 +19,3 @@ if WCHAR
|
|||||||
qseawk_LDADD += $(UNICOWS_LIBS)
|
qseawk_LDADD += $(UNICOWS_LIBS)
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -254,7 +254,8 @@ AUTOMAKE_OPTIONS = nostdinc
|
|||||||
AM_CPPFLAGS = \
|
AM_CPPFLAGS = \
|
||||||
-I$(top_builddir)/include \
|
-I$(top_builddir)/include \
|
||||||
-I$(top_srcdir)/include \
|
-I$(top_srcdir)/include \
|
||||||
-I$(includedir)
|
-I$(includedir) \
|
||||||
|
-DDEFAULT_MODDIR=\"$(libdir)/qse\"
|
||||||
|
|
||||||
qseawk_SOURCES = awk.c
|
qseawk_SOURCES = awk.c
|
||||||
qseawk_LDFLAGS = -L../../lib/awk -L../../lib/cmn -L$(libdir)
|
qseawk_LDFLAGS = -L../../lib/awk -L../../lib/cmn -L$(libdir)
|
||||||
|
@ -966,7 +966,7 @@ static int awk_main (int argc, qse_char_t* argv[])
|
|||||||
qse_awk_parsestd_t psout;
|
qse_awk_parsestd_t psout;
|
||||||
qse_mmgr_t* mmgr = QSE_MMGR_GETDFL();
|
qse_mmgr_t* mmgr = QSE_MMGR_GETDFL();
|
||||||
|
|
||||||
memset (&arg, 0, QSE_SIZEOF(arg));
|
qse_memset (&arg, 0, QSE_SIZEOF(arg));
|
||||||
arg.icf.mmgr = mmgr;
|
arg.icf.mmgr = mmgr;
|
||||||
|
|
||||||
i = comparg (argc, argv, &arg);
|
i = comparg (argc, argv, &arg);
|
||||||
@ -1129,9 +1129,88 @@ oops:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct mpi_t
|
||||||
|
{
|
||||||
|
void* h;
|
||||||
|
int (*i) (int argc, qse_achar_t* argv[]);
|
||||||
|
void (*f) (void);
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct mpi_t mpi_t;
|
||||||
|
|
||||||
|
static void open_mpi (mpi_t* mpi, int argc, qse_achar_t* argv[])
|
||||||
|
{
|
||||||
|
lt_dladvise adv;
|
||||||
|
|
||||||
|
qse_memset (mpi, 0, QSE_SIZEOF(*mpi));
|
||||||
|
|
||||||
|
#if defined(USE_LTDL)
|
||||||
|
|
||||||
|
#if defined(QSE_ACHAR_IS_MCHAR)
|
||||||
|
if (qse_mbscmp (qse_mbsbasename(argv[0]), QSE_MT("qseawkmp")) != 0 &&
|
||||||
|
qse_mbscmp (qse_mbsbasename(argv[0]), QSE_MT("qseawkmpi")) != 0) return;
|
||||||
|
#else
|
||||||
|
if (qse_wcscmp (qse_wcsbasename(argv[0]), QSE_WT("qseawkmp")) != 0 &&
|
||||||
|
qse_wcscmp (qse_wcsbasename(argv[0]), QSE_WT("qseawkmpi")) != 0) return;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (lt_dlinit () != 0) return;
|
||||||
|
|
||||||
|
if (lt_dladvise_init (&adv) != 0) goto oops;
|
||||||
|
|
||||||
|
/* If i don't set the global option, loading may end up with an error
|
||||||
|
* like this depending on your MPI library.
|
||||||
|
*
|
||||||
|
* symbol lookup error: /usr/lib/openmpi/lib/openmpi/mca_paffinity_linux.so: undefined symbol: mca_base_param_reg_int
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (lt_dladvise_global (&adv) != 0 || lt_dladvise_ext (&adv) != 0)
|
||||||
|
{
|
||||||
|
lt_dladvise_destroy (&adv);
|
||||||
|
goto oops;
|
||||||
|
}
|
||||||
|
|
||||||
|
mpi->h = lt_dlopenadvise (DEFAULT_MODDIR "/libawkmpi", adv);
|
||||||
|
lt_dladvise_destroy (&adv);
|
||||||
|
|
||||||
|
if (mpi->h)
|
||||||
|
{
|
||||||
|
mpi->i = lt_dlsym (mpi->h, "mpi_init");
|
||||||
|
mpi->f = lt_dlsym (mpi->h, "mpi_fini");
|
||||||
|
|
||||||
|
if (mpi->i == QSE_NULL ||
|
||||||
|
mpi->f == QSE_NULL ||
|
||||||
|
mpi->i (argc, argv) <= -1)
|
||||||
|
{
|
||||||
|
lt_dlclose (mpi->h);
|
||||||
|
mpi->h = QSE_NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
oops:
|
||||||
|
lt_dlexit ();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void close_mpi (mpi_t* mpi)
|
||||||
|
{
|
||||||
|
if (mpi->h)
|
||||||
|
{
|
||||||
|
#if defined(USE_LTDL)
|
||||||
|
mpi->f ();
|
||||||
|
lt_dlclose (mpi->h);
|
||||||
|
mpi->h = QSE_NULL;
|
||||||
|
lt_dlexit ();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int qse_main (int argc, qse_achar_t* argv[])
|
int qse_main (int argc, qse_achar_t* argv[])
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
mpi_t mpi;
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
char locale[100];
|
char locale[100];
|
||||||
@ -1162,15 +1241,11 @@ int qse_main (int argc, qse_achar_t* argv[])
|
|||||||
qse_setdflcmgrbyid (QSE_CMGR_SLMB);
|
qse_setdflcmgrbyid (QSE_CMGR_SLMB);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(USE_LTDL)
|
open_mpi (&mpi, argc, argv);
|
||||||
lt_dlinit ();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ret = qse_runmain (argc, argv, awk_main);
|
ret = qse_runmain (argc, argv, awk_main);
|
||||||
|
|
||||||
#if defined(USE_LTDL)
|
close_mpi (&mpi);
|
||||||
lt_dlexit ();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
WSACleanup ();
|
WSACleanup ();
|
||||||
|
@ -1045,7 +1045,7 @@ enum qse_awk_trait_t
|
|||||||
|
|
||||||
QSE_AWK_MODERN =
|
QSE_AWK_MODERN =
|
||||||
QSE_AWK_CLASSIC | QSE_AWK_EXTRAKWS | QSE_AWK_MAPTOVAR |
|
QSE_AWK_CLASSIC | QSE_AWK_EXTRAKWS | QSE_AWK_MAPTOVAR |
|
||||||
QSE_AWK_RWPIPE | QSE_AWK_REXBOUND | QSE_AWK_TOLERANT
|
QSE_AWK_RWPIPE | QSE_AWK_TOLERANT
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------------ */
|
||||||
|
@ -45,6 +45,7 @@
|
|||||||
#else
|
#else
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
# include <ltdl.h>
|
# include <ltdl.h>
|
||||||
|
# define USE_LTDL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef QSE_HAVE_CONFIG_H
|
#ifndef QSE_HAVE_CONFIG_H
|
||||||
@ -134,8 +135,7 @@ int StdAwk::open ()
|
|||||||
this->gbl_environ <= -1 ||
|
this->gbl_environ <= -1 ||
|
||||||
this->gbl_procinfo <= -1)
|
this->gbl_procinfo <= -1)
|
||||||
{
|
{
|
||||||
Awk::close ();
|
goto oops;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addFunction (QSE_T("rand"), 0, 0, (FunctionHandler)&StdAwk::rand, 0) <= -1 ||
|
if (addFunction (QSE_T("rand"), 0, 0, (FunctionHandler)&StdAwk::rand, 0) <= -1 ||
|
||||||
@ -145,10 +145,17 @@ int StdAwk::open ()
|
|||||||
addFunction (QSE_T("setioattr"), 3, 3, (FunctionHandler)&StdAwk::setioattr, QSE_AWK_RIO) <= -1 ||
|
addFunction (QSE_T("setioattr"), 3, 3, (FunctionHandler)&StdAwk::setioattr, QSE_AWK_RIO) <= -1 ||
|
||||||
addFunction (QSE_T("getioattr"), 2, 2, (FunctionHandler)&StdAwk::getioattr, QSE_AWK_RIO) <= -1)
|
addFunction (QSE_T("getioattr"), 2, 2, (FunctionHandler)&StdAwk::getioattr, QSE_AWK_RIO) <= -1)
|
||||||
{
|
{
|
||||||
Awk::close ();
|
goto oops;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(USE_LTDL)
|
||||||
|
/* lt_dlinit() can be called more than once and
|
||||||
|
* lt_dlexit() shuts down libltdl if it's called as many times as
|
||||||
|
* corresponding lt_dlinit(). so it's safe to call lt_dlinit()
|
||||||
|
* and lt_dlexit() at the library level. */
|
||||||
|
if (lt_dlinit() != 0) goto oops;
|
||||||
|
#endif
|
||||||
|
|
||||||
qse_ntime_t now;
|
qse_ntime_t now;
|
||||||
|
|
||||||
this->seed = (qse_gettime(&now) <= -1)? 0u: (long_t)now;
|
this->seed = (qse_gettime(&now) <= -1)? 0u: (long_t)now;
|
||||||
@ -160,6 +167,10 @@ int StdAwk::open ()
|
|||||||
|
|
||||||
this->cmgrtab_inited = false;
|
this->cmgrtab_inited = false;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
oops:
|
||||||
|
Awk::close ();
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StdAwk::close ()
|
void StdAwk::close ()
|
||||||
@ -171,8 +182,13 @@ void StdAwk::close ()
|
|||||||
this->cmgrtab_inited = false;
|
this->cmgrtab_inited = false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
clearConsoleOutputs ();
|
clearConsoleOutputs ();
|
||||||
Awk::close ();
|
Awk::close ();
|
||||||
|
|
||||||
|
#if defined(USE_LTDL)
|
||||||
|
lt_dlexit ();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
StdAwk::Run* StdAwk::parse (Source& in, Source& out)
|
StdAwk::Run* StdAwk::parse (Source& in, Source& out)
|
||||||
|
@ -827,14 +827,14 @@ void qse_awk_rtx_close (qse_awk_rtx_t* rtx)
|
|||||||
qse_awk_rtx_ecb_t* ecb;
|
qse_awk_rtx_ecb_t* ecb;
|
||||||
struct module_fini_ctx_t mfc;
|
struct module_fini_ctx_t mfc;
|
||||||
|
|
||||||
for (ecb = rtx->ecb; ecb; ecb = ecb->next)
|
|
||||||
if (ecb->close) ecb->close (rtx);
|
|
||||||
|
|
||||||
mfc.limit = 0;
|
mfc.limit = 0;
|
||||||
mfc.count = 0;
|
mfc.count = 0;
|
||||||
mfc.rtx = rtx;
|
mfc.rtx = rtx;
|
||||||
qse_rbt_walk (rtx->awk->modtab, fini_module, &mfc);
|
qse_rbt_walk (rtx->awk->modtab, fini_module, &mfc);
|
||||||
|
|
||||||
|
for (ecb = rtx->ecb; ecb; ecb = ecb->next)
|
||||||
|
if (ecb->close) ecb->close (rtx);
|
||||||
|
|
||||||
/* NOTE:
|
/* NOTE:
|
||||||
* the close callbacks are called before data in rtx
|
* the close callbacks are called before data in rtx
|
||||||
* is destroyed. if the destruction count on any data
|
* is destroyed. if the destruction count on any data
|
||||||
|
@ -49,6 +49,7 @@
|
|||||||
#else
|
#else
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
# include <ltdl.h>
|
# include <ltdl.h>
|
||||||
|
# define USE_LTDL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef QSE_HAVE_CONFIG_H
|
#ifndef QSE_HAVE_CONFIG_H
|
||||||
@ -421,6 +422,9 @@ qse_awk_t* qse_awk_openstd (qse_size_t xtnsize)
|
|||||||
static void fini_xtn (qse_awk_t* awk)
|
static void fini_xtn (qse_awk_t* awk)
|
||||||
{
|
{
|
||||||
/* nothing to do */
|
/* nothing to do */
|
||||||
|
#if defined(USE_LTDL)
|
||||||
|
lt_dlexit ();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clear_xtn (qse_awk_t* awk)
|
static void clear_xtn (qse_awk_t* awk)
|
||||||
@ -447,6 +451,7 @@ qse_awk_t* qse_awk_openstdwithmmgr (qse_mmgr_t* mmgr, qse_size_t xtnsize)
|
|||||||
prm.math.log10 = custom_awk_log10;
|
prm.math.log10 = custom_awk_log10;
|
||||||
prm.math.exp = custom_awk_exp;
|
prm.math.exp = custom_awk_exp;
|
||||||
prm.math.sqrt = custom_awk_sqrt;
|
prm.math.sqrt = custom_awk_sqrt;
|
||||||
|
|
||||||
prm.modopen = custom_awk_modopen;
|
prm.modopen = custom_awk_modopen;
|
||||||
prm.modclose = custom_awk_modclose;
|
prm.modclose = custom_awk_modclose;
|
||||||
prm.modsym = custom_awk_modsym;
|
prm.modsym = custom_awk_modsym;
|
||||||
@ -460,17 +465,25 @@ qse_awk_t* qse_awk_openstdwithmmgr (qse_mmgr_t* mmgr, qse_size_t xtnsize)
|
|||||||
|
|
||||||
/* add intrinsic global variables and functions */
|
/* add intrinsic global variables and functions */
|
||||||
if (add_globals(awk) <= -1 ||
|
if (add_globals(awk) <= -1 ||
|
||||||
add_functions (awk) <= -1)
|
add_functions (awk) <= -1) goto oops;
|
||||||
{
|
|
||||||
qse_awk_close (awk);
|
#if defined(USE_LTDL)
|
||||||
return QSE_NULL;
|
/* lt_dlinit() can be called more than once and
|
||||||
}
|
* lt_dlexit() shuts down libltdl if it's called as many times as
|
||||||
|
* corresponding lt_dlinit(). so it's safe to call lt_dlinit()
|
||||||
|
* and lt_dlexit() at the library level. */
|
||||||
|
if (lt_dlinit () != 0) goto oops;
|
||||||
|
#endif
|
||||||
|
|
||||||
xtn->ecb.close = fini_xtn;
|
xtn->ecb.close = fini_xtn;
|
||||||
xtn->ecb.clear = clear_xtn;
|
xtn->ecb.clear = clear_xtn;
|
||||||
qse_awk_pushecb (awk, &xtn->ecb);
|
qse_awk_pushecb (awk, &xtn->ecb);
|
||||||
|
|
||||||
return awk;
|
return awk;
|
||||||
|
|
||||||
|
oops:
|
||||||
|
if (awk) qse_awk_close (awk);
|
||||||
|
return QSE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* qse_awk_getxtnstd (qse_awk_t* awk)
|
void* qse_awk_getxtnstd (qse_awk_t* awk)
|
||||||
|
@ -1,7 +1,38 @@
|
|||||||
#include <qse/awk/std.h>
|
#include <qse/awk/awk.h>
|
||||||
#include <qse/cmn/str.h>
|
#include <qse/cmn/str.h>
|
||||||
|
#include <qse/cmn/main.h>
|
||||||
|
|
||||||
|
#if defined(HAVE_MPI)
|
||||||
# include <mpi.h>
|
# include <mpi.h>
|
||||||
|
#else
|
||||||
|
# error this module needs mpi
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int fnc_size (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
|
||||||
|
{
|
||||||
|
qse_awk_val_t* retv;
|
||||||
|
int rank;
|
||||||
|
|
||||||
|
MPI_Comm_size (MPI_COMM_WORLD, &rank);
|
||||||
|
retv = qse_awk_rtx_makeintval (rtx, rank);
|
||||||
|
if (retv == QSE_NULL) return -1;
|
||||||
|
|
||||||
|
qse_awk_rtx_setretval (rtx, retv);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fnc_rank (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
|
||||||
|
{
|
||||||
|
qse_awk_val_t* retv;
|
||||||
|
int rank;
|
||||||
|
|
||||||
|
MPI_Comm_rank (MPI_COMM_WORLD, &rank);
|
||||||
|
retv = qse_awk_rtx_makeintval (rtx, rank);
|
||||||
|
if (retv == QSE_NULL) return -1;
|
||||||
|
|
||||||
|
qse_awk_rtx_setretval (rtx, retv);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int fnc_hash (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
|
static int fnc_hash (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
|
||||||
{
|
{
|
||||||
@ -27,10 +58,13 @@ static int fnc_assign (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
|
|||||||
if (rx >= 0)
|
if (rx >= 0)
|
||||||
{
|
{
|
||||||
qse_awk_nrflt_t nrflt;
|
qse_awk_nrflt_t nrflt;
|
||||||
|
int size, rank;
|
||||||
|
|
||||||
|
MPI_Comm_size (MPI_COMM_WORLD, &size);
|
||||||
|
MPI_Comm_rank (MPI_COMM_WORLD, &rank);
|
||||||
nrflt.limit = limit;
|
nrflt.limit = limit;
|
||||||
// nrflt.size = rxtn->size;
|
nrflt.size = size;
|
||||||
// nrflt.rank = rxtn->rank;
|
nrflt.rank = rank;
|
||||||
qse_awk_rtx_setnrflt (rtx, &nrflt);
|
qse_awk_rtx_setnrflt (rtx, &nrflt);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,15 +75,12 @@ static int fnc_assign (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
static int fnc_reduce (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
|
static int fnc_reduce (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
|
||||||
{
|
{
|
||||||
qse_size_t nargs;
|
qse_awk_val_t* retv;
|
||||||
qse_awk_val_t* tmp, * a0, * a1;
|
|
||||||
qse_long_t opidx, lv;
|
qse_long_t opidx, lv;
|
||||||
qse_flt_t rv;
|
qse_flt_t rv;
|
||||||
int n;
|
int n;
|
||||||
rxtn_t* rxtn;
|
|
||||||
|
|
||||||
static MPI_Op optab[] =
|
static MPI_Op optab[] =
|
||||||
{
|
{
|
||||||
@ -61,55 +92,40 @@ static int fnc_reduce (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
|
|||||||
MPI_LOR
|
MPI_LOR
|
||||||
};
|
};
|
||||||
|
|
||||||
rxtn = (rxtn_t*) qse_awk_rtx_getxtnstd (rtx);
|
if (qse_awk_rtx_valtolong (rtx, qse_awk_rtx_getarg (rtx, 1), &opidx) <= -1 ||
|
||||||
|
(opidx < 0 || opidx >= QSE_COUNTOF(optab)) ||
|
||||||
nargs = qse_awk_rtx_getnargs (rtx);
|
(n = qse_awk_rtx_valtonum (rtx, qse_awk_rtx_getarg (rtx, 0), &lv, &rv)) <= -1) goto softfail;
|
||||||
QSE_ASSERT (nargs == 2);
|
|
||||||
|
|
||||||
a0 = qse_awk_rtx_getarg (rtx, 0);
|
|
||||||
a1 = qse_awk_rtx_getarg (rtx, 1);
|
|
||||||
|
|
||||||
if (qse_awk_rtx_valtolong (rtx, a1, &opidx) <= -1) return -1;
|
|
||||||
if (opidx < 0 || opidx >= QSE_COUNTOF(optab)) goto softfail;
|
|
||||||
if ((n = qse_awk_rtx_valtonum (rtx, a0, &lv, &rv)) <= -1) return -1;
|
|
||||||
|
|
||||||
/* TODO: determine it to be MPI_LONG or MPI_INT, OR MPI_LONG_LONG_INT depending on the size of qse_long_t */
|
/* TODO: determine it to be MPI_LONG or MPI_INT, OR MPI_LONG_LONG_INT depending on the size of qse_long_t */
|
||||||
/* TODO: how to tell normal -1 from the soft failure??? */
|
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
{
|
{
|
||||||
qse_long_t lout;
|
qse_long_t lout;
|
||||||
if (MPI_Allreduce (&lv, &lout, 1, MPI_LONG_LONG_INT, optab[opidx], rxtn->comm) != MPI_SUCCESS) goto softfail;
|
if (MPI_Allreduce (&lv, &lout, 1, MPI_LONG_LONG_INT, optab[opidx], MPI_COMM_WORLD) != MPI_SUCCESS) goto softfail;
|
||||||
tmp = qse_awk_rtx_makeintval (rtx, lout);
|
retv = qse_awk_rtx_makeintval (rtx, lout);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
qse_flt_t fout;
|
qse_flt_t fout;
|
||||||
if (MPI_Allreduce (&rv, &fout, 1, MPI_LONG_DOUBLE, optab[opidx], rxtn->comm) != MPI_SUCCESS) goto softfail;
|
if (MPI_Allreduce (&rv, &fout, 1, MPI_LONG_DOUBLE, optab[opidx], MPI_COMM_WORLD) != MPI_SUCCESS) goto softfail;
|
||||||
tmp = qse_awk_rtx_makefltval (rtx, fout);
|
retv = qse_awk_rtx_makefltval (rtx, fout);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tmp == QSE_NULL) return -1;
|
if (retv == QSE_NULL) return -1;
|
||||||
qse_awk_rtx_setretval (rtx, tmp);
|
qse_awk_rtx_setretval (rtx, retv);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
softfail:
|
softfail:
|
||||||
tmp = qse_awk_rtx_makeintval (rtx, (qse_long_t)-1);
|
/* return without setting the return value.
|
||||||
if (tmp == QSE_NULL) return -1;
|
* this intrinsic function will return a nil value when it fails */
|
||||||
qse_awk_rtx_setretval (rtx, tmp);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static int fnc_barrier (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
|
static int fnc_barrier (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
|
||||||
{
|
{
|
||||||
int rx;
|
int rx;
|
||||||
qse_awk_val_t* retv;
|
qse_awk_val_t* retv;
|
||||||
// rxtn_t* rxtn;
|
|
||||||
|
|
||||||
// rxtn = (rxtn_t*) qse_awk_rtx_getxtnstd (rtx);
|
|
||||||
|
|
||||||
// x = (MPI_Barrier (rxtn->comm) == MPI_SUCCESS)? 0: -1;
|
|
||||||
rx = (MPI_Barrier (MPI_COMM_WORLD) == MPI_SUCCESS)? 0: -1;
|
rx = (MPI_Barrier (MPI_COMM_WORLD) == MPI_SUCCESS)? 0: -1;
|
||||||
|
|
||||||
retv = qse_awk_rtx_makeintval (rtx, rx);
|
retv = qse_awk_rtx_makeintval (rtx, rx);
|
||||||
@ -119,43 +135,6 @@ static int fnc_barrier (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fnc_init (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
|
|
||||||
{
|
|
||||||
int rx;
|
|
||||||
qse_awk_val_t* retv;
|
|
||||||
|
|
||||||
/* I didn't manage to find a good way to change the
|
|
||||||
* default error handler to MPI_ERRORS_RETURN.
|
|
||||||
* so MPI_Init() will simply abort the program if it fails */
|
|
||||||
// if (MPI_Init (&argc, &argv) != MPI_SUCCESS) rx = -1;
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
MPI_Comm_set_errhandler (MPI_COMM_WORLD, MPI_ERRORS_RETURN);
|
|
||||||
rx = 0;
|
|
||||||
// }
|
|
||||||
|
|
||||||
retv = qse_awk_rtx_makeintval (rtx, rx);
|
|
||||||
if (retv == QSE_NULL) return -1;
|
|
||||||
|
|
||||||
qse_awk_rtx_setretval (rtx, retv);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int fnc_fini (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
|
|
||||||
{
|
|
||||||
int rx;
|
|
||||||
qse_awk_val_t* retv;
|
|
||||||
|
|
||||||
MPI_Finalize ();
|
|
||||||
rx = 0;
|
|
||||||
|
|
||||||
retv = qse_awk_rtx_makeintval (rtx, rx);
|
|
||||||
if (retv == QSE_NULL) return -1;
|
|
||||||
|
|
||||||
qse_awk_rtx_setretval (rtx, retv);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
typedef struct fnctab_t fnctab_t;
|
typedef struct fnctab_t fnctab_t;
|
||||||
@ -176,9 +155,20 @@ static fnctab_t fnctab[] =
|
|||||||
{
|
{
|
||||||
{ QSE_T("assign"), { { 1, 1 }, fnc_assign } },
|
{ QSE_T("assign"), { { 1, 1 }, fnc_assign } },
|
||||||
{ QSE_T("barrier"), { { 0, 0 }, fnc_barrier } },
|
{ QSE_T("barrier"), { { 0, 0 }, fnc_barrier } },
|
||||||
{ QSE_T("fini"), { { 0, 0 }, fnc_fini } },
|
|
||||||
{ QSE_T("hash"), { { 1, 1 }, fnc_hash } },
|
{ QSE_T("hash"), { { 1, 1 }, fnc_hash } },
|
||||||
{ QSE_T("init"), { { 0, 0 }, fnc_init } }
|
{ QSE_T("rank"), { { 0, 0 }, fnc_rank } },
|
||||||
|
{ QSE_T("reduce"), { { 2, 2 }, fnc_reduce } },
|
||||||
|
{ QSE_T("size"), { { 0, 0 }, fnc_size } }
|
||||||
|
};
|
||||||
|
|
||||||
|
static inttab_t inttab[] =
|
||||||
|
{
|
||||||
|
{ QSE_T("REDUCE_LAND"), { 4 } },
|
||||||
|
{ QSE_T("REDUCE_LOR"), { 5 } },
|
||||||
|
{ QSE_T("REDUCE_MAX"), { 1 } },
|
||||||
|
{ QSE_T("REDUCE_MIN"), { 0 } },
|
||||||
|
{ QSE_T("REDUCE_PROD"), { 3 } },
|
||||||
|
{ QSE_T("REDUCE_SUM"), { 2 } }
|
||||||
};
|
};
|
||||||
|
|
||||||
static int query (qse_awk_mod_t* mod, qse_awk_t* awk, const qse_char_t* name, qse_awk_mod_sym_t* sym)
|
static int query (qse_awk_mod_t* mod, qse_awk_t* awk, const qse_char_t* name, qse_awk_mod_sym_t* sym)
|
||||||
@ -197,7 +187,6 @@ static int query (qse_awk_mod_t* mod, qse_awk_t* awk, const qse_char_t* name, qs
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
for (i = 0; i < QSE_COUNTOF(inttab); i++)
|
for (i = 0; i < QSE_COUNTOF(inttab); i++)
|
||||||
{
|
{
|
||||||
if (qse_strcmp (inttab[i].name, name) == 0)
|
if (qse_strcmp (inttab[i].name, name) == 0)
|
||||||
@ -207,7 +196,6 @@ static int query (qse_awk_mod_t* mod, qse_awk_t* awk, const qse_char_t* name, qs
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
ea.ptr = name;
|
ea.ptr = name;
|
||||||
ea.len = qse_strlen(name);
|
ea.len = qse_strlen(name);
|
||||||
@ -217,12 +205,13 @@ static int query (qse_awk_mod_t* mod, qse_awk_t* awk, const qse_char_t* name, qs
|
|||||||
|
|
||||||
/* TODO: proper resource management */
|
/* TODO: proper resource management */
|
||||||
|
|
||||||
int init (qse_awk_mod_t* mod, qse_awk_rtx_t* rtx)
|
static int init (qse_awk_mod_t* mod, qse_awk_rtx_t* rtx)
|
||||||
{
|
{
|
||||||
|
/* TODO: anything */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fini (qse_awk_mod_t* mod, qse_awk_rtx_t* rtx)
|
static void fini (qse_awk_mod_t* mod, qse_awk_rtx_t* rtx)
|
||||||
{
|
{
|
||||||
/* TODO: anything */
|
/* TODO: anything */
|
||||||
}
|
}
|
||||||
@ -246,3 +235,30 @@ int load (qse_awk_mod_t* mod, qse_awk_t* awk)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The MPI module is special in that it exports 2 extra symbols -
|
||||||
|
* mpi_init and mpi_fini. These two symbols are intended to be called
|
||||||
|
* dynamically using dlopen() or something similar when an application
|
||||||
|
* intending to use mpi::xxx starts up. This way, the application doesn't
|
||||||
|
* have to be linked to any MPI libraries while this module is linked to
|
||||||
|
* an MPI library. If this module doesn't exist, it means MPI is not availble
|
||||||
|
* and the module wasn't built. So you can't access mpi::xxx symbols either
|
||||||
|
*/
|
||||||
|
|
||||||
|
int mpi_init (int argc, qse_achar_t* argv[])
|
||||||
|
{
|
||||||
|
int rx;
|
||||||
|
|
||||||
|
if (MPI_Init (&argc, &argv) != MPI_SUCCESS) rx = -1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MPI_Comm_set_errhandler (MPI_COMM_WORLD, MPI_ERRORS_RETURN);
|
||||||
|
rx = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rx;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mpi_fini (void)
|
||||||
|
{
|
||||||
|
MPI_Finalize ();
|
||||||
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include <qse/awk/std.h>
|
#include <qse/awk/awk.h>
|
||||||
#include <qse/cmn/str.h>
|
#include <qse/cmn/str.h>
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
@ -298,12 +298,12 @@ static int query (qse_awk_mod_t* mod, qse_awk_t* awk, const qse_char_t* name, qs
|
|||||||
|
|
||||||
/* TODO: proper resource management */
|
/* TODO: proper resource management */
|
||||||
|
|
||||||
int init (qse_awk_mod_t* mod, qse_awk_rtx_t* rtx)
|
static int init (qse_awk_mod_t* mod, qse_awk_rtx_t* rtx)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fini (qse_awk_mod_t* mod, qse_awk_rtx_t* rtx)
|
static void fini (qse_awk_mod_t* mod, qse_awk_rtx_t* rtx)
|
||||||
{
|
{
|
||||||
/* TODO:
|
/* TODO:
|
||||||
for (each pid for rtx) kill (pid, SIGKILL);
|
for (each pid for rtx) kill (pid, SIGKILL);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include <qse/awk/std.h>
|
#include <qse/awk/awk.h>
|
||||||
#include <qse/cmn/str.h>
|
#include <qse/cmn/str.h>
|
||||||
#include <qse/cmn/rbt.h>
|
#include <qse/cmn/rbt.h>
|
||||||
#include <qse/cmn/mbwc.h>
|
#include <qse/cmn/mbwc.h>
|
||||||
|
@ -36,8 +36,6 @@
|
|||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
# include <signal.h>
|
# include <signal.h>
|
||||||
# include <errno.h>
|
# include <errno.h>
|
||||||
# include <ltdl.h>
|
|
||||||
# define USE_LTDL
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* these three definitions for doxygen cross-reference */
|
/* these three definitions for doxygen cross-reference */
|
||||||
@ -58,6 +56,8 @@ public:
|
|||||||
idLastSleep = addGlobal (QSE_T("LAST_SLEEP"));
|
idLastSleep = addGlobal (QSE_T("LAST_SLEEP"));
|
||||||
if (idLastSleep <= -1) goto oops;
|
if (idLastSleep <= -1) goto oops;
|
||||||
|
|
||||||
|
/* this is for demonstration only.
|
||||||
|
* you can use sys::sleep() instead */
|
||||||
if (addFunction (QSE_T("sleep"), 1, 1,
|
if (addFunction (QSE_T("sleep"), 1, 1,
|
||||||
(FunctionHandler)&MyAwk::sleep) <= -1) goto oops;
|
(FunctionHandler)&MyAwk::sleep) <= -1) goto oops;
|
||||||
|
|
||||||
@ -470,16 +470,8 @@ int qse_main (int argc, qse_achar_t* argv[])
|
|||||||
qse_setdflcmgrbyid (QSE_CMGR_SLMB);
|
qse_setdflcmgrbyid (QSE_CMGR_SLMB);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(USE_LTDL)
|
|
||||||
lt_dlinit ();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ret = qse_runmain (argc, argv, awk_main);
|
ret = qse_runmain (argc, argv, awk_main);
|
||||||
|
|
||||||
#if defined(USE_LTDL)
|
|
||||||
lt_dlexit ();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
WSACleanup ();
|
WSACleanup ();
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user