mirror of
https://bitbucket.org/cosmicvoids/vide_public.git
synced 2025-07-05 07:41:11 +00:00
Imported libSDF into VOID tree
This commit is contained in:
parent
c6dd08bd7d
commit
2d09cb68df
55 changed files with 12667 additions and 0 deletions
286
external/libsdf/libmpmy/mpmy_generic.c
vendored
Normal file
286
external/libsdf/libmpmy/mpmy_generic.c
vendored
Normal file
|
@ -0,0 +1,286 @@
|
|||
/* This file is included in most (all?) of the mpmy_PAROS files.
|
||||
It defines several of the required mpmy functions in terms of a
|
||||
more primitive set. In some cases, however, there will be a PAROS
|
||||
specific way to achieve these results defined in the mpmy_PAROS file
|
||||
When that happens, the mpmy_PAROS file will also
|
||||
#define HAVE_MPMY_FUNCNAME
|
||||
so we know that we shouldn't define it here. */
|
||||
|
||||
/* These are set to the "right" thing on a uniprocessor, where it is
|
||||
most likely that we will neglect to call MPMY_Init, but where
|
||||
we really can proceed without any problems. I tried
|
||||
setting them to -1, but that just led to hard-to-understand
|
||||
crashes. We really should test occasionally that MPMY_Init has
|
||||
been called. But I'll leave that for another day... */
|
||||
int _MPMY_procnum_ = 0;
|
||||
int _MPMY_nproc_ = 1;
|
||||
int _MPMY_procs_per_node_ = 1;
|
||||
int _MPMY_initialized_ = 0;
|
||||
|
||||
Counter_t MPMYSendCnt;
|
||||
Counter_t MPMYRecvCnt;
|
||||
Counter_t MPMYDoneCnt;
|
||||
|
||||
#ifndef HAVE_MPMY_FLICK
|
||||
int MPMY_Flick(void){return MPMY_SUCCESS;}
|
||||
#endif /* HAVE_MPMY_FLICK */
|
||||
|
||||
#ifndef HAVE_MPMY_IRSEND
|
||||
int MPMY_Irsend(const void *buf, int cnt, int dest, int tag, MPMY_Comm_request *req){
|
||||
return MPMY_Isend(buf, cnt, dest, tag, req);
|
||||
}
|
||||
#endif /* HAVE_MPMY_IRSEND */
|
||||
|
||||
#ifndef HAVE_MPMY_SHIFT
|
||||
/* An implementation of shift that just uses mpmy_isend/irecv */
|
||||
/* Some systems will have a better option, but this should always work. */
|
||||
|
||||
#define SHIFT_TAG 0x1492
|
||||
/* Because NX can't distinguish different sources when reading */
|
||||
/* messages, we help it out by adding processor info to the tag. */
|
||||
/* Is this really necessary for the "generic" implementation? */
|
||||
int MPMY_Shift(int proc, void *recvbuf, int recvcnt,
|
||||
const void *sendbuf, int sendcnt, MPMY_Status *stat){
|
||||
MPMY_Comm_request inreq, outreq;
|
||||
Msgf(("Starting MPMY_Shift(proc=%d, recvcnt=%d, sendcnt=%d:\n",
|
||||
proc, recvcnt, sendcnt));
|
||||
if (proc > _MPMY_procnum_) {
|
||||
MPMY_Irecv(recvbuf, recvcnt, proc, SHIFT_TAG+proc, &inreq);
|
||||
Msgf(("Irecv posted\n"));
|
||||
MPMY_Wait(inreq, stat);
|
||||
Msgf(("Irecv done\n"));
|
||||
MPMY_Isend(sendbuf, sendcnt, proc, SHIFT_TAG+MPMY_Procnum(), &outreq);
|
||||
Msgf(("Isend posted\n"));
|
||||
MPMY_Wait(outreq, NULL);
|
||||
Msgf(("Isend done\n"));
|
||||
} else {
|
||||
MPMY_Isend(sendbuf, sendcnt, proc, SHIFT_TAG+MPMY_Procnum(), &outreq);
|
||||
Msgf(("Isend posted\n"));
|
||||
MPMY_Wait(outreq, NULL);
|
||||
Msgf(("Isend done\n"));
|
||||
MPMY_Irecv(recvbuf, recvcnt, proc, SHIFT_TAG+proc, &inreq);
|
||||
Msgf(("Irecv posted\n"));
|
||||
MPMY_Wait(inreq, stat);
|
||||
Msgf(("Irecv done\n"));
|
||||
}
|
||||
|
||||
Msgf(("Finished MPMY_Shift\n"));
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
#endif /* HAVE_MPMY_SHIFT */
|
||||
|
||||
/*
|
||||
This could be smarter. In particular, it could recover gracefully
|
||||
from malloc failing to deliver.
|
||||
*/
|
||||
#ifndef HAVE_MPMY_SHIFT_OVERLAP
|
||||
#include "Malloc.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
int MPMY_Shift_overlap(int proc, void *recvbuf, int recvcnt,
|
||||
const void *sendbuf, int sendcnt, MPMY_Status *stat){
|
||||
void *tmp = Malloc(sendcnt);
|
||||
int ret;
|
||||
|
||||
if( tmp == NULL && sendcnt>0 )
|
||||
return MPMY_FAILED;
|
||||
memcpy(tmp, sendbuf, sendcnt);
|
||||
ret = MPMY_Shift(proc, recvbuf, recvcnt, tmp, sendcnt, stat);
|
||||
Free(tmp);
|
||||
return ret;
|
||||
}
|
||||
#endif /* HAVE_MPMY_SHIFT_OVERLAP */
|
||||
|
||||
#ifndef HAVE_MPMY_SYNC
|
||||
/* Implementation of MPMY_Sync in terms of the 'combine' functions. */
|
||||
/* Some systems might provide a more useful interface. */
|
||||
|
||||
int MPMY_Sync(void){
|
||||
int junk=0;
|
||||
|
||||
/* I'm sure this is overkill! */
|
||||
return MPMY_Combine(&junk, &junk, 1, MPMY_INT, MPMY_BOR);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_MPMY_FINALIZE
|
||||
/* Any system specific stuff gets handled by a system-specific finalizer */
|
||||
int MPMY_Finalize(void){
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_MPMY_WAIT
|
||||
/* An implementation of mpmy_wait that just busy-waits on MPMY_Test. */
|
||||
/* Some systems will have a better option, but this should always work. */
|
||||
|
||||
int MPMY_Wait(MPMY_Comm_request req, MPMY_Status *stat){
|
||||
/* Should we do a 'MPMY_Flick'' ? */
|
||||
int flag = 0;
|
||||
int ret;
|
||||
|
||||
do{
|
||||
MPMY_Flick();
|
||||
ret = MPMY_Test(req, &flag, stat);
|
||||
}while( ret == MPMY_SUCCESS && flag==0 );
|
||||
return ret;
|
||||
}
|
||||
#endif /* HAVE_MPMY_WAIT */
|
||||
|
||||
#ifndef HAVE_MPMY_WAIT2
|
||||
int MPMY_Wait2(MPMY_Comm_request req1, MPMY_Status *stat1,
|
||||
MPMY_Comm_request req2, MPMY_Status *stat2){
|
||||
/* Should we do a 'MPMY_Flick'' ? */
|
||||
int done1, done2;
|
||||
int ret;
|
||||
|
||||
done1 = done2 = 0;
|
||||
do{ /* loop until at least one is finished */
|
||||
MPMY_Flick();
|
||||
ret = MPMY_Test(req1, &done1, stat1);
|
||||
if( ret != MPMY_SUCCESS )
|
||||
return ret;
|
||||
ret = MPMY_Test(req2, &done2, stat2);
|
||||
if( ret != MPMY_SUCCESS )
|
||||
return ret;
|
||||
}while( done1 == 0 && done2 == 0 );
|
||||
|
||||
/* Now there's only one left, so we can call MPMY_Wait */
|
||||
if( !done1 ){
|
||||
ret = MPMY_Wait(req1, stat1);
|
||||
if( ret != MPMY_SUCCESS )
|
||||
return ret;
|
||||
}
|
||||
if( !done2 ){
|
||||
ret = MPMY_Wait(req2, stat2);
|
||||
if( ret != MPMY_SUCCESS )
|
||||
return ret;
|
||||
}
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef HAVE_MPMY_DIAGNOSTIC
|
||||
void MPMY_Diagnostic(int (*printflike)(const char *, ...)){
|
||||
(*printflike)("No Diagnostic info for this MPMY\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_MPMY_INITIALIZED
|
||||
int MPMY_Initialized(void){
|
||||
return _MPMY_initialized_;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_MPMY_PHYSNODE
|
||||
const char *MPMY_Physnode(void){
|
||||
return "?";
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_MPMY_TIMERS
|
||||
/* This is a nightmare! Timers should really be ARCH dependent */
|
||||
/* but because of the CM5's special closeness to ARCH=sun4, they */
|
||||
/* are PAROS dependent, instead. That means that we would otherwise */
|
||||
/* repeat this code block in lots of mpmy_PAROS.c files */
|
||||
#ifdef _AIX
|
||||
/* No longer working?? Nov 3 1994
|
||||
# include "timers_readrtc.c" */
|
||||
#if !defined(USE_HWCLOCK) && !defined(USE_GETTIME)
|
||||
#include "timers_posix.c"
|
||||
#endif
|
||||
/* it's not inconceivable to compile sequentially for the intels */
|
||||
/* However, we won't necessarily be linking against, e.g, hwclock
|
||||
#elif defined(__INTEL_SSD__)
|
||||
# include "timers_nx.c"
|
||||
*/
|
||||
#else
|
||||
#if !defined(USE_HWCLOCK) && !defined(USE_GETTIME)
|
||||
# include "timers_posix.c"
|
||||
#endif
|
||||
#endif /* _AIX */
|
||||
#endif /* HAVE_MPMY_TIMERS */
|
||||
|
||||
static time_t job_start;
|
||||
static time_t job_end;
|
||||
static time_t checkpoint_last;
|
||||
static time_t checkpoint_next;
|
||||
static time_t checkpoint_interval;
|
||||
static int checkpoint_setup;
|
||||
|
||||
void
|
||||
MPMY_CheckpointSetup(int job_seconds, int interval_seconds, int step_seconds)
|
||||
{
|
||||
if (MPMY_Procnum() == 0) {
|
||||
job_start = time(NULL);
|
||||
if (job_seconds == -1) job_end = -1;
|
||||
else job_end = job_start + job_seconds - step_seconds;
|
||||
checkpoint_interval = interval_seconds - step_seconds;
|
||||
checkpoint_last = job_start;
|
||||
checkpoint_next = job_start + checkpoint_interval;
|
||||
Msg_do("Checkpoint Setup interval %ld start %ld next %ld end %ld\n",
|
||||
checkpoint_interval, job_start, checkpoint_next, job_end);
|
||||
}
|
||||
checkpoint_setup = 1;
|
||||
}
|
||||
|
||||
int
|
||||
MPMY_CheckpointDue(int next_output_seconds)
|
||||
{
|
||||
time_t t;
|
||||
int retval = 0;
|
||||
|
||||
if (MPMY_Procnum() == 0) {
|
||||
t = time(NULL);
|
||||
if (t >= checkpoint_next) retval = 1;
|
||||
if (next_output_seconds < checkpoint_interval/4) {
|
||||
Msg_do("Postponing checkpoint since output expected in %d seconds\n",
|
||||
next_output_seconds);
|
||||
retval = 0;
|
||||
}
|
||||
if (job_end > 0 && t >= job_end) retval = 1;
|
||||
}
|
||||
if (retval) Msg_do("Checkpoint Due\n");
|
||||
MPMY_Bcast(&retval, 1, MPMY_INT, 0);
|
||||
return retval;
|
||||
}
|
||||
|
||||
void
|
||||
MPMY_CheckpointFinished(void)
|
||||
{
|
||||
time_t t;
|
||||
|
||||
if (MPMY_Procnum() == 0) {
|
||||
t = time(NULL);
|
||||
checkpoint_last = t;
|
||||
checkpoint_next = t + checkpoint_interval;
|
||||
if (job_end > 0 && checkpoint_next > job_end) checkpoint_next = job_end;
|
||||
Msg_do("next checkpoint %ld (%ld from now)\n", checkpoint_next, checkpoint_next-t);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
MPMY_JobDone(void)
|
||||
{
|
||||
time_t t;
|
||||
int retval = 0;
|
||||
|
||||
if (MPMY_Procnum() == 0) {
|
||||
t = time(NULL);
|
||||
if (job_end > 0 && t >= job_end) {
|
||||
retval = 1;
|
||||
Msg_do("Job Done\n");
|
||||
}
|
||||
}
|
||||
MPMY_Bcast(&retval, 1, MPMY_INT, 0);
|
||||
return retval;
|
||||
}
|
||||
|
||||
#ifndef HAVE_MPMY_JOBREMAINING
|
||||
int
|
||||
MPMY_JobRemaining(void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue