mirror of
https://bitbucket.org/cosmicvoids/vide_public.git
synced 2025-07-05 15:51:12 +00:00
153 lines
4.3 KiB
C
153 lines
4.3 KiB
C
#include <string.h>
|
|
#include "ring.h"
|
|
#include "Malloc.h"
|
|
#include "mpmy.h"
|
|
#include "gc.h"
|
|
#include "Msgs.h"
|
|
#include "singlio.h"
|
|
|
|
#define MSGTYPE 142
|
|
|
|
void
|
|
Ring(void *bptr, int bsize, int bnobj,
|
|
void *optr, int osize, int onobj, int oused,
|
|
void initf(void *, void *), void interactf(void *, void *, int, int))
|
|
{
|
|
char *p;
|
|
void *travel_btab;
|
|
void *tmpbuf;
|
|
int travel_size;
|
|
int n, i;
|
|
int from_proc, to_proc;
|
|
int procnum = MPMY_Procnum();
|
|
int nproc = MPMY_Nproc();
|
|
int max_nobj = onobj;
|
|
|
|
MPMY_Combine(&onobj, &max_nobj, 1, MPMY_INT, MPMY_MAX);
|
|
|
|
travel_size = max_nobj * oused;
|
|
travel_btab = Malloc(travel_size);
|
|
tmpbuf = Malloc(travel_size);
|
|
for (i = 0; i < onobj; i++) {
|
|
p = (char *)optr+i*osize;
|
|
initf((char *)travel_btab+i*oused, p);
|
|
}
|
|
|
|
#if GRAYDECOMP
|
|
/* There should be functions like Gcup() which are periodic */
|
|
to_proc = Gcup(procnum, nproc);
|
|
from_proc = Gcdown(procnum, nproc);
|
|
if (to_proc == -1) to_proc = bin2gray(0);
|
|
if (from_proc == -1) from_proc = bin2gray(nproc-1);
|
|
#else
|
|
to_proc = (procnum+1)%nproc;
|
|
from_proc = (procnum+nproc-1)%nproc;
|
|
#endif
|
|
|
|
/* local part */
|
|
for (p = bptr; p < (char *)bptr + bnobj * bsize; p += bsize) {
|
|
interactf(p, travel_btab, oused, onobj);
|
|
}
|
|
|
|
for(n = 1; n < nproc; n++) {
|
|
MPMY_Comm_request req, req2;
|
|
MPMY_Status stat;
|
|
|
|
singlPrintf("cycle %d starting\n", n);
|
|
Msgf(("communicate, cycle %d\n", n));
|
|
/* This uses a lot more memory than packets would */
|
|
memcpy(tmpbuf, travel_btab, travel_size);
|
|
MPMY_Irecv(travel_btab, travel_size, from_proc, MSGTYPE, &req);
|
|
MPMY_Isend(tmpbuf, onobj * oused, to_proc, MSGTYPE, &req2);
|
|
MPMY_Wait2(req, &stat, req2, 0);
|
|
onobj = MPMY_Count(&stat)/oused;
|
|
|
|
Msgf(("compute, cycle %d\n", n));
|
|
for (p = bptr; p < (char *)bptr + bnobj * bsize; p += bsize) {
|
|
interactf(p, travel_btab, oused, onobj);
|
|
}
|
|
}
|
|
Free(tmpbuf);
|
|
Free(travel_btab);
|
|
}
|
|
|
|
/* Swap source and sink, and provide finishf() */
|
|
void
|
|
Ring2(void *bptr, int bsize, int bnobj,
|
|
void *optr, int osize, int onobj, int tsize,
|
|
void initf(void *, void *), void interactf(void *, void *, int, int), void finishf(void *, void *))
|
|
{
|
|
char *p;
|
|
void *travel_btab;
|
|
void *tmpbuf;
|
|
int travel_size;
|
|
int n, i;
|
|
int from_proc, to_proc;
|
|
int procnum = MPMY_Procnum();
|
|
int nproc = MPMY_Nproc();
|
|
int max_nobj = onobj;
|
|
int initial_onobj = onobj;
|
|
MPMY_Comm_request req, req2;
|
|
MPMY_Status stat;
|
|
|
|
|
|
MPMY_Combine(&onobj, &max_nobj, 1, MPMY_INT, MPMY_MAX);
|
|
|
|
travel_size = max_nobj * tsize;
|
|
travel_btab = Malloc(travel_size);
|
|
tmpbuf = Malloc(travel_size);
|
|
for (i = 0; i < onobj; i++) {
|
|
p = (char *)optr+i*osize;
|
|
initf((char *)travel_btab+i*tsize, p);
|
|
}
|
|
|
|
#if GRAYDECOMP
|
|
/* There should be functions like Gcup() which are periodic */
|
|
to_proc = Gcup(procnum, nproc);
|
|
from_proc = Gcdown(procnum, nproc);
|
|
if (to_proc == -1) to_proc = bin2gray(0);
|
|
if (from_proc == -1) from_proc = bin2gray(nproc-1);
|
|
#else
|
|
to_proc = (procnum+1)%nproc;
|
|
from_proc = (procnum+nproc-1)%nproc;
|
|
#endif
|
|
|
|
/* local part */
|
|
for (p = travel_btab; p < (char *)travel_btab + onobj * tsize; p += tsize) {
|
|
interactf(p, bptr, bsize, bnobj);
|
|
}
|
|
|
|
for(n = 1; n < nproc; n++) {
|
|
singlPrintf("ring2, cycle %d starting\n", n);
|
|
Msgf(("communicate, cycle %d\n", n));
|
|
/* This uses a lot more memory than packets would */
|
|
memcpy(tmpbuf, travel_btab, onobj * tsize);
|
|
MPMY_Irecv(travel_btab, travel_size, from_proc, MSGTYPE, &req);
|
|
MPMY_Isend(tmpbuf, onobj * tsize, to_proc, MSGTYPE, &req2);
|
|
MPMY_Wait2(req, &stat, req2, 0);
|
|
onobj = MPMY_Count(&stat)/tsize;
|
|
|
|
Msgf(("compute, cycle %d\n", n));
|
|
for (p = travel_btab; p < (char *)travel_btab + onobj * tsize; p += tsize) {
|
|
interactf(p, bptr, bsize, bnobj);
|
|
}
|
|
}
|
|
|
|
memcpy(tmpbuf, travel_btab, onobj * tsize);
|
|
MPMY_Irecv(travel_btab, travel_size, from_proc, MSGTYPE, &req);
|
|
MPMY_Isend(tmpbuf, onobj * tsize, to_proc, MSGTYPE, &req2);
|
|
MPMY_Wait2(req, &stat, req2, 0);
|
|
onobj = MPMY_Count(&stat)/tsize;
|
|
Free(tmpbuf);
|
|
|
|
if (onobj != initial_onobj) Error("onobj doesn't match after trip around ring\n");
|
|
|
|
Msgf(("finish ring\n"));
|
|
if (finishf) {
|
|
for (i = 0; i < onobj; i++) {
|
|
p = (char *)optr+i*osize;
|
|
finishf((char *)travel_btab+i*tsize, p);
|
|
}
|
|
}
|
|
Free(travel_btab);
|
|
}
|