Skip to content

Commit

Permalink
parRCB (#20)
Browse files Browse the repository at this point in the history
  • Loading branch information
stgeke authored Jul 20, 2020
1 parent f81875c commit bb51af9
Show file tree
Hide file tree
Showing 21 changed files with 919 additions and 415 deletions.
94 changes: 50 additions & 44 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,32 @@ PAUL ?= 1
CC ?= mpicc
CFLAGS ?= -O2

SRCROOT=.
MKFILEPATH = $(abspath $(lastword $(MAKEFILE_LIST)))
SRCROOT_ ?= $(patsubst %/,%,$(dir $(MKFILEPATH)))
SRCROOT=$(realpath $(SRCROOT_))

GSLIBDIR=$(GSLIBPATH)

SRCDIR =$(SRCROOT)/src
BUILDDIR=$(SRCROOT)/build
TESTDIR =$(SRCROOT)/example
SRCDIR =$(SRCROOT)/src
SORTDIR =$(SRCROOT)/src/sort
BUILDDIR =$(SRCROOT)/build
EXAMPLEDIR=$(SRCROOT)/example
TESTDIR =$(SRCROOT)/tests

TARGET=parRSB
TESTS=$(TESTDIR)/example
LIB=src/lib$(TARGET).a

INCFLAGS=-I$(SRCDIR) -I$(GSLIBDIR)/include
LIB=$(BUILDDIR)/lib/lib$(TARGET).a
EXAMPLE=$(EXAMPLEDIR)/example

TESTLDFLAGS:=-L$(BUILDDIR)/lib -l$(TARGET) -L $(GSLIBDIR)/lib -lgs -lm $(LDFLAGS)
INCFLAGS=-I$(SRCDIR) -I$(SORTDIR) -I$(GSLIBDIR)/include
LDFLAGS:=-L$(BUILDDIR)/lib -l$(TARGET) -L $(GSLIBDIR)/lib -lgs -lm

ifneq (,$(strip $(DESTDIR)))
INSTALL_ROOT = $(DESTDIR)
else
INSTALL_ROOT = $(SRCROOT)/build
endif
SRCS =$(wildcard $(SRCDIR)/*.c)
SORTSRCS=$(wildcard $(SORTDIR)/*.c)
TESTSRCS=$(wildcard $(TESTDIR)/*.c)

CSRCS:= $(SRCDIR)/genmap.c \
$(SRCDIR)/genmap-vector.c $(SRCDIR)/genmap-handle.c $(SRCDIR)/genmap-comm.c \
$(SRCDIR)/genmap-eigen.c $(SRCDIR)/genmap-laplacian.c $(SRCDIR)/genmap-lanczos.c \
$(SRCDIR)/genmap-rsb.c \
$(SRCDIR)/parrsb-binsort.c \
$(SRCDIR)/genmap-chelpers.c \
$(SRCDIR)/parRSB.c
COBJS:=$(CSRCS:.c=.o)

SRCOBJS:=$(COBJS)
SRCOBJS =$(patsubst $(SRCROOT)/%.c,$(BUILDDIR)/%.o,$(SRCS))
SRCOBJS+=$(patsubst $(SRCROOT)/%.c,$(BUILDDIR)/%.o,$(SORTSRCS))
TESTOBJS=$(patsubst $(SRCROOT)/%.c,$(BUILDDIR)/%,$(TESTSRCS))

PP=

Expand All @@ -45,50 +40,58 @@ ifneq ($(PAUL),0)
PP += -DGENMAP_PAUL
endif

INSTALLDIR=
ifneq (,$(strip $(DESTDIR)))
INSTALLDIR=$(realpath $(DESTDIR))
endif

.PHONY: default
default: check lib install

.PHONY: all
all: check lib tests install
all: check lib tests example install

.PHONY: install
install: lib
@mkdir -p $(INSTALL_ROOT)/lib 2>/dev/null
@cp -v $(LIB) $(INSTALL_ROOT)/lib 2>/dev/null
@mkdir -p $(INSTALL_ROOT)/include 2>/dev/null
@cp $(SRCDIR)/parRSB.h $(INSTALL_ROOT)/include 2>/dev/null

ifneq ($(INSTALLDIR),)
@mkdir -p $(INSTALLDIR)/lib 2>/dev/null
@cp -v $(LIB) $(INSTALLDIR)/lib 2>/dev/null
@mkdir -p $(INSTALLDIR)/include 2>/dev/null
@cp $(SRCDIR)/*.h $(SORTDIR)/*.h $(INSTALLDIR)/include 2>/dev/null
endif

.PHONY: $(TARGET)
.PHONY: lib
lib: $(SRCOBJS)
@mkdir -p $(BUILDDIR)/lib
@$(AR) cr $(LIB) $(SRCOBJS)
@ranlib $(LIB)

.PHONY: check
check:
ifeq ($(GSLIBPATH),)
$(error Specify GSLIBPATH=<path to gslib>/build)
$(error Specify GSLIBPATH=<path to gslib>/build)
endif

$(COBJS): %.o: %.c
$(BUILDDIR)/src/%.o: $(SRCROOT)/src/%.c
$(CC) $(CFLAGS) $(PP) $(INCFLAGS) -c $< -o $@

.PHONY: examples
examples: $(EXAMPLE)

$(EXAMPLE): install
$(CC) $(CFLAGS) -I$(GSLIBDIR)/include -I$(SRCDIR) -I$(SORTDIR) $@.c -o $@ $(LDFLAGS)

.PHONY: tests
tests: $(TESTS)
tests: install $(TESTOBJS)
@cp $(TESTDIR)/run-tests.sh $(BUILDDIR)/tests/
@cd $(BUILDDIR)/tests && ./run-tests.sh

$(TESTS): lib install
$(CC) $(CFLAGS) -I$(GSLIBDIR)/include -I$(BUILDDIR)/include $@.c -o $@ $(TESTLDFLAGS)
$(BUILDDIR)/tests/%: $(SRCROOT)/tests/%.c
$(CC) $(CFLAGS) -I$(GSLIBDIR)/include -I$(SRCDIR) -I$(SORTDIR) $< -o $@ $(LDFLAGS)

.PHONY: clean
clean:
@rm -f $(SRCOBJS) $(LIB) $(TESTS) $(TESTS).o

.PHONY: astyle
astyle:
astyle --style=google --indent=spaces=2 --max-code-length=80 \
--keep-one-line-statements --keep-one-line-blocks --lineend=linux \
--suffix=none --preserve-date --formatted --pad-oper \
--unpad-paren example/*.[ch] src/*.[ch]
@rm -rf $(BUILDDIR) $(EXAMPLE) $(EXAMPLE).o

print-%:
$(info [ variable name]: $*)
Expand All @@ -97,3 +100,6 @@ print-%:
$(info [expanded value]: $($*))
$(info)
@true

$(shell mkdir -p $(BUILDDIR)/src/sort)
$(shell mkdir -p $(BUILDDIR)/tests)
9 changes: 8 additions & 1 deletion example/conReader.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
#ifndef _CONREADER_H_
#define _CONREADER_H_

#include <math.h>

struct con {
int nv;
int nelg;
Expand Down Expand Up @@ -31,7 +36,7 @@ int conRead(const char *fname, struct con *c, MPI_Comm comm) {

float byte_test;
MPI_File_read_all(fh, &byte_test, 4, MPI_BYTE, MPI_STATUS_IGNORE);
if(abs(byte_test - 6.543210) > 1e-7) {
if(fabs(byte_test - 6.543210) > 1e-7) {
if(myid == 0) printf("ERROR byte_test failed! %f\n", byte_test);
return 1;
}
Expand Down Expand Up @@ -69,3 +74,5 @@ int conRead(const char *fname, struct con *c, MPI_Comm comm) {
free(buf);
return 0;
}

#endif
File renamed without changes.
14 changes: 3 additions & 11 deletions src/genmap-impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,6 @@ struct GenmapHandle_private {

int dbgLevel;
int printStat;

parRSBHistogram histogram;
};

int GenmapCreateHandle(GenmapHandle h);
Expand All @@ -68,19 +66,13 @@ struct GenmapVector_private {
#define GenmapCalloc(n, p) GenmapCallocArray ((n), sizeof(**(p)), p)
#define GenmapRealloc(n, p) GenmapReallocArray((n), sizeof(**(p)), p)

void GenmapFiedlerMinMax(GenmapHandle h, GenmapScalar *min, GenmapScalar *max);
void GenmapGlobalIdMinMax(GenmapHandle h, GenmapLong *min, GenmapLong *max);
void GenmapFiedlerMinMax(GenmapHandle h,GenmapScalar *min,
GenmapScalar *max);
void GenmapGlobalIdMinMax(GenmapHandle h,GenmapLong *min,GenmapLong *max);
GenmapInt GenmapSetFiedlerBin(GenmapHandle h);
GenmapInt GenmapSetGlobalIdBin(GenmapHandle h);
void GenmapAssignBins(GenmapHandle h, int field, buffer *buf0);
void GenmapTransferToBins(GenmapHandle h, int field, buffer *buf0);
void GenmapBinSort(GenmapHandle h, int field, buffer *buf0);

void parRSBHistogramSort(GenmapHandle h,GenmapComm c,int field,buffer *buf0);

struct parRSBHistogram_private {
GenmapLong *count;
GenmapScalar *probes;
};

#endif
75 changes: 75 additions & 0 deletions src/genmap-rcb.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#include <sort.h>
#include <float.h>
#include <parRSB.h>

void get_axis_len(double *length,struct array *a,struct comm *c,int ndim)
{
double min[MAXDIM],max[MAXDIM];
sint i;
for(i=0;i<ndim;i++) min[i]=DBL_MAX,max[i]=-DBL_MAX;

sint nel=a->n;
elm_rcb* elems=a->ptr;
for(i=0;i<nel;i++){
if(elems[i].coord[0]<min[0]) min[0]=elems[i].coord[0];
if(elems[i].coord[1]<min[1]) min[1]=elems[i].coord[1];
if(ndim==3)
if(elems[i].coord[2]<min[2]) min[2]=elems[i].coord[2];

if(elems[i].coord[0]>max[0]) max[0]=elems[i].coord[0];
if(elems[i].coord[1]>max[1]) max[1]=elems[i].coord[1];
if(ndim==3)
if(elems[i].coord[2]>max[2]) max[2]=elems[i].coord[2];
}

double buf[MAXDIM];
comm_allreduce(c,gs_double,gs_min,min,MAXDIM,buf);
comm_allreduce(c,gs_double,gs_max,max,MAXDIM,buf);

for(i=0;i<ndim;i++)
length[i]=max[i]-min[i];
}

int parRCB(struct comm *ci,struct array *a,int ndim){
struct comm c; comm_dup(&c,ci);

uint offsets[3]={offsetof(elm_rcb,coord[0]),
offsetof(elm_rcb,coord[1]),offsetof(elm_rcb,coord[2])};

double length[MAXDIM];

sint rank=c.id;
sint size=c.np;

if(rank == 0)
printf("running RCB "), fflush(stdout);

while(size>1){
get_axis_len(length,a,&c,ndim);

int axis1=0,d;
for(d=1;d<ndim;d++)
if(length[d]>length[axis1]) axis1=d;
int axis2=(axis1+1)%2;
for(d=0;d<ndim;d++)
if(length[d]>length[axis2] && d!=axis1) axis2=d;

uint off=offsets[axis1];
parallel_sort(elm_rcb,a,off,gs_double,&c);

int p=(size+1)/2;
int bin=(rank>=p);

comm_ext old=c.c;
#ifdef MPI
MPI_Comm new; MPI_Comm_split(old,bin,rank,&new);
comm_free(&c); comm_init(&c,new);
MPI_Comm_free(&new);
#endif
rank=c.id;
size=c.np;
}

comm_free(&c);
return 0;
}
3 changes: 0 additions & 3 deletions src/genmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ int GenmapInit(GenmapHandle *h, GenmapCommExternal ce) {
h_->dbgLevel = 0;
h_->printStat = 0;

GenmapMalloc(1,&h_->histogram);
return 0;
}

Expand All @@ -29,8 +28,6 @@ int GenmapFinalize(GenmapHandle h) {

array_free(&(h->elementArray));

GenmapFree(h->histogram);

GenmapFree(h);

return 0;
Expand Down
1 change: 0 additions & 1 deletion src/genmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ typedef struct GenmapComm_private *GenmapComm;
typedef struct GenmapHandle_private *GenmapHandle;
typedef struct GenmapVector_private *GenmapVector;
typedef struct GenmapElement_private *GenmapElements;
typedef struct parRSBHistogram_private *parRSBHistogram;

int GenmapInit(GenmapHandle *h, GenmapCommExternal ce);
int GenmapFinalize(GenmapHandle h);
Expand Down
88 changes: 88 additions & 0 deletions src/parRCB.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <time.h>

#include <sort.h>
#include <parRSB.h>

void fparRCB_partMesh(int *part,double *vtx,int *nel,int *nv,
int *options,int *comm,int *err)
{
*err = 1;

comm_ext c; c = MPI_Comm_f2c(*comm);
*err=parRCB_partMesh(part,vtx,*nel,*nv,options,c);
}

int parRCB_partMesh(int *part,double *vtx,int nel,int nv,
int *options,MPI_Comm comm)
{
struct comm c; comm_init(&c,comm);
int rank=c.id,size=c.np;

/* load balance input data */
slong out[2][1],buf[2][1];
slong nell=nel;
comm_scan(out,&c,gs_long,gs_add,&nell,1,&buf);
slong nelg_start=out[0][0];
slong nelg =out[1][0];

struct array a; array_init(elm_rcb,&a,nel);
elm_rcb *data=a.ptr;

int ndim=(nv==8)?3:2;

int e, n;
for(e=0;e<nel;++e){
data[e].id=nelg_start+(e+1);
data[e].orig=rank;
for(int n=0;n<ndim;n++)
data[e].coord[n]=vtx[e*ndim+n];
}
a.n=nel;

//TODO: load balance

struct comm rcb;
comm_ext old=c.c;
#ifdef MPI
MPI_Comm new; MPI_Comm_split(old,nel>0,rank,&new);
comm_init(&rcb,new); MPI_Comm_free(&new);
#else
comm_init(&rcb,1);
#endif

if(nel>0){
comm_barrier(&rcb);
double time=comm_time();

parRCB(&rcb,&a,ndim);

comm_barrier(&rcb);
time=comm_time()-time;

if(c.id==0)
printf(" finished in %lfs\n",time);
fflush(stdout);
}
comm_free(&rcb);

/* restore original input */
struct crystal cr; crystal_init(&cr,&c);
sarray_transfer(elm_rcb,&a,orig,1,&cr);
crystal_free(&cr);

comm_free(&c);

assert(a.n==nel);

buffer b; buffer_init(&b,1024);
sarray_sort(elm_rcb,a.ptr,a.n,id,1,&b);
buffer_free(&b);

data=a.ptr;
for(int e=0;e<nel;e++) part[e]=data[e].orig;

return 0;
}
2 changes: 1 addition & 1 deletion src/parRSB.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ int parRSB_partMesh(int *part, long long *vtx, int nel, int nve, int *options,
}

if(id == 0 && h->dbgLevel > 0)
printf("\nfinished in %lfs\n", comm_time() - time0);
printf(" finished in %lfs\n", comm_time() - time0);

GenmapFinalize(h);
fflush(stdout);
Expand Down
Loading

0 comments on commit bb51af9

Please sign in to comment.