mirror of
https://bitbucket.org/cosmicvoids/vide_public.git
synced 2025-07-04 23:31:12 +00:00
Merge branch 'master' of bitbucket.org:cosmicvoids/void_identification
This commit is contained in:
commit
f2cd2d6a8f
57 changed files with 13454 additions and 0 deletions
469
external/libsdf/libsw/GNUmakefile
vendored
Normal file
469
external/libsdf/libsw/GNUmakefile
vendored
Normal file
|
@ -0,0 +1,469 @@
|
|||
# Make.$(ARCH) sets many of the variables used below including:
|
||||
# CC, CFLAGS, AS, RANLIB, objdir, objsuf, asmdir
|
||||
|
||||
treedir=..
|
||||
treedir_sed=\.\.
|
||||
appexcludes=
|
||||
libname=libsw
|
||||
|
||||
# The "Salmon Warren Utility library"
|
||||
src:= \
|
||||
Malloc.c key.c \
|
||||
Msgs.c error.c files.c \
|
||||
chn.c dll.c \
|
||||
stk.c heap.c randoms.c \
|
||||
malloc.c gc.c byteswap.c \
|
||||
timers.c SDFwrite.c SDFread.c \
|
||||
ring.c qromo.c qromod.c \
|
||||
cosmo.c mpmy_combine.c counters.c \
|
||||
mpmy_gather.c memfile.c rsort.c \
|
||||
msgdirinit.c singlio.c abm.c \
|
||||
mpi_bcast.c mpi_reduce.c keycvt.c \
|
||||
peano.c SDFreadf.c hwclock.c
|
||||
|
||||
include $(treedir)/Make-common/Make.$(ARCH)
|
||||
|
||||
include $(treedir)/Make-common/Make.generic
|
||||
|
||||
# DO NOT DELETE THIS LINE -- make depend depends on it.
|
||||
|
||||
$(objdir)/Malloc$(objsuf):
|
||||
$(objdir)/Malloc$(objsuf):
|
||||
$(objdir)/Malloc$(objsuf):
|
||||
$(objdir)/Malloc$(objsuf):
|
||||
$(objdir)/Malloc$(objsuf):
|
||||
$(objdir)/Malloc$(objsuf):
|
||||
$(objdir)/Malloc$(objsuf):
|
||||
$(objdir)/Malloc$(objsuf):
|
||||
$(objdir)/Malloc$(objsuf):
|
||||
$(objdir)/Malloc$(objsuf):
|
||||
$(objdir)/Malloc$(objsuf):
|
||||
$(objdir)/Malloc$(objsuf):
|
||||
$(objdir)/Malloc$(objsuf): $(treedir)/include/libsdf/Msgs.h $(treedir)/include/libsdf/gccextensions.h
|
||||
$(objdir)/Malloc$(objsuf): $(treedir)/include/libsdf/Malloc.h $(treedir)/include/libsdf/error.h
|
||||
$(objdir)/Malloc$(objsuf):
|
||||
$(objdir)/Malloc$(objsuf):
|
||||
$(objdir)/Malloc$(objsuf):
|
||||
$(objdir)/Malloc$(objsuf):
|
||||
$(objdir)/key$(objsuf):
|
||||
$(objdir)/key$(objsuf):
|
||||
$(objdir)/key$(objsuf):
|
||||
$(objdir)/key$(objsuf):
|
||||
$(objdir)/key$(objsuf):
|
||||
$(objdir)/key$(objsuf):
|
||||
$(objdir)/key$(objsuf):
|
||||
$(objdir)/key$(objsuf): $(treedir)/include/libsdf/protos.h
|
||||
$(objdir)/Msgs$(objsuf):
|
||||
$(objdir)/Msgs$(objsuf):
|
||||
$(objdir)/Msgs$(objsuf):
|
||||
$(objdir)/Msgs$(objsuf):
|
||||
$(objdir)/Msgs$(objsuf):
|
||||
$(objdir)/Msgs$(objsuf):
|
||||
$(objdir)/Msgs$(objsuf):
|
||||
$(objdir)/Msgs$(objsuf):
|
||||
$(objdir)/Msgs$(objsuf): $(treedir)/include/libsdf/mpmy.h $(treedir)/include/libsdf/timers.h
|
||||
$(objdir)/Msgs$(objsuf):
|
||||
$(objdir)/Msgs$(objsuf): $(treedir)/include/libsdf/Malloc.h $(treedir)/include/libsdf/error.h
|
||||
$(objdir)/Msgs$(objsuf): $(treedir)/include/libsdf/gccextensions.h $(treedir)/include/libsdf/Msgs.h
|
||||
$(objdir)/Msgs$(objsuf): $(treedir)/include/libsdf/protos.h
|
||||
$(objdir)/error$(objsuf):
|
||||
$(objdir)/error$(objsuf):
|
||||
$(objdir)/error$(objsuf):
|
||||
$(objdir)/error$(objsuf):
|
||||
$(objdir)/error$(objsuf):
|
||||
$(objdir)/error$(objsuf):
|
||||
$(objdir)/error$(objsuf):
|
||||
$(objdir)/error$(objsuf):
|
||||
$(objdir)/error$(objsuf):
|
||||
$(objdir)/error$(objsuf):
|
||||
$(objdir)/error$(objsuf):
|
||||
$(objdir)/error$(objsuf):
|
||||
$(objdir)/error$(objsuf):
|
||||
$(objdir)/error$(objsuf):
|
||||
$(objdir)/error$(objsuf):
|
||||
$(objdir)/error$(objsuf):
|
||||
$(objdir)/error$(objsuf):
|
||||
$(objdir)/error$(objsuf):
|
||||
$(objdir)/error$(objsuf): $(treedir)/include/libsdf/error.h
|
||||
$(objdir)/error$(objsuf): $(treedir)/include/libsdf/gccextensions.h $(treedir)/include/libsdf/Msgs.h
|
||||
$(objdir)/error$(objsuf): $(treedir)/include/libsdf/mpmy.h $(treedir)/include/libsdf/timers.h
|
||||
$(objdir)/error$(objsuf):
|
||||
$(objdir)/error$(objsuf): $(treedir)/include/libsdf/mpmy_abnormal.h $(treedir)/include/libsdf/protos.h
|
||||
$(objdir)/error$(objsuf): $(treedir)/include/libsdf/memfile.h
|
||||
$(objdir)/files$(objsuf):
|
||||
$(objdir)/files$(objsuf):
|
||||
$(objdir)/files$(objsuf):
|
||||
$(objdir)/files$(objsuf):
|
||||
$(objdir)/files$(objsuf):
|
||||
$(objdir)/files$(objsuf):
|
||||
$(objdir)/files$(objsuf):
|
||||
$(objdir)/files$(objsuf):
|
||||
$(objdir)/files$(objsuf):
|
||||
$(objdir)/files$(objsuf):
|
||||
$(objdir)/files$(objsuf):
|
||||
$(objdir)/files$(objsuf):
|
||||
$(objdir)/files$(objsuf):
|
||||
$(objdir)/files$(objsuf): $(treedir)/include/libsdf/protos.h
|
||||
$(objdir)/files$(objsuf): $(treedir)/include/libsdf/Malloc.h $(treedir)/include/libsdf/error.h
|
||||
$(objdir)/files$(objsuf): $(treedir)/include/libsdf/gccextensions.h $(treedir)/include/libsdf/mpmy.h
|
||||
$(objdir)/files$(objsuf): $(treedir)/include/libsdf/timers.h
|
||||
$(objdir)/files$(objsuf):
|
||||
$(objdir)/chn$(objsuf): $(treedir)/include/libsdf/Assert.h $(treedir)/include/libsdf/error.h
|
||||
$(objdir)/chn$(objsuf): $(treedir)/include/libsdf/gccextensions.h $(treedir)/include/libsdf/chn.h
|
||||
$(objdir)/chn$(objsuf): $(treedir)/include/libsdf/Msgs.h
|
||||
$(objdir)/chn$(objsuf):
|
||||
$(objdir)/chn$(objsuf):
|
||||
$(objdir)/chn$(objsuf):
|
||||
$(objdir)/chn$(objsuf):
|
||||
$(objdir)/chn$(objsuf):
|
||||
$(objdir)/chn$(objsuf):
|
||||
$(objdir)/chn$(objsuf):
|
||||
$(objdir)/dll$(objsuf): $(treedir)/include/libsdf/chn.h $(treedir)/include/libsdf/Malloc.h
|
||||
$(objdir)/dll$(objsuf): $(treedir)/include/libsdf/error.h $(treedir)/include/libsdf/gccextensions.h
|
||||
$(objdir)/stk$(objsuf): $(treedir)/include/libsdf/Assert.h $(treedir)/include/libsdf/error.h
|
||||
$(objdir)/stk$(objsuf): $(treedir)/include/libsdf/gccextensions.h
|
||||
$(objdir)/heap$(objsuf): $(treedir)/include/libsdf/Assert.h $(treedir)/include/libsdf/error.h
|
||||
$(objdir)/heap$(objsuf): $(treedir)/include/libsdf/gccextensions.h $(treedir)/include/libsdf/Malloc.h
|
||||
$(objdir)/randoms$(objsuf): $(treedir)/include/libsdf/error.h $(treedir)/include/libsdf/gccextensions.h
|
||||
$(objdir)/malloc$(objsuf):
|
||||
$(objdir)/malloc$(objsuf):
|
||||
$(objdir)/malloc$(objsuf):
|
||||
$(objdir)/malloc$(objsuf):
|
||||
$(objdir)/malloc$(objsuf):
|
||||
$(objdir)/malloc$(objsuf):
|
||||
$(objdir)/malloc$(objsuf):
|
||||
$(objdir)/malloc$(objsuf):
|
||||
$(objdir)/malloc$(objsuf):
|
||||
$(objdir)/malloc$(objsuf):
|
||||
$(objdir)/malloc$(objsuf):
|
||||
$(objdir)/malloc$(objsuf):
|
||||
$(objdir)/malloc$(objsuf):
|
||||
$(objdir)/malloc$(objsuf):
|
||||
$(objdir)/malloc$(objsuf):
|
||||
$(objdir)/malloc$(objsuf):
|
||||
$(objdir)/malloc$(objsuf):
|
||||
$(objdir)/malloc$(objsuf): $(treedir)/include/libsdf/Msgs.h $(treedir)/include/libsdf/gccextensions.h
|
||||
$(objdir)/gc$(objsuf):
|
||||
$(objdir)/gc$(objsuf):
|
||||
$(objdir)/gc$(objsuf):
|
||||
$(objdir)/gc$(objsuf):
|
||||
$(objdir)/gc$(objsuf):
|
||||
$(objdir)/gc$(objsuf):
|
||||
$(objdir)/gc$(objsuf):
|
||||
$(objdir)/gc$(objsuf):
|
||||
$(objdir)/gc$(objsuf):
|
||||
$(objdir)/gc$(objsuf):
|
||||
$(objdir)/gc$(objsuf):
|
||||
$(objdir)/gc$(objsuf):
|
||||
$(objdir)/byteswap$(objsuf):
|
||||
$(objdir)/byteswap$(objsuf):
|
||||
$(objdir)/byteswap$(objsuf):
|
||||
$(objdir)/byteswap$(objsuf):
|
||||
$(objdir)/byteswap$(objsuf): $(treedir)/include/libsdf/byteswap.h
|
||||
$(objdir)/timers$(objsuf):
|
||||
$(objdir)/timers$(objsuf):
|
||||
$(objdir)/timers$(objsuf):
|
||||
$(objdir)/timers$(objsuf):
|
||||
$(objdir)/timers$(objsuf): $(treedir)/include/libsdf/Malloc.h $(treedir)/include/libsdf/error.h
|
||||
$(objdir)/timers$(objsuf): $(treedir)/include/libsdf/gccextensions.h $(treedir)/include/libsdf/timers.h
|
||||
$(objdir)/timers$(objsuf):
|
||||
$(objdir)/timers$(objsuf): $(treedir)/include/libsdf/mpmy.h $(treedir)/include/libsdf/mpmy_time.h
|
||||
$(objdir)/timers$(objsuf): $(treedir)/include/libsdf/Assert.h
|
||||
$(objdir)/SDFwrite$(objsuf):
|
||||
$(objdir)/SDFwrite$(objsuf):
|
||||
$(objdir)/SDFwrite$(objsuf):
|
||||
$(objdir)/SDFwrite$(objsuf):
|
||||
$(objdir)/SDFwrite$(objsuf):
|
||||
$(objdir)/SDFwrite$(objsuf):
|
||||
$(objdir)/SDFwrite$(objsuf):
|
||||
$(objdir)/SDFwrite$(objsuf):
|
||||
$(objdir)/SDFwrite$(objsuf):
|
||||
$(objdir)/SDFwrite$(objsuf):
|
||||
$(objdir)/SDFwrite$(objsuf):
|
||||
$(objdir)/SDFwrite$(objsuf):
|
||||
$(objdir)/SDFwrite$(objsuf):
|
||||
$(objdir)/SDFwrite$(objsuf):
|
||||
$(objdir)/SDFwrite$(objsuf):
|
||||
$(objdir)/SDFwrite$(objsuf):
|
||||
$(objdir)/SDFwrite$(objsuf):
|
||||
$(objdir)/SDFwrite$(objsuf):
|
||||
$(objdir)/SDFwrite$(objsuf):
|
||||
$(objdir)/SDFwrite$(objsuf):
|
||||
$(objdir)/SDFwrite$(objsuf):
|
||||
$(objdir)/SDFwrite$(objsuf):
|
||||
$(objdir)/SDFwrite$(objsuf):
|
||||
$(objdir)/SDFwrite$(objsuf):
|
||||
$(objdir)/SDFwrite$(objsuf):
|
||||
$(objdir)/SDFwrite$(objsuf): $(treedir)/include/libsdf/SDF.h $(treedir)/include/libsdf/SDFwrite.h
|
||||
$(objdir)/SDFwrite$(objsuf): $(treedir)/include/libsdf/Malloc.h $(treedir)/include/libsdf/error.h
|
||||
$(objdir)/SDFwrite$(objsuf): $(treedir)/include/libsdf/gccextensions.h $(treedir)/include/libsdf/mpmy.h
|
||||
$(objdir)/SDFwrite$(objsuf): $(treedir)/include/libsdf/timers.h
|
||||
$(objdir)/SDFwrite$(objsuf): $(treedir)/include/libsdf/mpmy_io.h
|
||||
$(objdir)/SDFwrite$(objsuf): $(treedir)/include/libsdf/Msgs.h $(treedir)/include/libsdf/protos.h
|
||||
$(objdir)/SDFwrite$(objsuf): $(treedir)/include/libsdf/singlio.h
|
||||
$(objdir)/SDFread$(objsuf):
|
||||
$(objdir)/SDFread$(objsuf):
|
||||
$(objdir)/SDFread$(objsuf):
|
||||
$(objdir)/SDFread$(objsuf):
|
||||
$(objdir)/SDFread$(objsuf):
|
||||
$(objdir)/SDFread$(objsuf):
|
||||
$(objdir)/SDFread$(objsuf):
|
||||
$(objdir)/SDFread$(objsuf):
|
||||
$(objdir)/SDFread$(objsuf):
|
||||
$(objdir)/SDFread$(objsuf):
|
||||
$(objdir)/SDFread$(objsuf):
|
||||
$(objdir)/SDFread$(objsuf):
|
||||
$(objdir)/SDFread$(objsuf):
|
||||
$(objdir)/SDFread$(objsuf):
|
||||
$(objdir)/SDFread$(objsuf):
|
||||
$(objdir)/SDFread$(objsuf):
|
||||
$(objdir)/SDFread$(objsuf):
|
||||
$(objdir)/SDFread$(objsuf):
|
||||
$(objdir)/SDFread$(objsuf):
|
||||
$(objdir)/SDFread$(objsuf):
|
||||
$(objdir)/SDFread$(objsuf):
|
||||
$(objdir)/SDFread$(objsuf): $(treedir)/include/libsdf/mpmy.h $(treedir)/include/libsdf/timers.h
|
||||
$(objdir)/SDFread$(objsuf):
|
||||
$(objdir)/SDFread$(objsuf): $(treedir)/include/libsdf/SDF.h $(treedir)/include/libsdf/Assert.h
|
||||
$(objdir)/SDFread$(objsuf): $(treedir)/include/libsdf/error.h $(treedir)/include/libsdf/gccextensions.h
|
||||
$(objdir)/SDFread$(objsuf): $(treedir)/include/libsdf/Malloc.h $(treedir)/include/libsdf/Msgs.h
|
||||
$(objdir)/SDFread$(objsuf): $(treedir)/include/libsdf/SDFread.h $(treedir)/include/libsdf/singlio.h
|
||||
$(objdir)/ring$(objsuf):
|
||||
$(objdir)/ring$(objsuf):
|
||||
$(objdir)/ring$(objsuf):
|
||||
$(objdir)/ring$(objsuf):
|
||||
$(objdir)/ring$(objsuf): $(treedir)/include/libsdf/Malloc.h $(treedir)/include/libsdf/error.h
|
||||
$(objdir)/ring$(objsuf): $(treedir)/include/libsdf/gccextensions.h $(treedir)/include/libsdf/mpmy.h
|
||||
$(objdir)/ring$(objsuf): $(treedir)/include/libsdf/timers.h
|
||||
$(objdir)/ring$(objsuf): $(treedir)/include/libsdf/Msgs.h
|
||||
$(objdir)/ring$(objsuf): $(treedir)/include/libsdf/singlio.h
|
||||
$(objdir)/qromo$(objsuf):
|
||||
$(objdir)/qromo$(objsuf):
|
||||
$(objdir)/qromo$(objsuf):
|
||||
$(objdir)/qromo$(objsuf):
|
||||
$(objdir)/qromo$(objsuf):
|
||||
$(objdir)/qromo$(objsuf):
|
||||
$(objdir)/qromo$(objsuf):
|
||||
$(objdir)/qromo$(objsuf): $(treedir)/include/libsdf/Malloc.h $(treedir)/include/libsdf/error.h
|
||||
$(objdir)/qromo$(objsuf): $(treedir)/include/libsdf/gccextensions.h
|
||||
$(objdir)/qromod$(objsuf):
|
||||
$(objdir)/qromod$(objsuf):
|
||||
$(objdir)/qromod$(objsuf):
|
||||
$(objdir)/qromod$(objsuf):
|
||||
$(objdir)/qromod$(objsuf):
|
||||
$(objdir)/qromod$(objsuf):
|
||||
$(objdir)/qromod$(objsuf):
|
||||
$(objdir)/qromod$(objsuf): $(treedir)/include/libsdf/Malloc.h $(treedir)/include/libsdf/error.h
|
||||
$(objdir)/qromod$(objsuf): $(treedir)/include/libsdf/gccextensions.h
|
||||
$(objdir)/cosmo$(objsuf):
|
||||
$(objdir)/cosmo$(objsuf):
|
||||
$(objdir)/cosmo$(objsuf):
|
||||
$(objdir)/cosmo$(objsuf):
|
||||
$(objdir)/cosmo$(objsuf):
|
||||
$(objdir)/cosmo$(objsuf):
|
||||
$(objdir)/cosmo$(objsuf):
|
||||
$(objdir)/cosmo$(objsuf):
|
||||
$(objdir)/cosmo$(objsuf):
|
||||
$(objdir)/cosmo$(objsuf):
|
||||
$(objdir)/cosmo$(objsuf):
|
||||
$(objdir)/cosmo$(objsuf):
|
||||
$(objdir)/cosmo$(objsuf):
|
||||
$(objdir)/cosmo$(objsuf):
|
||||
$(objdir)/cosmo$(objsuf):
|
||||
$(objdir)/cosmo$(objsuf): $(treedir)/include/libsdf/Msgs.h
|
||||
$(objdir)/cosmo$(objsuf): $(treedir)/include/libsdf/gccextensions.h $(treedir)/include/libsdf/cosmo.h
|
||||
$(objdir)/mpmy_combine$(objsuf):
|
||||
$(objdir)/mpmy_combine$(objsuf):
|
||||
$(objdir)/mpmy_combine$(objsuf):
|
||||
$(objdir)/mpmy_combine$(objsuf):
|
||||
$(objdir)/mpmy_combine$(objsuf):
|
||||
$(objdir)/mpmy_combine$(objsuf):
|
||||
$(objdir)/mpmy_combine$(objsuf):
|
||||
$(objdir)/mpmy_combine$(objsuf):
|
||||
$(objdir)/mpmy_combine$(objsuf):
|
||||
$(objdir)/mpmy_combine$(objsuf):
|
||||
$(objdir)/mpmy_combine$(objsuf): $(treedir)/include/libsdf/Malloc.h $(treedir)/include/libsdf/error.h
|
||||
$(objdir)/mpmy_combine$(objsuf): $(treedir)/include/libsdf/gccextensions.h
|
||||
$(objdir)/mpmy_combine$(objsuf): $(treedir)/include/libsdf/mpmy.h $(treedir)/include/libsdf/timers.h
|
||||
$(objdir)/mpmy_combine$(objsuf):
|
||||
$(objdir)/mpmy_combine$(objsuf): $(treedir)/include/libsdf/Msgs.h op_template.c
|
||||
$(objdir)/counters$(objsuf):
|
||||
$(objdir)/counters$(objsuf):
|
||||
$(objdir)/counters$(objsuf):
|
||||
$(objdir)/counters$(objsuf):
|
||||
$(objdir)/counters$(objsuf): $(treedir)/include/libsdf/Malloc.h $(treedir)/include/libsdf/error.h
|
||||
$(objdir)/counters$(objsuf): $(treedir)/include/libsdf/gccextensions.h
|
||||
$(objdir)/counters$(objsuf): $(treedir)/include/libsdf/timers.h
|
||||
$(objdir)/counters$(objsuf): $(treedir)/include/libsdf/mpmy.h
|
||||
$(objdir)/counters$(objsuf): $(treedir)/include/libsdf/Assert.h
|
||||
$(objdir)/mpmy_gather$(objsuf):
|
||||
$(objdir)/mpmy_gather$(objsuf):
|
||||
$(objdir)/mpmy_gather$(objsuf):
|
||||
$(objdir)/mpmy_gather$(objsuf):
|
||||
$(objdir)/mpmy_gather$(objsuf):
|
||||
$(objdir)/mpmy_gather$(objsuf):
|
||||
$(objdir)/mpmy_gather$(objsuf):
|
||||
$(objdir)/mpmy_gather$(objsuf):
|
||||
$(objdir)/mpmy_gather$(objsuf):
|
||||
$(objdir)/mpmy_gather$(objsuf):
|
||||
$(objdir)/mpmy_gather$(objsuf):
|
||||
$(objdir)/mpmy_gather$(objsuf): $(treedir)/include/libsdf/mpmy.h $(treedir)/include/libsdf/timers.h
|
||||
$(objdir)/mpmy_gather$(objsuf):
|
||||
$(objdir)/mpmy_gather$(objsuf): $(treedir)/include/libsdf/Msgs.h
|
||||
$(objdir)/mpmy_gather$(objsuf): $(treedir)/include/libsdf/gccextensions.h
|
||||
$(objdir)/mpmy_gather$(objsuf): $(treedir)/include/libsdf/Malloc.h $(treedir)/include/libsdf/error.h
|
||||
$(objdir)/memfile$(objsuf):
|
||||
$(objdir)/memfile$(objsuf):
|
||||
$(objdir)/memfile$(objsuf):
|
||||
$(objdir)/memfile$(objsuf):
|
||||
$(objdir)/memfile$(objsuf):
|
||||
$(objdir)/memfile$(objsuf):
|
||||
$(objdir)/memfile$(objsuf):
|
||||
$(objdir)/memfile$(objsuf):
|
||||
$(objdir)/memfile$(objsuf): $(treedir)/include/libsdf/Malloc.h
|
||||
$(objdir)/memfile$(objsuf): $(treedir)/include/libsdf/error.h $(treedir)/include/libsdf/gccextensions.h
|
||||
$(objdir)/memfile$(objsuf): $(treedir)/include/libsdf/Msgs.h $(treedir)/include/libsdf/protos.h
|
||||
$(objdir)/memfile$(objsuf): $(treedir)/include/libsdf/mpmy.h $(treedir)/include/libsdf/timers.h
|
||||
$(objdir)/memfile$(objsuf):
|
||||
$(objdir)/rsort$(objsuf):
|
||||
$(objdir)/rsort$(objsuf):
|
||||
$(objdir)/rsort$(objsuf):
|
||||
$(objdir)/rsort$(objsuf):
|
||||
$(objdir)/rsort$(objsuf):
|
||||
$(objdir)/rsort$(objsuf):
|
||||
$(objdir)/rsort$(objsuf):
|
||||
$(objdir)/rsort$(objsuf):
|
||||
$(objdir)/rsort$(objsuf):
|
||||
$(objdir)/rsort$(objsuf):
|
||||
$(objdir)/rsort$(objsuf):
|
||||
$(objdir)/rsort$(objsuf):
|
||||
$(objdir)/rsort$(objsuf): $(treedir)/include/libsdf/Malloc.h
|
||||
$(objdir)/rsort$(objsuf): $(treedir)/include/libsdf/error.h $(treedir)/include/libsdf/gccextensions.h
|
||||
$(objdir)/msgdirinit$(objsuf):
|
||||
$(objdir)/msgdirinit$(objsuf):
|
||||
$(objdir)/msgdirinit$(objsuf):
|
||||
$(objdir)/msgdirinit$(objsuf):
|
||||
$(objdir)/msgdirinit$(objsuf):
|
||||
$(objdir)/msgdirinit$(objsuf):
|
||||
$(objdir)/msgdirinit$(objsuf):
|
||||
$(objdir)/msgdirinit$(objsuf):
|
||||
$(objdir)/msgdirinit$(objsuf):
|
||||
$(objdir)/msgdirinit$(objsuf):
|
||||
$(objdir)/msgdirinit$(objsuf):
|
||||
$(objdir)/msgdirinit$(objsuf):
|
||||
$(objdir)/msgdirinit$(objsuf):
|
||||
$(objdir)/msgdirinit$(objsuf):
|
||||
$(objdir)/msgdirinit$(objsuf):
|
||||
$(objdir)/msgdirinit$(objsuf):
|
||||
$(objdir)/msgdirinit$(objsuf):
|
||||
$(objdir)/msgdirinit$(objsuf):
|
||||
$(objdir)/msgdirinit$(objsuf):
|
||||
$(objdir)/msgdirinit$(objsuf):
|
||||
$(objdir)/msgdirinit$(objsuf):
|
||||
$(objdir)/msgdirinit$(objsuf): $(treedir)/include/libsdf/Malloc.h
|
||||
$(objdir)/msgdirinit$(objsuf): $(treedir)/include/libsdf/error.h
|
||||
$(objdir)/msgdirinit$(objsuf): $(treedir)/include/libsdf/gccextensions.h
|
||||
$(objdir)/msgdirinit$(objsuf): $(treedir)/include/libsdf/mpmy_abnormal.h
|
||||
$(objdir)/msgdirinit$(objsuf): $(treedir)/include/libsdf/protos.h $(treedir)/include/libsdf/Msgs.h
|
||||
$(objdir)/msgdirinit$(objsuf): $(treedir)/include/libsdf/mpmy.h $(treedir)/include/libsdf/timers.h
|
||||
$(objdir)/msgdirinit$(objsuf):
|
||||
$(objdir)/msgdirinit$(objsuf): $(treedir)/include/libsdf/mpmy_io.h
|
||||
$(objdir)/singlio$(objsuf):
|
||||
$(objdir)/singlio$(objsuf):
|
||||
$(objdir)/singlio$(objsuf):
|
||||
$(objdir)/singlio$(objsuf):
|
||||
$(objdir)/singlio$(objsuf):
|
||||
$(objdir)/singlio$(objsuf):
|
||||
$(objdir)/singlio$(objsuf):
|
||||
$(objdir)/singlio$(objsuf): $(treedir)/include/libsdf/protos.h
|
||||
$(objdir)/singlio$(objsuf): $(treedir)/include/libsdf/mpmy.h $(treedir)/include/libsdf/timers.h
|
||||
$(objdir)/singlio$(objsuf):
|
||||
$(objdir)/singlio$(objsuf): $(treedir)/include/libsdf/Msgs.h $(treedir)/include/libsdf/gccextensions.h
|
||||
$(objdir)/singlio$(objsuf): $(treedir)/include/libsdf/singlio.h
|
||||
$(objdir)/abm$(objsuf):
|
||||
$(objdir)/abm$(objsuf):
|
||||
$(objdir)/abm$(objsuf):
|
||||
$(objdir)/abm$(objsuf):
|
||||
$(objdir)/abm$(objsuf):
|
||||
$(objdir)/abm$(objsuf):
|
||||
$(objdir)/abm$(objsuf):
|
||||
$(objdir)/abm$(objsuf):
|
||||
$(objdir)/abm$(objsuf):
|
||||
$(objdir)/abm$(objsuf):
|
||||
$(objdir)/abm$(objsuf):
|
||||
$(objdir)/abm$(objsuf):
|
||||
$(objdir)/abm$(objsuf):
|
||||
$(objdir)/abm$(objsuf):
|
||||
$(objdir)/abm$(objsuf):
|
||||
$(objdir)/abm$(objsuf): $(treedir)/include/libsdf/protos.h $(treedir)/include/libsdf/Assert.h
|
||||
$(objdir)/abm$(objsuf): $(treedir)/include/libsdf/error.h $(treedir)/include/libsdf/gccextensions.h
|
||||
$(objdir)/abm$(objsuf): $(treedir)/include/libsdf/mpmy.h $(treedir)/include/libsdf/timers.h
|
||||
$(objdir)/abm$(objsuf):
|
||||
$(objdir)/abm$(objsuf): $(treedir)/include/libsdf/Malloc.h $(treedir)/include/libsdf/Msgs.h
|
||||
$(objdir)/mpi_bcast$(objsuf): $(treedir)/include/libsdf/Msgs.h
|
||||
$(objdir)/mpi_bcast$(objsuf): $(treedir)/include/libsdf/gccextensions.h
|
||||
$(objdir)/mpi_bcast$(objsuf): $(treedir)/include/libsdf/error.h
|
||||
$(objdir)/mpi_reduce$(objsuf):
|
||||
$(objdir)/mpi_reduce$(objsuf):
|
||||
$(objdir)/mpi_reduce$(objsuf):
|
||||
$(objdir)/mpi_reduce$(objsuf):
|
||||
$(objdir)/mpi_reduce$(objsuf):
|
||||
$(objdir)/mpi_reduce$(objsuf):
|
||||
$(objdir)/mpi_reduce$(objsuf):
|
||||
$(objdir)/mpi_reduce$(objsuf):
|
||||
$(objdir)/mpi_reduce$(objsuf):
|
||||
$(objdir)/mpi_reduce$(objsuf):
|
||||
$(objdir)/mpi_reduce$(objsuf):
|
||||
$(objdir)/mpi_reduce$(objsuf):
|
||||
$(objdir)/mpi_reduce$(objsuf):
|
||||
$(objdir)/mpi_reduce$(objsuf): $(treedir)/include/libsdf/Msgs.h
|
||||
$(objdir)/mpi_reduce$(objsuf): $(treedir)/include/libsdf/gccextensions.h
|
||||
$(objdir)/mpi_reduce$(objsuf): $(treedir)/include/libsdf/error.h mpi_template.c
|
||||
$(objdir)/keycvt$(objsuf): $(treedir)/include/libsdf/protos.h $(treedir)/include/libsdf/mpmy.h
|
||||
$(objdir)/keycvt$(objsuf): $(treedir)/include/libsdf/timers.h
|
||||
$(objdir)/keycvt$(objsuf):
|
||||
$(objdir)/keycvt$(objsuf):
|
||||
$(objdir)/keycvt$(objsuf):
|
||||
$(objdir)/keycvt$(objsuf): $(treedir)/include/libsdf/Msgs.h
|
||||
$(objdir)/keycvt$(objsuf): $(treedir)/include/libsdf/gccextensions.h $(treedir)/include/libsdf/Assert.h
|
||||
$(objdir)/keycvt$(objsuf): $(treedir)/include/libsdf/error.h
|
||||
$(objdir)/peano$(objsuf): $(treedir)/include/libsdf/Msgs.h $(treedir)/include/libsdf/gccextensions.h
|
||||
$(objdir)/peano$(objsuf): $(treedir)/include/libsdf/Assert.h $(treedir)/include/libsdf/error.h
|
||||
$(objdir)/SDFreadf$(objsuf):
|
||||
$(objdir)/SDFreadf$(objsuf):
|
||||
$(objdir)/SDFreadf$(objsuf):
|
||||
$(objdir)/SDFreadf$(objsuf):
|
||||
$(objdir)/SDFreadf$(objsuf):
|
||||
$(objdir)/SDFreadf$(objsuf):
|
||||
$(objdir)/SDFreadf$(objsuf):
|
||||
$(objdir)/SDFreadf$(objsuf):
|
||||
$(objdir)/SDFreadf$(objsuf):
|
||||
$(objdir)/SDFreadf$(objsuf):
|
||||
$(objdir)/SDFreadf$(objsuf):
|
||||
$(objdir)/SDFreadf$(objsuf):
|
||||
$(objdir)/SDFreadf$(objsuf):
|
||||
$(objdir)/SDFreadf$(objsuf):
|
||||
$(objdir)/SDFreadf$(objsuf):
|
||||
$(objdir)/SDFreadf$(objsuf):
|
||||
$(objdir)/SDFreadf$(objsuf):
|
||||
$(objdir)/SDFreadf$(objsuf):
|
||||
$(objdir)/SDFreadf$(objsuf):
|
||||
$(objdir)/SDFreadf$(objsuf):
|
||||
$(objdir)/SDFreadf$(objsuf):
|
||||
$(objdir)/SDFreadf$(objsuf): $(treedir)/include/libsdf/mpmy.h
|
||||
$(objdir)/SDFreadf$(objsuf): $(treedir)/include/libsdf/timers.h
|
||||
$(objdir)/SDFreadf$(objsuf): $(treedir)/include/libsdf/SDF.h
|
||||
$(objdir)/SDFreadf$(objsuf): $(treedir)/include/libsdf/Assert.h $(treedir)/include/libsdf/error.h
|
||||
$(objdir)/SDFreadf$(objsuf): $(treedir)/include/libsdf/gccextensions.h
|
||||
$(objdir)/SDFreadf$(objsuf): $(treedir)/include/libsdf/Malloc.h $(treedir)/include/libsdf/Msgs.h
|
||||
$(objdir)/SDFreadf$(objsuf): $(treedir)/include/libsdf/SDFread.h $(treedir)/include/libsdf/singlio.h
|
||||
$(objdir)/hwclock$(objsuf):
|
||||
$(objdir)/hwclock$(objsuf):
|
||||
$(objdir)/hwclock$(objsuf):
|
||||
$(objdir)/hwclock$(objsuf):
|
||||
$(objdir)/hwclock$(objsuf):
|
||||
$(objdir)/hwclock$(objsuf):
|
||||
$(objdir)/hwclock$(objsuf):
|
||||
$(objdir)/hwclock$(objsuf):
|
||||
$(objdir)/hwclock$(objsuf): $(treedir)/include/libsdf/error.h
|
||||
$(objdir)/hwclock$(objsuf): $(treedir)/include/libsdf/gccextensions.h
|
139
external/libsdf/libsw/Malloc.c
vendored
Normal file
139
external/libsdf/libsw/Malloc.c
vendored
Normal file
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* Copyright 1991 Michael S. Warren and John K. Salmon. All Rights Reserved.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include "Msgs.h"
|
||||
#include "Malloc.h"
|
||||
#include "malloc.h"
|
||||
|
||||
#define WARNSIZEINITIAL (1024L*1024*1024*2)
|
||||
static size_t WarnSize = WARNSIZEINITIAL;
|
||||
|
||||
#include "error.h"
|
||||
|
||||
static void Error_and_mprint(const char *fmt, ...){
|
||||
va_list alist;
|
||||
malloc_print();
|
||||
va_start(alist, fmt);
|
||||
vError(fmt, alist);
|
||||
va_end(alist);
|
||||
}
|
||||
|
||||
/* Try to do this without the typedef Error_t!!! */
|
||||
static Error_t reporter = Error_and_mprint;
|
||||
|
||||
Error_t MallocHandler(Error_t new){
|
||||
Error_t ret = reporter;
|
||||
reporter = new;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
xFree(void *ptr, const char *file, int lineno)
|
||||
{
|
||||
Msgf(("%s(%d): f(%#lx)\n", file, lineno, (unsigned long)ptr));
|
||||
if( ptr != (void *)0 )
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
void *
|
||||
xMalloc(size_t size, const char *file, int lineno)
|
||||
{
|
||||
void *ptr;
|
||||
|
||||
Msgf(("%s(%d): m(%lu)=", file, lineno, (unsigned long)size));
|
||||
if (size > WarnSize){
|
||||
Shout("Large Malloc Warning, size %ld\n", (long)size);
|
||||
WarnSize *=2;
|
||||
}
|
||||
if (size == 0) {
|
||||
Msgf(("0x0"));
|
||||
return (void *)0;
|
||||
}
|
||||
ptr = malloc(size);
|
||||
if (ptr == (void *)0 && reporter) {
|
||||
reporter("%s(%d) Malloc(%ld) failed\n", file, lineno, (long)size);
|
||||
}
|
||||
Msgf(("%#lx\n", (unsigned long)ptr));
|
||||
return(ptr);
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
xRealloc(void *ptr, size_t size, const char *file, int lineno)
|
||||
{
|
||||
void *p1 = ptr;
|
||||
|
||||
Msgf(("%s(%d): r(%#lx,%lu)=", file, lineno, (unsigned long)ptr,
|
||||
(unsigned long)size));
|
||||
if (size > WarnSize){
|
||||
Shout("Large Realloc Warning, size %ld\n", (long)size);
|
||||
WarnSize *= 2;
|
||||
}
|
||||
|
||||
if( ptr == (void *)0 ){
|
||||
Msgf(("-> malloc\n"));
|
||||
return Malloc(size);
|
||||
}
|
||||
if( size == 0 ){
|
||||
Msgf(("-> free\n"));
|
||||
Free(ptr);
|
||||
return (void *)0;
|
||||
}
|
||||
ptr = realloc(ptr, size);
|
||||
if (ptr == (void *)0 && reporter) {
|
||||
reporter("%s(%d): Realloc(%p, %ld) failed\n", file, lineno, p1, (long)size);
|
||||
}
|
||||
Msgf(("%#lx\n", (unsigned long)ptr));
|
||||
return(ptr);
|
||||
}
|
||||
|
||||
void *
|
||||
xCalloc(size_t n, size_t s, const char *file, int lineno)
|
||||
{
|
||||
void *ptr;
|
||||
|
||||
Msgf(("%s(%d): c(%lu,%lu)=", file, lineno,
|
||||
(unsigned long)n, (unsigned long)s));
|
||||
if (n*s > WarnSize){
|
||||
Shout("Large Calloc Warning, size %ld\n", (long)n*s);
|
||||
WarnSize *= 2;
|
||||
}
|
||||
if( n==0 || s==0 ){
|
||||
Msgf(("0x0\n"));
|
||||
return (void *)0;
|
||||
}
|
||||
ptr = calloc(n,s);
|
||||
if (ptr == (void *)0 && reporter) {
|
||||
reporter("%s(%d): Calloc(%ld) failed\n", file, lineno, (long)n);
|
||||
}
|
||||
Msgf(("%#lx\n", (unsigned long)ptr));
|
||||
return(ptr);
|
||||
}
|
||||
|
||||
/* Use these, for example, when you pass a ptr-to-function arg */
|
||||
/* to another function. They call the macro version, which prints */
|
||||
/* a message. If you don't intend to ever use the old K&R /lib/cpp */
|
||||
/* pre-processor, then these are superfluous. You could pass, e.g. */
|
||||
/* foo(Realloc), and you could call these functions, e.g., Realloc */
|
||||
/* and everything would be fine... */
|
||||
|
||||
void *Realloc_f(void *ptr, size_t size){
|
||||
return Realloc(ptr, size);
|
||||
}
|
||||
|
||||
void *Malloc_f(size_t n){
|
||||
return Malloc(n);
|
||||
}
|
||||
|
||||
void *Calloc_f(size_t n, size_t s){
|
||||
return Calloc(n, s);
|
||||
}
|
||||
|
||||
void Free_f(void *p){
|
||||
Free(p);
|
||||
}
|
||||
/* void MallocOnNULLReturn(void (*printf_like)(const char *fmt, ...)) */
|
375
external/libsdf/libsw/Msgs.c
vendored
Normal file
375
external/libsdf/libsw/Msgs.c
vendored
Normal file
|
@ -0,0 +1,375 @@
|
|||
/*
|
||||
* This file implements a common mechanism for delivering messages
|
||||
* to the user. It also provides a way to selectively turn
|
||||
* on and off the status messages emanating from a part of the
|
||||
* program.
|
||||
* Call msg_on("foo"); to see all messages of the form:
|
||||
* msg("foo", ("printf-format", printf-args));
|
||||
* Note how __FILE__ can be used in place of "foo"...
|
||||
*
|
||||
* This file does not use <stdio.h>. This is because in the wonderful
|
||||
* world of distributed parallel, figuring out whose <stdio.h> you're getting
|
||||
* and whether or not the names have been secretly scrambled is a complete
|
||||
* nightmare. The solution is to make the user pass in two function pointers
|
||||
* that are supposed to behave like vfprintf and fflush, and a void * which
|
||||
* acts like a FILE * (when passed to the two functions). How the caller
|
||||
* arranges these functions is not our problem.
|
||||
* The down-side is that picky compilers may complain about not having
|
||||
* prototypes for sscanf. Too bad...
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h> /* only for sscanf! */
|
||||
#include "mpmy.h"
|
||||
#include "Malloc.h"
|
||||
#include "Msgs.h"
|
||||
#include "protos.h"
|
||||
|
||||
#ifndef Static
|
||||
#define Static static
|
||||
#endif
|
||||
|
||||
/* Don't increase MAXNAMES arbitrarily. If it grows much bigger */
|
||||
/* than O(100), a different search algorithm would be appropriate. */
|
||||
#define MAXNAMES 50
|
||||
|
||||
/* A substantially larger MAXFILES is probably a mistake. You'll run out */
|
||||
/* of file descriptors soon enough anyway. */
|
||||
#define MAXFILES 12
|
||||
|
||||
/* The sum of the lengths of all the NAMES (including terminal null). */
|
||||
#define NAMEPOOLLENGTH (MAXNAMES*32)
|
||||
|
||||
Static int nnames;
|
||||
Static struct nt_s{
|
||||
const char *name;
|
||||
int status;
|
||||
struct nt_s *next;
|
||||
} name_tbl[MAXNAMES], *first;
|
||||
|
||||
Static int nfiles;
|
||||
Static struct ft_s{
|
||||
void *fp;
|
||||
int (*vfprintf_like)(void *, const char *, va_list);
|
||||
int (*fflush_like)(void *);
|
||||
} file_tbl[MAXFILES];
|
||||
|
||||
char name_pool[NAMEPOOLLENGTH] ;
|
||||
char *poolptr = name_pool;
|
||||
char *poolend = name_pool + NAMEPOOLLENGTH;
|
||||
|
||||
Static int look_name(const char *name);
|
||||
Static int Msg_restriction(const char *arg);
|
||||
|
||||
int _Msg_enabled = 1;
|
||||
|
||||
Static int _Msg_flushalways = 0;
|
||||
Static int called_addfile = 0;
|
||||
|
||||
int Msg_addfile(void *fp,
|
||||
int (*vfprintf_like)(void *, const char *, va_list),
|
||||
int (*fflush_like)(void *)){
|
||||
if( nfiles == MAXFILES )
|
||||
return -1;
|
||||
|
||||
file_tbl[nfiles].fp = fp;
|
||||
file_tbl[nfiles].vfprintf_like = vfprintf_like;
|
||||
file_tbl[nfiles].fflush_like = fflush_like;
|
||||
nfiles++;
|
||||
called_addfile = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Msg_delfile(void *fp){
|
||||
int i;
|
||||
|
||||
for(i=0; i<nfiles && file_tbl[i].fp != fp; i++) ;
|
||||
|
||||
if( i==nfiles )
|
||||
return -1;
|
||||
if( i != --nfiles ){
|
||||
file_tbl[i] = file_tbl[nfiles];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Msg_nopen(void){
|
||||
return nfiles;
|
||||
}
|
||||
|
||||
int Msg_on(const char *name)
|
||||
{
|
||||
int i;
|
||||
i = look_name(name);
|
||||
if(i < 0){
|
||||
return i;
|
||||
}
|
||||
name_tbl[i].status = 1;
|
||||
Msg_do("Messages turned on for name %s\n", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Msg_off(const char *name)
|
||||
{
|
||||
int i;
|
||||
i = look_name(name);
|
||||
if(i < 0){
|
||||
return i;
|
||||
}
|
||||
name_tbl[i].status = 0;
|
||||
Msg_do("Messages turned off for name %s\n", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Msg_set_enable(int new)
|
||||
{
|
||||
int ret = _Msg_enabled;
|
||||
_Msg_enabled = new;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int _Msg_test(const char *name)
|
||||
{
|
||||
int i;
|
||||
i = look_name(name);
|
||||
if(i < 0)
|
||||
return 0;
|
||||
else
|
||||
return name_tbl[i].status;
|
||||
}
|
||||
|
||||
int Msg_flushalways(int new)
|
||||
{
|
||||
int ret = _Msg_flushalways;
|
||||
_Msg_flushalways = new;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Recursion is NOT your friend! */
|
||||
static int recursion;
|
||||
|
||||
int
|
||||
Msg_do(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
int i;
|
||||
struct ft_s *ft;
|
||||
int save;
|
||||
int extra = 0;
|
||||
|
||||
/* First, we try to actually prevent recursion */
|
||||
save = _Msg_enabled;
|
||||
/* And then we try to avoid catastrophe if it happened anyway. */
|
||||
if( recursion++ == 0 ){
|
||||
for(i=0; i<nfiles; i++){
|
||||
ft = &file_tbl[i];
|
||||
va_start(args, fmt);
|
||||
(*ft->vfprintf_like)(ft->fp, fmt, args);
|
||||
va_end(args);
|
||||
if( _Msg_flushalways && ft->fflush_like)
|
||||
(*ft->fflush_like)(ft->fp);
|
||||
}
|
||||
#ifndef NO_STDIO
|
||||
if( nfiles == 0 && !called_addfile ){
|
||||
va_start(args, fmt);
|
||||
vfprintf(stderr, fmt, args);
|
||||
if( _Msg_flushalways )
|
||||
fflush(stderr);
|
||||
va_end(args);
|
||||
extra = 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
--recursion;
|
||||
_Msg_enabled = save;
|
||||
return nfiles+extra;
|
||||
}
|
||||
|
||||
int
|
||||
Msg_doalist(const char *fmt, va_list alist)
|
||||
{
|
||||
int i;
|
||||
struct ft_s *ft;
|
||||
int save;
|
||||
int extra = 0;
|
||||
|
||||
save = _Msg_enabled;
|
||||
if( recursion++ == 0 ){
|
||||
for(i=0; i<nfiles; i++){
|
||||
ft = &file_tbl[i];
|
||||
(*ft->vfprintf_like)(ft->fp, fmt, alist);
|
||||
if( _Msg_flushalways && ft->fflush_like )
|
||||
(*ft->fflush_like)(ft->fp);
|
||||
}
|
||||
#ifndef NO_STDIO
|
||||
if( nfiles == 0 && !called_addfile ){
|
||||
vfprintf(stderr, fmt, alist);
|
||||
if( _Msg_flushalways )
|
||||
fflush(stderr);
|
||||
extra = 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
--recursion;
|
||||
_Msg_enabled = save;
|
||||
return nfiles+extra;
|
||||
}
|
||||
|
||||
void Msg_turnon(const char *msg_turn_on){
|
||||
char *copy;
|
||||
char *msg_key;
|
||||
|
||||
/* You can turn off msgs with a "nomsgs" or a null string or an */
|
||||
/* empty string. */
|
||||
if( msg_turn_on == NULL
|
||||
|| msg_turn_on[0] == '\0'
|
||||
|| strcmp(msg_turn_on, "nomsgs")==0 ){
|
||||
Msg_set_enable(0);
|
||||
return;
|
||||
}
|
||||
|
||||
copy = strcpy(Malloc(strlen(msg_turn_on)+1), msg_turn_on);
|
||||
/* Look for comma or space separated arguments to Msg_on */
|
||||
for(msg_key = strtok(copy, " ,\t\n");
|
||||
msg_key;
|
||||
msg_key = strtok(NULL, " ,\t\n")){
|
||||
char *restriction_begin = strchr(msg_key, ':');
|
||||
if( restriction_begin ){
|
||||
if( !Msg_restriction(restriction_begin+1) )
|
||||
continue;
|
||||
*restriction_begin='\0';
|
||||
}
|
||||
Msg_on(msg_key);
|
||||
Msg_do("Turning on Msgs for \"%s\"\n", msg_key);
|
||||
/* Do we need to add "./" to the key in addition??? */
|
||||
if( strncmp( __FILE__, "./", 2) == 0 &&
|
||||
strncmp( msg_key, "./", 2 ) != 0 ){
|
||||
char *dot_slash_key = Malloc(strlen(msg_key)+3);
|
||||
/* sprintf might be easier, but we are trying to avoid */
|
||||
/* using stdio. */
|
||||
/* sprintf(dot_slash_key, "./%s", msg_key) */
|
||||
strcpy(dot_slash_key, "./");
|
||||
strcat(dot_slash_key, msg_key);
|
||||
Msg_on(dot_slash_key);
|
||||
Msg_do("Turning on Msgs for \"%s\"\n", dot_slash_key);
|
||||
Free(dot_slash_key);
|
||||
}
|
||||
}
|
||||
Free(copy);
|
||||
}
|
||||
|
||||
int Msg_flush(void)
|
||||
{
|
||||
int i, ret;
|
||||
struct ft_s *ft;
|
||||
int save;
|
||||
|
||||
save = _Msg_enabled;
|
||||
ret = 0;
|
||||
if( recursion++ == 0 ){
|
||||
for(i=0; i<nfiles; i++){
|
||||
ft = &file_tbl[i];
|
||||
if( ft->fflush_like )
|
||||
ret |= (*ft->fflush_like)(ft->fp);
|
||||
}
|
||||
}
|
||||
--recursion;
|
||||
_Msg_enabled = save;
|
||||
return ret;
|
||||
}
|
||||
|
||||
Static int look_name(const char *name)
|
||||
{
|
||||
int i;
|
||||
struct nt_s *last, *this;
|
||||
unsigned int len;
|
||||
|
||||
last = NULL;
|
||||
this = first;
|
||||
if( name == NULL ){
|
||||
Warning("look_name(NULL)\n");
|
||||
return -1;
|
||||
}
|
||||
while( this && this->name && strcmp(name, this->name) != 0 ) {
|
||||
last = this;
|
||||
this = this->next;
|
||||
}
|
||||
if( this ){
|
||||
if( last ){
|
||||
last->next = this->next;
|
||||
this->next = first;
|
||||
first = this;
|
||||
}
|
||||
return this - name_tbl;
|
||||
}else{
|
||||
/* Create a new entry. Add it to the front. */
|
||||
/* NOTE: we never free any of this! */
|
||||
if(nnames == MAXNAMES){
|
||||
return -1;
|
||||
}
|
||||
len = strlen(name)+1;
|
||||
if( poolptr + len >= poolend ){
|
||||
return -1;
|
||||
}
|
||||
i = nnames++;
|
||||
strcpy(poolptr, name);
|
||||
|
||||
name_tbl[i].name = poolptr;
|
||||
poolptr += len;
|
||||
name_tbl[i].next = first;
|
||||
first = &name_tbl[i];
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
Static int Msg_restriction(const char *arg){
|
||||
int first, last;
|
||||
|
||||
if( strchr(arg, '-') ){
|
||||
if( sscanf(arg, "%d-%d", &first, &last) != 2 ){
|
||||
Msg_do("Unparseable msg restriction: \"%s\"\n", arg);
|
||||
return 0;
|
||||
}
|
||||
return MPMY_Procnum() <= last && MPMY_Procnum()>= first ;
|
||||
}else{
|
||||
if( sscanf(arg, "%d", &first) != 1 ){
|
||||
Msg_do("Unparseable msg restriction: \"%s\"\n", arg);
|
||||
return 0;
|
||||
}
|
||||
return MPMY_Procnum() == first;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef STANDALONE
|
||||
#include <stdio.h>
|
||||
/* Of course, Sun's stdio.h doesn't declare fflush or vfprintf! */
|
||||
int vfprintf(FILE *, const char *, va_list);
|
||||
int fflush(FILE *);
|
||||
|
||||
main(int argc, char **argv){
|
||||
FILE *aux;
|
||||
|
||||
Msg_addfile(stdout, vfprintf, fflush);
|
||||
|
||||
aux = fopen("Msg.out", "w");
|
||||
if( aux == NULL ){
|
||||
fprintf(stderr, "Couldn't fopen("Msg.out"), errno=%d\n", errno);
|
||||
exit(1);
|
||||
}
|
||||
Msg_addfile(aux, vfprintf, fflush);
|
||||
Msg_on("foo");
|
||||
Msg("foo", ("Hello world foo seventeen=%d\n", 17));
|
||||
Msg("bar", ("Hello bar"));
|
||||
Msg_on("Msgs.c");
|
||||
Msg_on("bar");
|
||||
Msg("bar", ("Hello bar pi=%g\n", 3.14159));
|
||||
Msglno("bar", ("What was that value again??... %g\n,", 3.1415));
|
||||
Msgf(("This is a Msgf message.\n"));
|
||||
Msg_off("foo");
|
||||
Msg_off(__FILE__);
|
||||
Msgf(("This is a blocked Msgf message.\n"));
|
||||
Msg("foo", ("Not seen.\n"));
|
||||
exit(0);
|
||||
}
|
||||
#endif
|
||||
|
290
external/libsdf/libsw/SDFread.c
vendored
Normal file
290
external/libsdf/libsw/SDFread.c
vendored
Normal file
|
@ -0,0 +1,290 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
#include "mpmy.h"
|
||||
#include "SDF.h"
|
||||
#include "Assert.h"
|
||||
#include "Malloc.h"
|
||||
#include "Msgs.h"
|
||||
#include "error.h"
|
||||
#include "verify.h"
|
||||
#include "SDFread.h"
|
||||
#include "gc.h"
|
||||
#include "singlio.h"
|
||||
#include "timers.h"
|
||||
|
||||
#define MAXNAMES 64
|
||||
|
||||
Timer_t SDFreadTm;
|
||||
|
||||
/* These ought to be arguments to SDFread, but that breaks too many
|
||||
things that call SDFread. The varargs makes creating a wrapper a pain. */
|
||||
char *SDFread_datafile = "datafile";
|
||||
char *SDFread_hdrfile = "hdrfile";
|
||||
char *SDFread_npart = "npart";
|
||||
|
||||
SDF *SDFread(SDF *csdfp, void **btabp, int *gnobjp, int *nobjp,
|
||||
int stride,
|
||||
/* char *name, offset_t offset, int *confirm */...)
|
||||
{
|
||||
va_list ap;
|
||||
char name[256];
|
||||
int start;
|
||||
SDF *sdfp;
|
||||
int gnobj, nobj;
|
||||
void *btab;
|
||||
int Nfiles, procs_per_file, myfile, mysection;
|
||||
char hdrname[256];
|
||||
void *addrs[MAXNAMES];
|
||||
char *names[MAXNAMES];
|
||||
int strides[MAXNAMES];
|
||||
int nobjs[MAXNAMES];
|
||||
int64_t starts[MAXNAMES];
|
||||
int *confirm;
|
||||
int nnames;
|
||||
int sz = 0;
|
||||
|
||||
EnableTimer(&SDFreadTm, "SDFread");
|
||||
StartTimer(&SDFreadTm);
|
||||
|
||||
if( !SDFread_datafile || !SDFhasname(SDFread_datafile, csdfp) ){
|
||||
sdfp = csdfp;
|
||||
SinglWarning("SDFread: Looking for data in 'control' file\n");
|
||||
Nfiles = 1;
|
||||
}else{
|
||||
sdfp = NULL;
|
||||
Nfiles = SDFnrecs(SDFread_datafile, csdfp);
|
||||
if( Nfiles > MPMY_Nproc() || Nfiles < 0){
|
||||
SinglError("Sorry, bad Nfiles (%d)!\n", Nfiles);
|
||||
}
|
||||
}
|
||||
|
||||
/* Pick out which file in the control file will be ours. */
|
||||
/* and which "section" of the file. */
|
||||
procs_per_file = MPMY_Nproc()/Nfiles;
|
||||
Verify(procs_per_file*Nfiles == MPMY_Nproc());
|
||||
myfile = MPMY_Procnum()/procs_per_file;
|
||||
mysection = MPMY_Procnum()%procs_per_file;
|
||||
|
||||
if( sdfp == NULL ){
|
||||
VerifySX(0==SDFseekrdvecs(csdfp,
|
||||
SDFread_datafile, myfile, 1, name, sizeof(name),
|
||||
NULL),
|
||||
SinglShout("%s", SDFerrstring));
|
||||
if( SDFread_hdrfile )
|
||||
SDFgetstringOrDefault(csdfp, SDFread_hdrfile, hdrname, sizeof(hdrname), "");
|
||||
else
|
||||
hdrname[0] = '\0';
|
||||
|
||||
/* This was moved from above where it used name unitialized */
|
||||
if (hdrname[0] && SDFissdf(name) ) {
|
||||
SinglWarning("Superfluous headerfile %s ignored\n", hdrname);
|
||||
hdrname[0] = '\0';
|
||||
}
|
||||
VerifySX(sdfp = SDFopen(hdrname, name),SinglShout("%s", SDFerrstring));
|
||||
}else{
|
||||
strncpy(name, "<SDF file>", sizeof(name));
|
||||
}
|
||||
|
||||
if( SDFbyteorder(sdfp) == 0 ){
|
||||
int swap;
|
||||
/* The data/hdr file itself doesn't specify a byte order. */
|
||||
SDFgetintOrDefault(csdfp, "swapbytes", &swap, 0);
|
||||
if( swap )
|
||||
SDFswap(sdfp);
|
||||
/* If there's no byteorder specified, then it won't swap */
|
||||
}
|
||||
|
||||
if( SDFread_npart && SDFgetint(sdfp, SDFread_npart, &gnobj) ){
|
||||
/* Hopefully calling va_start and va_end in here won't disturb */
|
||||
/* the real loop over arguments below... */
|
||||
va_start(ap, stride);
|
||||
names[0] = va_arg(ap, char *);
|
||||
gnobj = SDFnrecs(names[0], sdfp);
|
||||
va_end(ap);
|
||||
if( MPMY_Procnum() == 0 ){
|
||||
SinglShout("%s does not have an \"%s\".\n", name, SDFread_npart);
|
||||
SinglShout("Guessing %s=%d from SDFnrecs(., %s)\n",
|
||||
SDFread_npart, gnobj, names[0]);
|
||||
}
|
||||
}
|
||||
|
||||
NobjInitial(gnobj, procs_per_file, mysection, &nobj, &start);
|
||||
btab = Calloc(nobj, stride);
|
||||
Msgf(("Proc %d starting at %d in file, reading %d of %d\n",
|
||||
MPMY_Procnum(), start, nobj, gnobj));
|
||||
|
||||
nnames = 0;
|
||||
va_start(ap, stride);
|
||||
while(( names[nnames] = va_arg(ap, char *)) != NULL ){
|
||||
assert(nnames < MAXNAMES);
|
||||
addrs[nnames] = va_arg(ap, int) + (char *)btab;
|
||||
confirm = va_arg(ap, int *);
|
||||
if( !SDFhasname(names[nnames], sdfp) ){
|
||||
*confirm = 0;
|
||||
Msgf(("SDF file does not have %s\n", names[nnames]));
|
||||
continue;
|
||||
}else{
|
||||
*confirm = 1;
|
||||
}
|
||||
starts[nnames] = start;
|
||||
nobjs[nnames] = nobj;
|
||||
sz += SDFtype_sizes[SDFtype(names[nnames], sdfp)];
|
||||
strides[nnames] = stride;
|
||||
nnames++;
|
||||
}
|
||||
va_end(ap);
|
||||
|
||||
VerifyX(0==SDFseekrdvecsarr(sdfp, nnames,
|
||||
names, starts, nobjs, addrs, strides),
|
||||
Shout("%s", SDFerrstring));
|
||||
|
||||
*nobjp = nobj;
|
||||
MPMY_Combine(nobjp, gnobjp, 1, MPMY_INT, MPMY_SUM);
|
||||
Msgf(("nobj=%d, gnobj=%d\n", *nobjp, *gnobjp));
|
||||
|
||||
*btabp = btab;
|
||||
StopTimer(&SDFreadTm);
|
||||
OutputTimer(&SDFreadTm, singlPrintf); /* global sync and sets timer->max */
|
||||
singlPrintf("read %ld x %d at %.0f MB/s\n", *gnobjp, sz, (*gnobjp/(100.*1000.))*(sz/ReadTimer(&SDFreadTm)));
|
||||
DisableTimer(&SDFreadTm);
|
||||
return sdfp;
|
||||
}
|
||||
|
||||
SDF *SDFread64(SDF *csdfp, void **btabp, int64_t *gnobjp, int *nobjp,
|
||||
int stride,
|
||||
/* char *name, offset_t offset, int *confirm */...)
|
||||
{
|
||||
va_list ap;
|
||||
char name[256];
|
||||
int64_t start;
|
||||
SDF *sdfp;
|
||||
int64_t gnobj;
|
||||
int nobj;
|
||||
void *btab;
|
||||
int Nfiles, procs_per_file, myfile, mysection;
|
||||
char hdrname[256];
|
||||
void *addrs[MAXNAMES];
|
||||
char *names[MAXNAMES];
|
||||
int strides[MAXNAMES];
|
||||
int nobjs[MAXNAMES];
|
||||
int64_t starts[MAXNAMES];
|
||||
int *confirm;
|
||||
int nnames;
|
||||
int sz = 0;
|
||||
|
||||
EnableTimer(&SDFreadTm, "SDFread");
|
||||
StartTimer(&SDFreadTm);
|
||||
|
||||
if( !SDFread_datafile || !SDFhasname(SDFread_datafile, csdfp) ){
|
||||
sdfp = csdfp;
|
||||
SinglWarning("SDFread: Looking for data in 'control' file\n");
|
||||
Nfiles = 1;
|
||||
}else{
|
||||
sdfp = NULL;
|
||||
Nfiles = SDFnrecs(SDFread_datafile, csdfp);
|
||||
if( Nfiles > MPMY_Nproc() || Nfiles < 0){
|
||||
SinglError("Sorry, bad Nfiles (%d)!\n", Nfiles);
|
||||
}
|
||||
}
|
||||
|
||||
/* Pick out which file in the control file will be ours. */
|
||||
/* and which "section" of the file. */
|
||||
procs_per_file = MPMY_Nproc()/Nfiles;
|
||||
Verify(procs_per_file*Nfiles == MPMY_Nproc());
|
||||
myfile = MPMY_Procnum()/procs_per_file;
|
||||
mysection = MPMY_Procnum()%procs_per_file;
|
||||
|
||||
if( sdfp == NULL ){
|
||||
VerifySX(0==SDFseekrdvecs(csdfp,
|
||||
SDFread_datafile, myfile, 1, name, sizeof(name),
|
||||
NULL),
|
||||
SinglShout("%s", SDFerrstring));
|
||||
if( SDFread_hdrfile )
|
||||
SDFgetstringOrDefault(csdfp, SDFread_hdrfile, hdrname, sizeof(hdrname), "");
|
||||
else
|
||||
hdrname[0] = '\0';
|
||||
|
||||
/* This was moved from above where it used name unitialized */
|
||||
if (hdrname[0] && SDFissdf(name) ) {
|
||||
SinglWarning("Superfluous headerfile %s ignored\n", hdrname);
|
||||
hdrname[0] = '\0';
|
||||
}
|
||||
VerifySX(sdfp = SDFopen(hdrname, name),SinglShout("%s", SDFerrstring));
|
||||
}else{
|
||||
strncpy(name, "<SDF file>", sizeof(name));
|
||||
}
|
||||
|
||||
if( SDFbyteorder(sdfp) == 0 ){
|
||||
int swap;
|
||||
/* The data/hdr file itself doesn't specify a byte order. */
|
||||
SDFgetintOrDefault(csdfp, "swapbytes", &swap, 0);
|
||||
if( swap )
|
||||
SDFswap(sdfp);
|
||||
/* If there's no byteorder specified, then it won't swap */
|
||||
}
|
||||
|
||||
if( SDFread_npart && SDFgetint64(sdfp, SDFread_npart, &gnobj) ){
|
||||
/* Hopefully calling va_start and va_end in here won't disturb */
|
||||
/* the real loop over arguments below... */
|
||||
va_start(ap, stride);
|
||||
names[0] = va_arg(ap, char *);
|
||||
gnobj = SDFnrecs(names[0], sdfp);
|
||||
va_end(ap);
|
||||
if( MPMY_Procnum() == 0 ){
|
||||
SinglShout("%s does not have an \"%s\".\n", name, SDFread_npart);
|
||||
#if __WORDSIZE==64
|
||||
SinglShout("Guessing %s=%ld from SDFnrecs(., %s)\n",
|
||||
SDFread_npart, gnobj, names[0]);
|
||||
#else
|
||||
SinglShout("Guessing %s=%lld from SDFnrecs(., %s)\n",
|
||||
SDFread_npart, gnobj, names[0]);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
NobjInitial64(gnobj, procs_per_file, mysection, &nobj, &start);
|
||||
btab = Calloc(nobj, stride);
|
||||
Msgf(("Proc %d starting at %ld in file, reading %d of %ld\n",
|
||||
MPMY_Procnum(), start, nobj, gnobj));
|
||||
|
||||
nnames = 0;
|
||||
va_start(ap, stride);
|
||||
while(( names[nnames] = va_arg(ap, char *)) != NULL ){
|
||||
assert(nnames < MAXNAMES);
|
||||
addrs[nnames] = va_arg(ap, int) + (char *)btab;
|
||||
confirm = va_arg(ap, int *);
|
||||
if( !SDFhasname(names[nnames], sdfp) ){
|
||||
*confirm = 0;
|
||||
Msgf(("SDF file does not have %s\n", names[nnames]));
|
||||
continue;
|
||||
}else{
|
||||
*confirm = 1;
|
||||
}
|
||||
starts[nnames] = start;
|
||||
nobjs[nnames] = nobj;
|
||||
strides[nnames] = stride;
|
||||
sz += SDFtype_sizes[SDFtype(names[nnames], sdfp)];
|
||||
nnames++;
|
||||
}
|
||||
va_end(ap);
|
||||
|
||||
VerifyX(0==SDFseekrdvecsarr(sdfp, nnames,
|
||||
names, starts, nobjs, addrs, strides),
|
||||
Shout("%s", SDFerrstring));
|
||||
|
||||
*gnobjp = *nobjp = nobj;
|
||||
MPMY_Combine(gnobjp, gnobjp, 1, MPMY_INT64, MPMY_SUM);
|
||||
Msgf(("nobj=%d, gnobj=%ld\n", *nobjp, *gnobjp));
|
||||
|
||||
*btabp = btab;
|
||||
StopTimer(&SDFreadTm);
|
||||
OutputTimer(&SDFreadTm, singlPrintf); /* global sync and sets timer->max */
|
||||
singlPrintf("read %ld x %d at %.0f MB/s\n", *gnobjp, sz, (*gnobjp/(1000.*1000.))*(sz/ReadTimer(&SDFreadTm)));
|
||||
DisableTimer(&SDFreadTm);
|
||||
return sdfp;
|
||||
}
|
||||
|
177
external/libsdf/libsw/SDFreadf.c
vendored
Normal file
177
external/libsdf/libsw/SDFreadf.c
vendored
Normal file
|
@ -0,0 +1,177 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
#include "mpmy.h"
|
||||
#include "SDF.h"
|
||||
#include "Assert.h"
|
||||
#include "Malloc.h"
|
||||
#include "Msgs.h"
|
||||
#include "error.h"
|
||||
#include "verify.h"
|
||||
#include "SDFread.h"
|
||||
#include "gc.h"
|
||||
#include "singlio.h"
|
||||
#include "timers.h"
|
||||
|
||||
#define MAXNAMES 64
|
||||
|
||||
extern Timer_t SDFreadTm;
|
||||
|
||||
SDF *SDFreadf(char *hdr, char *name, void **btabp, int *gnobjp, int *nobjp,
|
||||
int stride,
|
||||
/* char *name, offset_t offset, int *confirm */...)
|
||||
{
|
||||
va_list ap;
|
||||
int start;
|
||||
SDF *sdfp;
|
||||
int gnobj, nobj;
|
||||
void *btab;
|
||||
void *addrs[MAXNAMES];
|
||||
char *names[MAXNAMES];
|
||||
int strides[MAXNAMES];
|
||||
int nobjs[MAXNAMES];
|
||||
int64_t starts[MAXNAMES];
|
||||
int *confirm;
|
||||
int nnames;
|
||||
|
||||
EnableTimer(&SDFreadTm, "SDFread");
|
||||
StartTimer(&SDFreadTm);
|
||||
|
||||
VerifySX(sdfp = SDFopen(hdr, name),SinglShout("%s", SDFerrstring));
|
||||
|
||||
if( SDFgetint(sdfp, "npart", &gnobj) ){
|
||||
/* Hopefully calling va_start and va_end in here won't disturb */
|
||||
/* the real loop over arguments below... */
|
||||
va_start(ap, stride);
|
||||
names[0] = va_arg(ap, char *);
|
||||
gnobj = SDFnrecs(names[0], sdfp);
|
||||
va_end(ap);
|
||||
if( MPMY_Procnum() == 0 ){
|
||||
SinglShout("%s does not have an \"npart\".\n", name);
|
||||
SinglShout("Guessing npart=%d from SDFnrecs(., %s)\n",
|
||||
gnobj, names[0]);
|
||||
}
|
||||
}
|
||||
|
||||
NobjInitial(gnobj, MPMY_Nproc(), MPMY_Procnum(), &nobj, &start);
|
||||
btab = Calloc(nobj, stride);
|
||||
Msgf(("Proc %d starting at %d in file, reading %d of %d\n",
|
||||
MPMY_Procnum(), start, nobj, gnobj));
|
||||
|
||||
nnames = 0;
|
||||
va_start(ap, stride);
|
||||
while(( names[nnames] = va_arg(ap, char *)) != NULL ){
|
||||
assert(nnames < MAXNAMES);
|
||||
addrs[nnames] = va_arg(ap, int) + (char *)btab;
|
||||
confirm = va_arg(ap, int *);
|
||||
if( !SDFhasname(names[nnames], sdfp) ){
|
||||
*confirm = 0;
|
||||
Msgf(("SDF file does not have %s\n", names[nnames]));
|
||||
continue;
|
||||
}else{
|
||||
*confirm = 1;
|
||||
}
|
||||
starts[nnames] = start;
|
||||
nobjs[nnames] = nobj;
|
||||
strides[nnames] = stride;
|
||||
nnames++;
|
||||
}
|
||||
va_end(ap);
|
||||
|
||||
VerifyX(0==SDFseekrdvecsarr(sdfp, nnames,
|
||||
names, starts, nobjs, addrs, strides),
|
||||
Shout("%s", SDFerrstring));
|
||||
|
||||
*nobjp = nobj;
|
||||
MPMY_Combine(nobjp, gnobjp, 1, MPMY_INT, MPMY_SUM);
|
||||
Msgf(("nobj=%d, gnobj=%d\n", *nobjp, *gnobjp));
|
||||
|
||||
*btabp = btab;
|
||||
StopTimer(&SDFreadTm);
|
||||
OutputTimer(&SDFreadTm, singlPrintf); /* global sync and sets timer->max */
|
||||
singlPrintf("read speed %.0f Mb/s\n", (*gnobjp/(1024.*1024.))*(stride/SDFreadTm.max));
|
||||
DisableTimer(&SDFreadTm);
|
||||
return sdfp;
|
||||
}
|
||||
|
||||
SDF *SDFreadf64(char *hdr, char *name, void **btabp, int64_t *gnobjp, int *nobjp,
|
||||
int stride,
|
||||
/* char *name, offset_t offset, int *confirm */...)
|
||||
{
|
||||
va_list ap;
|
||||
int64_t start;
|
||||
SDF *sdfp;
|
||||
int64_t gnobj;
|
||||
int nobj;
|
||||
void *btab;
|
||||
void *addrs[MAXNAMES];
|
||||
char *names[MAXNAMES];
|
||||
int strides[MAXNAMES];
|
||||
int nobjs[MAXNAMES];
|
||||
int64_t starts[MAXNAMES];
|
||||
int *confirm;
|
||||
int nnames;
|
||||
|
||||
EnableTimer(&SDFreadTm, "SDFread");
|
||||
StartTimer(&SDFreadTm);
|
||||
|
||||
VerifySX(sdfp = SDFopen(hdr, name),SinglShout("%s", SDFerrstring));
|
||||
|
||||
if( SDFgetint64(sdfp, "npart", &gnobj) ){
|
||||
/* Hopefully calling va_start and va_end in here won't disturb */
|
||||
/* the real loop over arguments below... */
|
||||
va_start(ap, stride);
|
||||
names[0] = va_arg(ap, char *);
|
||||
gnobj = SDFnrecs(names[0], sdfp);
|
||||
va_end(ap);
|
||||
if( MPMY_Procnum() == 0 ){
|
||||
SinglShout("%s does not have an \"npart\".\n", name);
|
||||
SinglShout("Guessing npart=%ld from SDFnrecs(., %s)\n",
|
||||
gnobj, names[0]);
|
||||
}
|
||||
}
|
||||
|
||||
NobjInitial64(gnobj, MPMY_Nproc(), MPMY_Procnum(), &nobj, &start);
|
||||
btab = Calloc(nobj, stride);
|
||||
Msgf(("Proc %d starting at %ld in file, reading %d of %ld\n",
|
||||
MPMY_Procnum(), start, nobj, gnobj));
|
||||
|
||||
nnames = 0;
|
||||
va_start(ap, stride);
|
||||
while(( names[nnames] = va_arg(ap, char *)) != NULL ){
|
||||
assert(nnames < MAXNAMES);
|
||||
addrs[nnames] = va_arg(ap, int) + (char *)btab;
|
||||
confirm = va_arg(ap, int *);
|
||||
if( !SDFhasname(names[nnames], sdfp) ){
|
||||
*confirm = 0;
|
||||
Msgf(("SDF file does not have %s\n", names[nnames]));
|
||||
continue;
|
||||
}else{
|
||||
*confirm = 1;
|
||||
}
|
||||
starts[nnames] = start;
|
||||
nobjs[nnames] = nobj;
|
||||
strides[nnames] = stride;
|
||||
nnames++;
|
||||
}
|
||||
va_end(ap);
|
||||
|
||||
VerifyX(0==SDFseekrdvecsarr(sdfp, nnames,
|
||||
names, starts, nobjs, addrs, strides),
|
||||
Shout("%s", SDFerrstring));
|
||||
|
||||
*gnobjp = *nobjp = nobj;
|
||||
MPMY_Combine(gnobjp, gnobjp, 1, MPMY_INT64, MPMY_SUM);
|
||||
Msgf(("nobj=%d, gnobj=%ld\n", *nobjp, *gnobjp));
|
||||
|
||||
*btabp = btab;
|
||||
StopTimer(&SDFreadTm);
|
||||
OutputTimer(&SDFreadTm, singlPrintf); /* global sync and sets timer->max */
|
||||
singlPrintf("read speed %.0f Mb/s\n", (*gnobjp/(1024.*1024.))*(stride/SDFreadTm.max));
|
||||
DisableTimer(&SDFreadTm);
|
||||
return sdfp;
|
||||
}
|
||||
|
435
external/libsdf/libsw/SDFwrite.c
vendored
Normal file
435
external/libsdf/libsw/SDFwrite.c
vendored
Normal file
|
@ -0,0 +1,435 @@
|
|||
/* This subroutine writes a restricted class of SDF files.
|
||||
The files contain an arbitrary set of ascii scalars, (specified in the
|
||||
variable length arg-list) and an array of binary struct records.
|
||||
This is good enough for our purposes at the moment. More sophisticated
|
||||
interfaces will probably be needed as time goes on.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h> /* for open */
|
||||
#include <unistd.h> /* for close */
|
||||
#include "SDF.h"
|
||||
#include "SDFwrite.h"
|
||||
#include "Malloc.h"
|
||||
#include "mpmy.h"
|
||||
#include "mpmy_io.h"
|
||||
#include "Msgs.h"
|
||||
#include "error.h"
|
||||
#include "protos.h"
|
||||
#include "timers.h"
|
||||
#include "singlio.h"
|
||||
|
||||
Timer_t SDFwriteTm;
|
||||
static char *header_buf;
|
||||
static int header_size;
|
||||
static int header_len;
|
||||
|
||||
|
||||
/* We would like to write some headers separately from the data. */
|
||||
/* We can let SDFwritehdr set this variable, and SDFwrite_alist */
|
||||
/* will avoid writing the header if wrote_header is true */
|
||||
static int wrote_header = 0;
|
||||
|
||||
/* How much to increase header buffer size when realloced */
|
||||
#define BUF_INC 4096
|
||||
|
||||
/* How big is our line buffer */
|
||||
#define LINE_LEN 512
|
||||
|
||||
/* Align the data segment on this size boundary. */
|
||||
/* It MUST be less than LINE_LEN */
|
||||
#define DATAALIGN 32
|
||||
|
||||
static void
|
||||
SDFwrite_alist(const char *filename, int gnobj, int nobj,
|
||||
const void *btab, int bsize, const char *bodydesc, va_list alist);
|
||||
|
||||
static void
|
||||
SDFwrite_alist64(const char *filename, int mode, int64_t gnobj, int64_t nobj,
|
||||
const void *btab, int bsize, const char *bodydesc, va_list alist);
|
||||
|
||||
static void
|
||||
outstr(const char *str)
|
||||
/* This is an obstack, but who's counting? */
|
||||
{
|
||||
int len;
|
||||
|
||||
len = strlen(str);
|
||||
if (header_size - header_len <= len) { /* <= deals with terminal null */
|
||||
header_size += BUF_INC + len;
|
||||
header_buf = Realloc(header_buf, header_size);
|
||||
}
|
||||
strcpy(header_buf + header_len, str);
|
||||
header_len += len;
|
||||
}
|
||||
|
||||
void
|
||||
SDFwrite(const char *filename, int gnobj, int nobj,
|
||||
const void *btab, int bsize, const char *bodydesc, ...){
|
||||
va_list alist;
|
||||
|
||||
EnableTimer(&SDFwriteTm, "SDFwrite");
|
||||
StartTimer(&SDFwriteTm);
|
||||
va_start(alist, bodydesc);
|
||||
SDFwrite_alist(filename, gnobj, nobj, btab, bsize, bodydesc, alist);
|
||||
va_end(alist);
|
||||
StopTimer(&SDFwriteTm);
|
||||
OutputTimer(&SDFwriteTm, singlPrintf); /* global sync and set timer->max */
|
||||
if (SDFwriteTm.max != 0.0)
|
||||
singlPrintf("write speed %.0f MB/s\n",
|
||||
(gnobj/(1000.0*1000.0))*(bsize/SDFwriteTm.max));
|
||||
DisableTimer(&SDFwriteTm); /* suppress printing again in OutputTimers */
|
||||
}
|
||||
|
||||
void
|
||||
SDFwrite64(const char *filename, int64_t gnobj, int64_t nobj,
|
||||
const void *btab, int bsize, const char *bodydesc, ...){
|
||||
va_list alist;
|
||||
int mode = MPMY_WRONLY|MPMY_CREAT|MPMY_TRUNC|MPMY_MULTI;
|
||||
|
||||
EnableTimer(&SDFwriteTm, "SDFwrite");
|
||||
StartTimer(&SDFwriteTm);
|
||||
va_start(alist, bodydesc);
|
||||
SDFwrite_alist64(filename, mode, gnobj, nobj, btab, bsize, bodydesc, alist);
|
||||
va_end(alist);
|
||||
StopTimer(&SDFwriteTm);
|
||||
OutputTimer(&SDFwriteTm, singlPrintf); /* global sync and set timer->max */
|
||||
if (SDFwriteTm.max != 0.0)
|
||||
singlPrintf("write speed %.0f MB/s\n",
|
||||
(gnobj/(1000.0*1000.0))*(bsize/SDFwriteTm.max));
|
||||
DisableTimer(&SDFwriteTm); /* suppress printing again in OutputTimers */
|
||||
}
|
||||
|
||||
void
|
||||
SDFappend64(const char *filename, int64_t gnobj, int64_t nobj,
|
||||
const void *btab, int bsize, const char *bodydesc, ...){
|
||||
va_list alist;
|
||||
int mode = MPMY_WRONLY|MPMY_MULTI;
|
||||
|
||||
EnableTimer(&SDFwriteTm, "SDFwrite");
|
||||
StartTimer(&SDFwriteTm);
|
||||
va_start(alist, bodydesc);
|
||||
SDFwrite_alist64(filename, mode, gnobj, nobj, btab, bsize, bodydesc, alist);
|
||||
va_end(alist);
|
||||
wrote_header = 1;
|
||||
StopTimer(&SDFwriteTm);
|
||||
OutputTimer(&SDFwriteTm, singlPrintf); /* global sync and set timer->max */
|
||||
if (SDFwriteTm.max != 0.0)
|
||||
singlPrintf("write speed %.0f MB/s\n",
|
||||
(gnobj/(1000.0*1000.0))*(bsize/SDFwriteTm.max));
|
||||
DisableTimer(&SDFwriteTm); /* suppress printing again in OutputTimers */
|
||||
}
|
||||
|
||||
void
|
||||
SDFwritehdr(const char *filename, const char *bodydesc, ...){
|
||||
va_list alist;
|
||||
|
||||
va_start(alist, bodydesc);
|
||||
SDFwrite_alist(filename, 0, 0, NULL, 0, bodydesc, alist);
|
||||
va_end(alist);
|
||||
wrote_header = 1;
|
||||
}
|
||||
|
||||
void
|
||||
SDFunsetwroteheader(void)
|
||||
{
|
||||
wrote_header = 0;
|
||||
}
|
||||
|
||||
void
|
||||
SDFsetwroteheader(void)
|
||||
{
|
||||
wrote_header = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
SDFwrite_alist(const char *filename, int gnobj, int nobj,
|
||||
const void *btab, int bsize, const char *bodydesc, va_list alist)
|
||||
{
|
||||
MPMYFile *myfd;
|
||||
int i, pad;
|
||||
char line[LINE_LEN];
|
||||
int ival;
|
||||
double dval;
|
||||
char *sval;
|
||||
char *name;
|
||||
char *buf;
|
||||
int len;
|
||||
int mode;
|
||||
int ok, allok, retried;
|
||||
|
||||
Msgf(("In Wtdata\n"));
|
||||
header_len = 0;
|
||||
|
||||
header_size = BUF_INC;
|
||||
header_buf = Malloc(header_size);
|
||||
|
||||
if (MPMY_Procnum() == 0 && wrote_header == 0) {
|
||||
outstr ("# SDF\n");
|
||||
sprintf(line, "parameter byteorder = 0x%x;\n",
|
||||
SDFcpubyteorder()); outstr(line);
|
||||
while( (name = va_arg(alist, char *)) ){
|
||||
Msgf(("name(%lx)=%s\n", (unsigned long int)name, name));
|
||||
switch( va_arg(alist, enum SDF_type_enum) ){
|
||||
case SDF_INT:
|
||||
ival = va_arg(alist, int);
|
||||
sprintf(line, "int %s = %d;\n", name, ival); outstr(line);
|
||||
break;
|
||||
case SDF_FLOAT:
|
||||
dval = va_arg(alist, double);
|
||||
sprintf(line, "float %s = %.8g;\n", name, dval); outstr(line);
|
||||
break;
|
||||
case SDF_DOUBLE:
|
||||
dval = va_arg(alist, double);
|
||||
sprintf(line, "double %s = %.16g;\n", name, dval);
|
||||
outstr(line);
|
||||
break;
|
||||
case SDF_STRING:
|
||||
sval = va_arg(alist, char *);
|
||||
sprintf(line, "char %s[] = \"%s\";\n", name, sval);
|
||||
outstr(line);
|
||||
break;
|
||||
default:
|
||||
Shout("Unexpected type in wtdata\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( bodydesc ){
|
||||
outstr(bodydesc);
|
||||
if( gnobj > 0 )
|
||||
sprintf(line, "[%d];\n", gnobj);
|
||||
else
|
||||
sprintf(line, "[];\n");
|
||||
outstr(line);
|
||||
}
|
||||
outstr("#\f\n");
|
||||
outstr ("# SDF-EOH ");
|
||||
/* This little bit of magic will cause the first word of data */
|
||||
/* to be aligned. This isn't required by anything, but it makes */
|
||||
/* it a lot easier to use really primitive tools like od. */
|
||||
pad = (header_len+1)%DATAALIGN; /* the +1 is to account for the '\n' */
|
||||
if( pad )
|
||||
pad = DATAALIGN - pad;
|
||||
for(i=0; i<pad; i++){
|
||||
line[i] = ' ';
|
||||
}
|
||||
line[pad] = '\n';
|
||||
line[pad+1] = '\0';
|
||||
outstr(line);
|
||||
/* Avoid separate write for header due to paragon limitations */
|
||||
/* It's only memory, after all */
|
||||
len = header_len+bsize*nobj;
|
||||
buf = header_buf = Realloc(header_buf, len);
|
||||
memcpy(buf+header_len, btab, bsize*nobj);
|
||||
} else {
|
||||
len = bsize*nobj;
|
||||
buf = btab;
|
||||
}
|
||||
|
||||
if (wrote_header == 0) {
|
||||
mode = MPMY_WRONLY|MPMY_CREAT|MPMY_TRUNC|MPMY_MULTI;
|
||||
} else {
|
||||
mode = MPMY_WRONLY|MPMY_APPEND|MPMY_MULTI;
|
||||
}
|
||||
retried = 0;
|
||||
retry:
|
||||
myfd = MPMY_Fopen(filename, mode);
|
||||
if( myfd == NULL ){
|
||||
SeriousWarning("MPMY_Fopen(%s, 0x%x) returns NULL, errno=%d\n",
|
||||
filename, mode, errno);
|
||||
goto outahere;
|
||||
}
|
||||
|
||||
i = MPMY_Fwrite(buf, 1, len, myfd);
|
||||
if (i != len){
|
||||
SeriousWarning("MPMY_Fwrite(btab, len=%d) only wrote %d, errno=%d\n",
|
||||
len, i, errno);
|
||||
SeriousWarning("\"%s\" is probably corrupt!\n", filename);
|
||||
}
|
||||
ok = (i==len);
|
||||
/* Should there be an MPMY_LAND and MPMY_LOR ? */
|
||||
allok = 0;
|
||||
MPMY_Combine(&ok, &allok, 1, MPMY_INT, MPMY_BAND);
|
||||
Msgf(("ok=%d, allok=%d\n", ok, allok));
|
||||
if( !allok ){
|
||||
int retryable;
|
||||
#ifdef ETIMEDOUT /* This seems to be a solaris thing */
|
||||
retryable = !retried && (ok || errno==ETIMEDOUT);
|
||||
#else
|
||||
retryable = 0;
|
||||
#endif
|
||||
Msgf(("retryable (local) = %d\n", retryable));
|
||||
MPMY_Combine(&retryable, &retryable, 1, MPMY_INT, MPMY_BAND);
|
||||
Msgf(("retryable (global) = %d\n", retryable));
|
||||
if( retryable ){
|
||||
SinglShout("Fingers crossed, we are going to retry!\n");
|
||||
retried = 1; /* only retry once! */
|
||||
MPMY_Fclose(myfd);
|
||||
#ifdef ETIMEDOUT
|
||||
/* The failure mode we are trying to recover from is an
|
||||
NFS timeout which might go away in a few seconds. We
|
||||
trust that if ETIMEDOUT exists, then sleep does too... */
|
||||
SinglShout("sleep(30), maybe the timeout will go away!\n");
|
||||
sleep(30);
|
||||
#endif
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
MPMY_Fclose(myfd);
|
||||
outahere:
|
||||
Free(header_buf);
|
||||
header_size = header_len = 0;
|
||||
header_buf = NULL;
|
||||
wrote_header = 0;
|
||||
Msgf(("SDFwrite2 done\n"));
|
||||
}
|
||||
|
||||
static void
|
||||
SDFwrite_alist64(const char *filename, int mode, int64_t gnobj, int64_t nobj,
|
||||
const void *btab, int bsize, const char *bodydesc, va_list alist)
|
||||
{
|
||||
MPMYFile *myfd;
|
||||
int i, pad;
|
||||
char line[LINE_LEN];
|
||||
int ival;
|
||||
int64_t i64val;
|
||||
double dval;
|
||||
char *sval;
|
||||
char *name;
|
||||
char *buf;
|
||||
size_t len;
|
||||
int ok, allok, retried;
|
||||
|
||||
Msgf(("In Wtdata\n"));
|
||||
header_len = 0;
|
||||
|
||||
header_size = BUF_INC;
|
||||
header_buf = Malloc(header_size);
|
||||
|
||||
if (MPMY_Procnum() == 0 && wrote_header == 0) {
|
||||
outstr ("# SDF\n");
|
||||
sprintf(line, "parameter byteorder = 0x%x;\n",
|
||||
SDFcpubyteorder()); outstr(line);
|
||||
while( (name = va_arg(alist, char *)) ){
|
||||
Msgf(("name(%lx)=%s\n", (unsigned long int)name, name));
|
||||
switch( va_arg(alist, enum SDF_type_enum) ){
|
||||
case SDF_INT:
|
||||
ival = va_arg(alist, int);
|
||||
sprintf(line, "int %s = %d;\n", name, ival); outstr(line);
|
||||
break;
|
||||
case SDF_INT64:
|
||||
i64val = va_arg(alist, int64_t);
|
||||
sprintf(line, "int64_t %s = %ld;\n", name, i64val); outstr(line);
|
||||
break;
|
||||
case SDF_FLOAT:
|
||||
dval = va_arg(alist, double);
|
||||
sprintf(line, "float %s = %.8g;\n", name, dval); outstr(line);
|
||||
break;
|
||||
case SDF_DOUBLE:
|
||||
dval = va_arg(alist, double);
|
||||
sprintf(line, "double %s = %.16g;\n", name, dval);
|
||||
outstr(line);
|
||||
break;
|
||||
case SDF_STRING:
|
||||
sval = va_arg(alist, char *);
|
||||
sprintf(line, "char %s[] = \"%s\";\n", name, sval);
|
||||
outstr(line);
|
||||
break;
|
||||
default:
|
||||
Shout("Unexpected type in wtdata\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( bodydesc ){
|
||||
outstr(bodydesc);
|
||||
if( gnobj > 0 ) {
|
||||
#if __WORDSIZE==64
|
||||
sprintf(line, "[%ld];\n", gnobj);
|
||||
#else
|
||||
sprintf(line, "[%lld];\n", gnobj);
|
||||
#endif
|
||||
} else {
|
||||
sprintf(line, "[];\n");
|
||||
}
|
||||
outstr(line);
|
||||
}
|
||||
outstr("#\f\n");
|
||||
outstr ("# SDF-EOH ");
|
||||
/* This little bit of magic will cause the first word of data */
|
||||
/* to be aligned. This isn't required by anything, but it makes */
|
||||
/* it a lot easier to use really primitive tools like od. */
|
||||
pad = (header_len+1)%DATAALIGN; /* the +1 is to account for the '\n' */
|
||||
if( pad )
|
||||
pad = DATAALIGN - pad;
|
||||
for(i=0; i<pad; i++){
|
||||
line[i] = ' ';
|
||||
}
|
||||
line[pad] = '\n';
|
||||
line[pad+1] = '\0';
|
||||
outstr(line);
|
||||
/* Avoid separate write for header due to paragon limitations */
|
||||
/* It's only memory, after all */
|
||||
len = header_len+(size_t)bsize*nobj;
|
||||
buf = header_buf = Realloc(header_buf, len);
|
||||
memcpy(buf+header_len, btab, (size_t)bsize*nobj);
|
||||
} else {
|
||||
len = (size_t)bsize*nobj;
|
||||
buf = btab;
|
||||
}
|
||||
|
||||
retried = 0;
|
||||
retry:
|
||||
myfd = MPMY_Fopen(filename, mode);
|
||||
if( myfd == NULL ){
|
||||
SeriousWarning("MPMY_Fopen(%s, 0x%x) returns NULL, errno=%d\n",
|
||||
filename, mode, errno);
|
||||
goto outahere;
|
||||
}
|
||||
|
||||
if (!(mode & MPMY_TRUNC)) MPMY_Fseek(myfd, 0L, MPMY_SEEK_END);
|
||||
i64val = MPMY_Fwrite(buf, 1, len, myfd);
|
||||
if (i64val != len){
|
||||
SeriousWarning("MPMY_Fwrite(btab, len=%ld) only wrote %ld, errno=%d\n",
|
||||
len, i64val, errno);
|
||||
SeriousWarning("\"%s\" is probably corrupt!\n", filename);
|
||||
}
|
||||
ok = (i64val==len);
|
||||
/* Should there be an MPMY_LAND and MPMY_LOR ? */
|
||||
allok = 0;
|
||||
MPMY_Combine(&ok, &allok, 1, MPMY_INT, MPMY_BAND);
|
||||
Msgf(("ok=%d, allok=%d\n", ok, allok));
|
||||
if( !allok ){
|
||||
int retryable;
|
||||
#ifdef ETIMEDOUT /* This seems to be a solaris thing */
|
||||
retryable = !retried && (ok || errno==ETIMEDOUT);
|
||||
#else
|
||||
retryable = 0;
|
||||
#endif
|
||||
Msgf(("retryable (local) = %d\n", retryable));
|
||||
MPMY_Combine(&retryable, &retryable, 1, MPMY_INT, MPMY_BAND);
|
||||
Msgf(("retryable (global) = %d\n", retryable));
|
||||
if( retryable ){
|
||||
SinglShout("Fingers crossed, we are going to retry!\n");
|
||||
retried = 1; /* only retry once! */
|
||||
MPMY_Fclose(myfd);
|
||||
#ifdef ETIMEDOUT
|
||||
/* The failure mode we are trying to recover from is an
|
||||
NFS timeout which might go away in a few seconds. We
|
||||
trust that if ETIMEDOUT exists, then sleep does too... */
|
||||
SinglShout("sleep(30), maybe the timeout will go away!\n");
|
||||
sleep(30);
|
||||
#endif
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
MPMY_Fclose(myfd);
|
||||
outahere:
|
||||
Free(header_buf);
|
||||
header_size = header_len = 0;
|
||||
header_buf = NULL;
|
||||
wrote_header = 0;
|
||||
Msgf(("SDFwrite2 done\n"));
|
||||
}
|
542
external/libsdf/libsw/abm.c
vendored
Normal file
542
external/libsdf/libsw/abm.c
vendored
Normal file
|
@ -0,0 +1,542 @@
|
|||
#define NO_TIMERS /* On sun4, the timer in ABMDlvr is a huge penalty.
|
||||
It takes up to half the total processing time! */
|
||||
/*#define NO_MSGS*/
|
||||
/*
|
||||
ABM: Asynchronous Buffered Messages.
|
||||
Otherwise known as "Active Messages, through the looking glass"
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "abm.h"
|
||||
#include "protos.h"
|
||||
#include "Assert.h"
|
||||
#include "mpmy.h"
|
||||
#include "Malloc.h"
|
||||
#include "Msgs.h"
|
||||
#include "verify.h"
|
||||
#include "gc.h"
|
||||
#include "dll.h"
|
||||
|
||||
#define Ver(x) Verify((x) == MPMY_SUCCESS)
|
||||
|
||||
#define ABMDONETYPE -1
|
||||
#define ABMALLDONETYPE -2
|
||||
|
||||
/* Use this for queueing entries for later packetization */
|
||||
typedef struct{
|
||||
void *arg;
|
||||
int type; /* request/reply/done */
|
||||
int sz;
|
||||
ABMpktz_t *func; /* how to bundle the data */
|
||||
} Qelmt_t ;
|
||||
|
||||
/* Send exaclty one pkt */
|
||||
static void SendPkt(ABM *abm, void *ptr, int sz, int dest);
|
||||
|
||||
/* Keep track of the resources tied up in outgoing messages */
|
||||
static void DeliveryWait(ABM *abm);
|
||||
static void DeliveryTest(ABM *abm);
|
||||
|
||||
/* Common subroutine between ABMPoll and ABMPollWait */
|
||||
static int ABMPoll_common(ABM *abm, MPMY_Status *status);
|
||||
|
||||
/* Keep track of the messages that haven't been MPMY_Test'ed affirmative yet */
|
||||
typedef struct {
|
||||
void *ptr;
|
||||
MPMY_Comm_request req;
|
||||
} undelivered_t;
|
||||
|
||||
/* To be "safe", ABMFlushOne should also eliminate dest from destarr[], but
|
||||
the precise behavior of the callers of this function make that
|
||||
unnecessary. If you call ABMFlushOne, you must guarantee that
|
||||
destarr[] is left in a correct state when you are done. */
|
||||
static void ABMFlushOne(ABM *abm, int dest);
|
||||
|
||||
static int hist_enable;
|
||||
Timer_t ABMDlvrTm;
|
||||
Counter_t ABMIsendCnt;
|
||||
Counter_t ABMPostCnt;
|
||||
Counter_t ABMByteCnt;
|
||||
Counter_t ABMHistCnt[ABMHISTLEN];
|
||||
|
||||
void
|
||||
ABMHistEnable(int log2lo, int log2hi){
|
||||
int i;
|
||||
char name[32];
|
||||
|
||||
/* Sanity check the args. Maybe we should assert these?? */
|
||||
if( log2lo < 0 )
|
||||
log2lo = 0;
|
||||
if( log2hi >= ABMHISTLEN )
|
||||
log2hi = ABMHISTLEN-1;
|
||||
if( log2lo > log2hi )
|
||||
log2lo = log2hi;
|
||||
if( log2hi < log2lo )
|
||||
log2hi = log2lo;
|
||||
for(i=log2lo; i<=log2hi; i++){
|
||||
sprintf(name, "Pkt(>=%d)", 1<<i);
|
||||
EnableCounter(&ABMHistCnt[i], name);
|
||||
}
|
||||
hist_enable = 1;
|
||||
}
|
||||
|
||||
void
|
||||
ABMSetup(ABM *abm, int pktsize, int tag, int nfuncs, ABMhndlr_t *hndlarray[]){
|
||||
int nproc, procnum;
|
||||
int i, bit;
|
||||
|
||||
abm->pktsize = pktsize;
|
||||
abm->nfuncs = nfuncs;
|
||||
abm->hndlarray = Malloc(nfuncs*sizeof(ABMhndlr_t *));
|
||||
memcpy(abm->hndlarray, hndlarray, nfuncs*sizeof(ABMhndlr_t *));
|
||||
nproc = MPMY_Nproc();
|
||||
procnum = MPMY_Procnum();
|
||||
abm->doc = ilog2(nproc);
|
||||
if (nproc != 1 << (abm->doc))
|
||||
abm->doc++; /* for non power-of-two sizes */
|
||||
/* This shouldn't require 10 lines of code... */
|
||||
if( procnum == 0 ){
|
||||
abm->allbitsdone = (1 << (abm->doc+1))-1;
|
||||
}else if( lobit(procnum) == 0 ){
|
||||
abm->allbitsdone = 1;
|
||||
}else{
|
||||
bit = 1<<(lobit(procnum)-1);
|
||||
Msg("abmdone", ("bit=%d\n", bit));
|
||||
while( (bit^procnum) >= nproc ){
|
||||
Msg("abmdone", ("looping, bit=%d\n", bit));
|
||||
bit >>= 1;
|
||||
}
|
||||
abm->allbitsdone = (bit==0)? 1 : (bit<<2)-1;
|
||||
}
|
||||
abm->done = 0;
|
||||
abm->alldone = 0;
|
||||
Msg("abmdone", ("ABM:allbitsdone=%d, done=%d\n", abm->allbitsdone, abm->done));
|
||||
abm->recvbufA = abm->recvbuf1 = Malloc(pktsize);
|
||||
abm->recvbufB = abm->recvbuf2 = Malloc(pktsize);
|
||||
abm->tag = tag;
|
||||
Ver(MPMY_Irecv(abm->recvbufA, abm->pktsize,
|
||||
MPMY_SOURCE_ANY, abm->tag, &abm->Recv_Hndl));
|
||||
abm->Enqueued = Malloc(sizeof(Dll)*nproc);
|
||||
abm->destarr = Malloc(sizeof(int)*nproc);
|
||||
abm->cntarr = Calloc(nproc, sizeof(int));
|
||||
abm->ndests = 0;
|
||||
DllCreateChn(&abm->QelmtChn, sizeof(Qelmt_t), 10);
|
||||
for(i=0; i<nproc; i++){
|
||||
DllCreate(&abm->Enqueued[i], &abm->QelmtChn);
|
||||
}
|
||||
|
||||
DllCreateChn(&abm->undelChn, sizeof(undelivered_t), 20);
|
||||
DllCreate(&abm->undeliveredLL, &abm->undelChn);
|
||||
}
|
||||
|
||||
void
|
||||
ABMIamDone(ABM *abm){
|
||||
int i, procnum;
|
||||
|
||||
procnum = MPMY_Procnum();
|
||||
if( abm->done & 1 ){
|
||||
SeriousWarning("ABMIamDone apparently called twice!\n");
|
||||
Shout("allbitsdone=%d, done=%d\n", abm->allbitsdone, abm->done);
|
||||
return;
|
||||
}
|
||||
if( abm->alldone ){
|
||||
SeriousWarning("ABMIamDone called after alldone\n");
|
||||
Shout("allbitsdone=%d, done=%d\n", abm->allbitsdone, abm->done);
|
||||
return;
|
||||
}
|
||||
Msg("abmdone", ("ABMIamDone\n"));
|
||||
ABMPost(abm, procnum, 0, ABMDONETYPE, NULL, NULL);
|
||||
ABMFlushOne(abm, procnum);
|
||||
for(i=abm->ndests-1; i>=0; --i){
|
||||
if( abm->destarr[i] == procnum ){
|
||||
abm->destarr[i] = abm->destarr[--abm->ndests];
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(i >= 0);
|
||||
}
|
||||
|
||||
int
|
||||
ABMAllDone(ABM *abm){
|
||||
return abm->alldone;
|
||||
}
|
||||
|
||||
void
|
||||
ABMShutdown(ABM *abm){
|
||||
int i;
|
||||
int junk = 0;
|
||||
MPMY_Status stat;
|
||||
MPMY_Comm_request req;
|
||||
|
||||
while( !ABMAllDone(abm) ){
|
||||
ABMFlush(abm);
|
||||
if( ABMPoll(abm) < 0 )
|
||||
Error("AbmPoll failed in ABMShutdown!\n");
|
||||
}
|
||||
/* There's still a recv outstanding in NLPoll */
|
||||
Ver(MPMY_Isend(&junk, sizeof(int), MPMY_Procnum(), abm->tag, &req));
|
||||
MPMY_Wait2(req, NULL, abm->Recv_Hndl, &stat);
|
||||
assert(MPMY_Source(&stat) == MPMY_Procnum()
|
||||
&& MPMY_Count(&stat) == sizeof(int));
|
||||
|
||||
for(i=0; i<MPMY_Nproc(); i++){
|
||||
DllTerminate(&abm->Enqueued[i]);
|
||||
}
|
||||
ChnTerminate(&abm->QelmtChn);
|
||||
Free(abm->hndlarray);
|
||||
Free(abm->Enqueued);
|
||||
Free(abm->destarr);
|
||||
Free(abm->cntarr);
|
||||
Free(abm->recvbuf1);
|
||||
Free(abm->recvbuf2);
|
||||
DllTerminate(&abm->undeliveredLL);
|
||||
ChnTerminate(&abm->undelChn);
|
||||
}
|
||||
|
||||
static void
|
||||
Donehndlr(ABM *abm, int who){
|
||||
int mask, dest, type;
|
||||
int procnum= MPMY_Procnum();
|
||||
|
||||
mask = who ^ procnum;
|
||||
|
||||
if( mask == 0 )
|
||||
mask = 1;
|
||||
else
|
||||
mask <<= 1;
|
||||
Msg("abmdone", ("Donehndlr(who=%d), mask=%x\n", who, mask));
|
||||
if( (abm->done & mask) || !(abm->allbitsdone & mask)){
|
||||
SeriousWarning("Unexepected bit set in 'done' or 'allbitsdone':\n");
|
||||
Shout("done=%x, allbitsdone=%x, who=%x, procnum=%d, mask=%x\n",
|
||||
abm->done, abm->allbitsdone, who, procnum, mask);
|
||||
}
|
||||
abm->done |= mask;
|
||||
|
||||
if( abm->done == abm->allbitsdone ){
|
||||
if( procnum == 0 ){
|
||||
type = ABMALLDONETYPE;
|
||||
dest = 0;
|
||||
Msg("abmdone", ("Proc 0 is done. Initiatiing ALLDONE cascade\n"));
|
||||
}else{
|
||||
type = ABMDONETYPE;
|
||||
dest = (1<<lobit(procnum)) ^ procnum;
|
||||
Msg("abmdone", ("all bits done. Forwarding DONE to %d\n", dest));
|
||||
Msg_flush();
|
||||
}
|
||||
ABMPost(abm, dest, 0, type, NULL, NULL);
|
||||
ABMFlush(abm);
|
||||
}else{
|
||||
Msg("abmdone", ("alldone: %d != abm->done: %d\n", abm->alldone, abm->done));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
AllDonehndlr(ABM *abm)
|
||||
{
|
||||
int chan;
|
||||
int procnum = MPMY_Procnum();
|
||||
int nproc = MPMY_Nproc();
|
||||
|
||||
Msg("abmdone", ("AllDonehndlr\n"));
|
||||
|
||||
for (chan = hibit(MPMY_Procnum())+1; chan < abm->doc; chan++) {
|
||||
int dest = procnum ^ (1 << chan);
|
||||
if (!(procnum & (1 << chan)) && dest < nproc) {
|
||||
Msgf(("AllDone: informing p%d\n", dest));
|
||||
ABMPost(abm, dest, 0, ABMALLDONETYPE, NULL, NULL);
|
||||
ABMFlush(abm);
|
||||
}
|
||||
}
|
||||
assert(abm->ndests == 0);
|
||||
Msg("abmdone", ("Waiting for all Isends to complete\n"));
|
||||
Msg_flush();
|
||||
DeliveryWait(abm);
|
||||
Msg("abmdone", ("Everybody done. Everybody informed\n"));
|
||||
Msg_flush();
|
||||
abm->alldone = 1;
|
||||
}
|
||||
|
||||
int
|
||||
ABMPoll(ABM *abm){
|
||||
MPMY_Status status;
|
||||
int flag;
|
||||
|
||||
Ver(MPMY_Test(abm->Recv_Hndl, &flag, &status));
|
||||
if( flag == 0 )
|
||||
return 0;
|
||||
return ABMPoll_common(abm, &status);
|
||||
}
|
||||
|
||||
int
|
||||
ABMPollWait(ABM *abm){
|
||||
MPMY_Status status;
|
||||
|
||||
ABMFlush(abm);
|
||||
if( Msg_test(__FILE__) ){
|
||||
Msg_do("Waiting in ABMPollWait\n");
|
||||
Msg_flush();
|
||||
}
|
||||
Ver(MPMY_Wait(abm->Recv_Hndl, &status));
|
||||
return ABMPoll_common(abm, &status);
|
||||
}
|
||||
|
||||
static int
|
||||
ABMPoll_common(ABM *abm, MPMY_Status *status){
|
||||
int type;
|
||||
int flag;
|
||||
int len;
|
||||
int sz;
|
||||
int src;
|
||||
char *in, *end;
|
||||
int nloop = 0;
|
||||
|
||||
do{
|
||||
/* Testing inside the while with a "," operator breaks the T3D */
|
||||
nloop++;
|
||||
if (MPMY_Tag(status) != abm->tag)
|
||||
Error("Bad tag (%d) in ABMPoll(), should be %d, source %d, len %d\n",
|
||||
MPMY_Tag(status), abm->tag, MPMY_Source(status),
|
||||
MPMY_Count(status));
|
||||
src = MPMY_Source(status);
|
||||
len = MPMY_Count(status);
|
||||
Msgf(("ABMPoll Received %d byte packet from p%d\n", len, src));
|
||||
|
||||
in = abm->recvbufA;
|
||||
Ver(MPMY_Irecv(abm->recvbufB, abm->pktsize,
|
||||
MPMY_SOURCE_ANY, abm->tag, &abm->Recv_Hndl));
|
||||
abm->recvbufA = abm->recvbufB;
|
||||
abm->recvbufB = in;
|
||||
end = in + len;
|
||||
while( in < end ){
|
||||
if( abm->alldone ){
|
||||
long int *ip = (long int *)in;
|
||||
SeriousWarning("message arrived after alldone.\n");
|
||||
Shout("allbitsdone=%d, done=%d\n", abm->allbitsdone,
|
||||
abm->done);
|
||||
Shout("src=%d, total len=%d, buf=%#lx, in=%#lx\n",
|
||||
src, len, (long)abm->recvbufB, (long)in);
|
||||
Shout("type=%ld, message size: %ld, contents: %#lx %#lx %#lx %#lx\n",
|
||||
ip[0], ip[1], ip[2], ip[3], ip[4], ip[5]);
|
||||
return -1;
|
||||
}
|
||||
type = *(int *)in;
|
||||
in += sizeof(int);
|
||||
sz = *(int *)in;
|
||||
in += sizeof(int);
|
||||
|
||||
switch(type){
|
||||
case ABMALLDONETYPE:
|
||||
Msgf(("ABMALLDONE recvd from p%d.\n", src));
|
||||
AllDonehndlr(abm);
|
||||
break;
|
||||
case ABMDONETYPE:
|
||||
Msgf(("ABMDONE recvd from p%d.\n", src));
|
||||
Donehndlr(abm, src);
|
||||
break;
|
||||
default:
|
||||
Msgf(("ABMPoll type %d\n", type));
|
||||
if( type >= 0 && type < abm->nfuncs )
|
||||
abm->hndlarray[type](src, sz, in);
|
||||
else{
|
||||
Error("Bad type, %d!\n", type);
|
||||
}
|
||||
break;
|
||||
}
|
||||
in += sz;
|
||||
}
|
||||
Ver(MPMY_Test(abm->Recv_Hndl, &flag, status));
|
||||
}while(flag);
|
||||
return nloop;
|
||||
}
|
||||
|
||||
void
|
||||
ABMPost(ABM *abm, int dest, int sz, int type, ABMpktz_t *func, void *arg){
|
||||
Dll *Q = &abm->Enqueued[dest];
|
||||
Qelmt_t *new;
|
||||
|
||||
IncrCounter(&ABMPostCnt);
|
||||
if( sz + 2*sizeof(int) > abm->pktsize){
|
||||
Error("Can't ABMPost a message of size %d. pktsize=%d\n",
|
||||
sz, abm->pktsize);
|
||||
}
|
||||
if( DllLength(Q) == 0 ){
|
||||
abm->destarr[abm->ndests++] = dest;
|
||||
}
|
||||
if( abm->cntarr[dest] + sz + 2*sizeof(int) > abm->pktsize ){
|
||||
ABMFlushOne(abm, dest);
|
||||
}
|
||||
abm->cntarr[dest] += sz + 2*sizeof(int);
|
||||
Msgf(("ABMPost %ld for p%d, cntarr now %d\n", sz + 2*sizeof(int), dest, abm->cntarr[dest]));
|
||||
new = DllData( DllInsertAtBottom(Q) );
|
||||
new->sz = sz;
|
||||
new->func = func;
|
||||
new->arg = arg;
|
||||
new->type = type;
|
||||
}
|
||||
|
||||
static int
|
||||
cmp_xor(const void *p1, const void *p2){
|
||||
int d1 = *(int *)p1;
|
||||
int d2 = *(int *)p2;
|
||||
int procnum = MPMY_Procnum();
|
||||
|
||||
return (d1^procnum) - (d2^procnum);
|
||||
}
|
||||
|
||||
/* To be "safe", ABMFlushOne should also eliminate dest from destarr[], but
|
||||
the precise behavior of the callers of this function make that
|
||||
unnecessary. If you call this function, you must guarantee that
|
||||
destarr[] is left in a correct state whey you are done. */
|
||||
static void
|
||||
ABMFlushOne(ABM *abm, int dest){
|
||||
char *cp;
|
||||
void *buf;
|
||||
Qelmt_t *Qelmt;
|
||||
Dll *Q;
|
||||
Dll_elmt *q;
|
||||
int szleft, used;
|
||||
|
||||
Q = &abm->Enqueued[dest];
|
||||
if( DllLength(Q) == 0 )
|
||||
return;
|
||||
|
||||
#if 0
|
||||
/* This loop is wasting time. If we get here from ABMFlush, then
|
||||
we should already know which element in destarr is in question.
|
||||
If we get here from ABMPost, then we know the very next thing
|
||||
we are going to do is put the same destination back in destarr.
|
||||
Thus, we can just forget this altogether! */
|
||||
for(i=0; i<abm->ndests; i++){
|
||||
if( abm->destarr[i] == dest )
|
||||
break;
|
||||
}
|
||||
assert(i < abm->ndests);; /* we actually found one! */
|
||||
abm->destarr[i] = abm->destarr[--abm->ndests];
|
||||
#endif
|
||||
|
||||
Msgf(("ABMFl to p%d\n", dest));
|
||||
cp = buf = Malloc(abm->pktsize);
|
||||
szleft = abm->pktsize;
|
||||
|
||||
for(q = DllTop(Q); q!=DllInf(Q); q=DllDeleteDown(Q, q)){
|
||||
Qelmt = (Qelmt_t *)DllData(q);
|
||||
if( Qelmt->sz + 2*sizeof(int) > szleft ){
|
||||
/* Now that ABMPost flushes automatically when the count
|
||||
passes pktsize, this test may be overkill. It's not worth
|
||||
simplifying. */
|
||||
used = abm->pktsize - szleft;
|
||||
buf = Realloc(buf, used);
|
||||
Msgf(("SendQ full packet for p%d (len=%d)\n",
|
||||
dest, used));
|
||||
SendPkt(abm, buf, used, dest);
|
||||
cp = buf = Malloc(abm->pktsize);
|
||||
szleft = abm->pktsize;
|
||||
}
|
||||
/* I think it would be possible to recover here if we
|
||||
introduce another TYPE of message 'NLPKTGROWTYPE' which
|
||||
tells the recipient to Realloc his receive buf. A good project
|
||||
for a rainy day.... */
|
||||
assert(Qelmt->sz + 2*sizeof(int) <= szleft && Qelmt->sz >= 0 );
|
||||
*(int *)cp = Qelmt->type;
|
||||
cp += sizeof(int);
|
||||
szleft -= sizeof(int);
|
||||
*(int *)cp = Qelmt->sz;
|
||||
cp += sizeof(int);
|
||||
szleft -= sizeof(int);
|
||||
if( Qelmt->func ){
|
||||
Qelmt->func(cp, Qelmt->arg, Qelmt->sz);
|
||||
cp += Qelmt->sz;
|
||||
szleft -= Qelmt->sz;
|
||||
}
|
||||
}
|
||||
assert(szleft < abm->pktsize);
|
||||
used = abm->pktsize - szleft;
|
||||
Msgf(("SendQ: Remaining packet for p%d (len=%d)\n",
|
||||
dest, used));
|
||||
SendPkt(abm, buf, used, dest);
|
||||
abm->cntarr[dest] = 0;
|
||||
}
|
||||
|
||||
void
|
||||
ABMFlush(ABM *abm){
|
||||
int i;
|
||||
|
||||
if (abm->ndests == 0) return; /* Required to avoid huge overhead. */
|
||||
|
||||
/* reorder the destinations so everybody doesn't immediately dump on 0 ! */
|
||||
qsort(abm->destarr, abm->ndests, sizeof(int), cmp_xor); /* unnecessary? */
|
||||
|
||||
/* loop over the destinations that have something queued. */
|
||||
for(i=0; i<abm->ndests; i++){
|
||||
ABMFlushOne(abm, abm->destarr[i]);
|
||||
}
|
||||
abm->ndests = 0;
|
||||
DeliveryTest(abm);
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
void SendPkt(ABM *abm, void *ptr, int sz, int dest){
|
||||
undelivered_t *new;
|
||||
|
||||
new = DllData(DllInsertAtTop(&abm->undeliveredLL));
|
||||
new->ptr = ptr;
|
||||
AddCounter(&ABMByteCnt, sz);
|
||||
IncrCounter(&ABMIsendCnt);
|
||||
if( hist_enable ){
|
||||
int h = ilog2(sz);
|
||||
/* If I weren't so lazy, I'd record the outliers separately... */
|
||||
if( h < ABMHISTFIRST ) h = ABMHISTFIRST;
|
||||
if( h >=ABMHISTLEN ) h = ABMHISTLEN-1;
|
||||
/* We could just increment these by 1, or by sz. You learn
|
||||
something slightly different either way... */
|
||||
AddCounter(&ABMHistCnt[h], sz);
|
||||
}
|
||||
Ver(MPMY_Isend(ptr, sz, dest, abm->tag, &new->req));
|
||||
/* Calling DeliveryTest here is not strictly necessary for correctness,
|
||||
but it is a good idea to try to reduce the number of outstanding
|
||||
requests. See the comment near DeliverTest for other ideas */
|
||||
DeliveryTest(abm);
|
||||
}
|
||||
|
||||
/* It might be useful to have two versions of this. The one called
|
||||
from ABMFlush (and hence at user request) should be aggressive and try
|
||||
each and every outstanding request. The one called from ABMFlushOne,
|
||||
(and hence more frequently, but perhaps asynchronously), could give up
|
||||
after the first failure. This would keep those machines that need
|
||||
constant prodding working, without putting an unnecessary burden on
|
||||
others. */
|
||||
static void DeliveryTest(ABM *abm){
|
||||
int flag;
|
||||
undelivered_t *p;
|
||||
Dll_elmt *pp;
|
||||
|
||||
/* Another good opportunity to call Flick? This is done once per
|
||||
ABMFlush. */
|
||||
StartTimer(&ABMDlvrTm);
|
||||
MPMY_Flick();
|
||||
for(pp=DllBottom(&abm->undeliveredLL);
|
||||
pp != DllSup(&abm->undeliveredLL);
|
||||
/* pp incremented inside body */){
|
||||
p = DllData(pp);
|
||||
Ver( MPMY_Test(p->req, &flag, NULL) );
|
||||
if( flag ){
|
||||
Free(p->ptr);
|
||||
pp = DllDeleteUp(&abm->undeliveredLL, pp);
|
||||
}else{
|
||||
pp = DllUp(pp);
|
||||
}
|
||||
}
|
||||
StopTimer(&ABMDlvrTm);
|
||||
}
|
||||
|
||||
static void DeliveryWait(ABM *abm){
|
||||
Msgf(("ABMWait\n"));
|
||||
while( DllLength(&abm->undeliveredLL) ){
|
||||
DeliveryTest(abm);
|
||||
}
|
||||
}
|
||||
|
204
external/libsdf/libsw/alloca.c
vendored
Normal file
204
external/libsdf/libsw/alloca.c
vendored
Normal file
|
@ -0,0 +1,204 @@
|
|||
/*
|
||||
alloca -- (mostly) portable public-domain implementation -- D A Gwyn
|
||||
|
||||
last edit: 93/06/06 johns
|
||||
use Malloc instead of xmalloc.
|
||||
|
||||
last edit: 86/05/30 rms
|
||||
include config.h, since on VMS it renames some symbols.
|
||||
Use xmalloc instead of malloc.
|
||||
|
||||
This implementation of the PWB library alloca() function,
|
||||
which is used to allocate space off the run-time stack so
|
||||
that it is automatically reclaimed upon procedure exit,
|
||||
was inspired by discussions with J. Q. Johnson of Cornell.
|
||||
|
||||
It should work under any C implementation that uses an
|
||||
actual procedure stack (as opposed to a linked list of
|
||||
frames). There are some preprocessor constants that can
|
||||
be defined when compiling for your specific system, for
|
||||
improved efficiency; however, the defaults should be okay.
|
||||
|
||||
The general concept of this implementation is to keep
|
||||
track of all alloca()-allocated blocks, and reclaim any
|
||||
that are found to be deeper in the stack than the current
|
||||
invocation. This heuristic does not reclaim storage as
|
||||
soon as it becomes invalid, but it will do so eventually.
|
||||
|
||||
As a special case, alloca(0) reclaims storage without
|
||||
allocating any. It is a good idea to use alloca(0) in
|
||||
your main control loop, etc. to force garbage collection.
|
||||
*/
|
||||
#ifndef lint
|
||||
static char SCCSid[] = "@(#)alloca.c 1.1"; /* for the "what" utility */
|
||||
#endif
|
||||
|
||||
#ifdef emacs
|
||||
#include "config.h"
|
||||
#ifdef static
|
||||
/* actually, only want this if static is defined as ""
|
||||
-- this is for usg, in which emacs must undefine static
|
||||
in order to make unexec workable
|
||||
*/
|
||||
#ifndef STACK_DIRECTION
|
||||
you
|
||||
lose
|
||||
-- must know STACK_DIRECTION at compile-time
|
||||
#endif /* STACK_DIRECTION undefined */
|
||||
#endif /* static */
|
||||
#endif /* emacs */
|
||||
|
||||
#ifndef alloca /* If compiling with GCC, this file's not needed. */
|
||||
|
||||
#ifdef __STDC__
|
||||
typedef void *pointer; /* generic pointer type */
|
||||
#else
|
||||
typedef char *pointer; /* generic pointer type */
|
||||
#endif
|
||||
|
||||
#define NULL 0 /* null pointer constant */
|
||||
|
||||
#if 0
|
||||
extern void free();
|
||||
extern pointer xmalloc();
|
||||
#else
|
||||
/* Johns mods for swutils library. */
|
||||
#define xmalloc Malloc
|
||||
#define free Free
|
||||
#include "Malloc.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
Define STACK_DIRECTION if you know the direction of stack
|
||||
growth for your system; otherwise it will be automatically
|
||||
deduced at run-time.
|
||||
|
||||
STACK_DIRECTION > 0 => grows toward higher addresses
|
||||
STACK_DIRECTION < 0 => grows toward lower addresses
|
||||
STACK_DIRECTION = 0 => direction of growth unknown
|
||||
*/
|
||||
|
||||
#ifndef STACK_DIRECTION
|
||||
#define STACK_DIRECTION 0 /* direction unknown */
|
||||
#endif
|
||||
|
||||
#if STACK_DIRECTION != 0
|
||||
|
||||
#define STACK_DIR STACK_DIRECTION /* known at compile-time */
|
||||
|
||||
#else /* STACK_DIRECTION == 0; need run-time code */
|
||||
|
||||
static int stack_dir; /* 1 or -1 once known */
|
||||
#define STACK_DIR stack_dir
|
||||
|
||||
static void
|
||||
find_stack_direction (/* void */)
|
||||
{
|
||||
static char *addr = NULL; /* address of first
|
||||
`dummy', once known */
|
||||
auto char dummy; /* to get stack address */
|
||||
|
||||
if (addr == NULL)
|
||||
{ /* initial entry */
|
||||
addr = &dummy;
|
||||
|
||||
find_stack_direction (); /* recurse once */
|
||||
}
|
||||
else /* second entry */
|
||||
if (&dummy > addr)
|
||||
stack_dir = 1; /* stack grew upward */
|
||||
else
|
||||
stack_dir = -1; /* stack grew downward */
|
||||
}
|
||||
|
||||
#endif /* STACK_DIRECTION == 0 */
|
||||
|
||||
/*
|
||||
An "alloca header" is used to:
|
||||
(a) chain together all alloca()ed blocks;
|
||||
(b) keep track of stack depth.
|
||||
|
||||
It is very important that sizeof(header) agree with malloc()
|
||||
alignment chunk size. The following default should work okay.
|
||||
*/
|
||||
|
||||
#ifndef ALIGN_SIZE
|
||||
#define ALIGN_SIZE sizeof(double)
|
||||
#endif
|
||||
|
||||
typedef union hdr
|
||||
{
|
||||
char align[ALIGN_SIZE]; /* to force sizeof(header) */
|
||||
struct
|
||||
{
|
||||
union hdr *next; /* for chaining headers */
|
||||
char *deep; /* for stack depth measure */
|
||||
} h;
|
||||
} header;
|
||||
|
||||
/*
|
||||
alloca( size ) returns a pointer to at least `size' bytes of
|
||||
storage which will be automatically reclaimed upon exit from
|
||||
the procedure that called alloca(). Originally, this space
|
||||
was supposed to be taken from the current stack frame of the
|
||||
caller, but that method cannot be made to work for some
|
||||
implementations of C, for example under Gould's UTX/32.
|
||||
*/
|
||||
|
||||
static header *last_alloca_header = NULL; /* -> last alloca header */
|
||||
|
||||
pointer
|
||||
alloca (size) /* returns pointer to storage */
|
||||
unsigned size; /* # bytes to allocate */
|
||||
{
|
||||
auto char probe; /* probes stack depth: */
|
||||
register char *depth = &probe;
|
||||
|
||||
#if STACK_DIRECTION == 0
|
||||
if (STACK_DIR == 0) /* unknown growth direction */
|
||||
find_stack_direction ();
|
||||
#endif
|
||||
|
||||
/* Reclaim garbage, defined as all alloca()ed storage that
|
||||
was allocated from deeper in the stack than currently. */
|
||||
|
||||
{
|
||||
register header *hp; /* traverses linked list */
|
||||
|
||||
for (hp = last_alloca_header; hp != NULL;)
|
||||
if ((STACK_DIR > 0 && hp->h.deep > depth)
|
||||
|| (STACK_DIR < 0 && hp->h.deep < depth))
|
||||
{
|
||||
register header *np = hp->h.next;
|
||||
|
||||
free ((pointer) hp); /* collect garbage */
|
||||
|
||||
hp = np; /* -> next header */
|
||||
}
|
||||
else
|
||||
break; /* rest are not deeper */
|
||||
|
||||
last_alloca_header = hp; /* -> last valid storage */
|
||||
}
|
||||
|
||||
if (size == 0)
|
||||
return NULL; /* no allocation required */
|
||||
|
||||
/* Allocate combined header + user data storage. */
|
||||
|
||||
{
|
||||
register pointer new = xmalloc (sizeof (header) + size);
|
||||
/* address of header */
|
||||
|
||||
((header *)new)->h.next = last_alloca_header;
|
||||
((header *)new)->h.deep = depth;
|
||||
|
||||
last_alloca_header = (header *)new;
|
||||
|
||||
/* User storage begins just after header. */
|
||||
|
||||
return (pointer)((char *)new + sizeof(header));
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* no alloca */
|
82
external/libsdf/libsw/batch.c
vendored
Normal file
82
external/libsdf/libsw/batch.c
vendored
Normal file
|
@ -0,0 +1,82 @@
|
|||
/* batch.c: Collect a series of small sends into larger ones */
|
||||
|
||||
#include "batch.h"
|
||||
#include "mpmy.h"
|
||||
#include "stk.h"
|
||||
#include "Malloc.h"
|
||||
#include "Msgs.h"
|
||||
|
||||
void PollWait(MPMY_Comm_request req, int tag);
|
||||
|
||||
static Stk **stks;
|
||||
static int tag;
|
||||
static int batch_size;
|
||||
|
||||
void
|
||||
SetupBatch(int ttag, int size)
|
||||
{
|
||||
int dest;
|
||||
|
||||
Msgf(("SetupBatch: tag %d size %d\n", ttag, size));
|
||||
tag = ttag;
|
||||
batch_size = size;
|
||||
stks = Calloc(MPMY_Nproc(), sizeof(Stk *));
|
||||
/* allocate all memory beforehand */
|
||||
/* Otherwise the incoming poll buffer will fight with the batch stks */
|
||||
/* for heap space, and we end up with a bunch of holes in the heap */
|
||||
for (dest = 0; dest < MPMY_Nproc(); dest++) {
|
||||
stks[dest] = Malloc(sizeof(Stk));
|
||||
StkInit(stks[dest], batch_size, Realloc_f, 0);
|
||||
StkPushType(stks[dest], dest, int);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
FinishBatch(void)
|
||||
{
|
||||
int i;
|
||||
MPMY_Comm_request req;
|
||||
int nproc = MPMY_Nproc();
|
||||
int procnum = MPMY_Procnum();
|
||||
int procs_per_node = MPMY_ProcsPerNode();
|
||||
int my_master = (procnum / procs_per_node) * procs_per_node;
|
||||
int ddest;
|
||||
|
||||
for (i = 0; i < nproc; i++) {
|
||||
Stk *s = stks[i];
|
||||
if (StkSz(s) > sizeof(int)) {
|
||||
ddest = (i / procs_per_node) * procs_per_node;
|
||||
if (ddest == my_master) ddest = i;
|
||||
Msgf(("SendBatch: %ld to %d via %d\n", StkSz(s), i, ddest));
|
||||
MPMY_Isend(StkBase(s), StkSz(s), ddest, tag, &req);
|
||||
PollWait(req, tag);
|
||||
}
|
||||
StkTerminate(s);
|
||||
Free(s);
|
||||
}
|
||||
Free(stks);
|
||||
Msgf(("FinishBatch done\n"));
|
||||
}
|
||||
|
||||
void
|
||||
SendBatch(void *outbuf, int size, int dest)
|
||||
{
|
||||
Stk *s = stks[dest];
|
||||
|
||||
StkPushData(s, outbuf, size);
|
||||
if (StkSz(s) > batch_size - size) {
|
||||
MPMY_Comm_request req;
|
||||
int ddest, my_master;
|
||||
int procs_per_node = MPMY_ProcsPerNode();
|
||||
int procnum = MPMY_Procnum();
|
||||
|
||||
ddest = (dest / procs_per_node) * procs_per_node;
|
||||
my_master = (procnum / procs_per_node) * procs_per_node;
|
||||
if (ddest == my_master) ddest = dest;
|
||||
Msgf(("SendBatch: %ld to %d via %d\n", StkSz(s), dest, ddest));
|
||||
MPMY_Isend(StkBase(s), StkSz(s), ddest, tag, &req);
|
||||
PollWait(req, tag);
|
||||
StkClear(s);
|
||||
StkPushType(s, dest, int);
|
||||
}
|
||||
}
|
6
external/libsdf/libsw/bcopy.c
vendored
Normal file
6
external/libsdf/libsw/bcopy.c
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
#include <string.h>
|
||||
|
||||
void bcopy(void *b1, void *b2, int length){
|
||||
memmove(b2, b1, length);
|
||||
}
|
||||
|
127
external/libsdf/libsw/byteswap.c
vendored
Normal file
127
external/libsdf/libsw/byteswap.c
vendored
Normal file
|
@ -0,0 +1,127 @@
|
|||
/* Functions to do general byte swapping: */
|
||||
|
||||
#include <string.h>
|
||||
#include "byteswap.h"
|
||||
|
||||
static int swap2(int, void *, void *);
|
||||
static int swap4(int, void *, void *);
|
||||
static int swap8(int, void *, void *);
|
||||
static int swapgen(int, int, void *, void *);
|
||||
|
||||
/* A general, in-place, byte-swapper. */
|
||||
/* It swaps a total of unit_len*n_units bytes, unit_len bytes at a time. */
|
||||
/* Thus, you can use it for arrays of doubles with unit_len=8, or */
|
||||
/* arrays of chars with unit_len=1 (which is equivalent to memcpy). */
|
||||
/* It checks for stupid arguments. It works fine when */
|
||||
/* from and to are identical. It breaks if from and to are */
|
||||
/* almost the same. */
|
||||
int Byteswap(int unit_len, int n_units, void *from, void *to)
|
||||
{
|
||||
int ptrdiff;
|
||||
|
||||
if(n_units < 0 || unit_len < 0){
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* This isn't ANSI conforming. I don't think it can be. */
|
||||
/* It's the canonical "You can't write memcpy in ANSI C because */
|
||||
/* you can't compare the pointers and learn anything reliable." */
|
||||
/* problem. The compiler is free to return nonsense for ptrdiff. */
|
||||
ptrdiff = (char *)from - (char *)to;
|
||||
if( ptrdiff != 0 && (ptrdiff < unit_len*n_units && ptrdiff > -unit_len) ){
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch(unit_len){
|
||||
case 1:
|
||||
memcpy(to, from, n_units);
|
||||
return 0;
|
||||
case 2:
|
||||
return swap2(n_units, from, to);
|
||||
case 4:
|
||||
return swap4(n_units, from, to);
|
||||
case 8:
|
||||
return swap8(n_units, from, to);
|
||||
default:
|
||||
return swapgen(unit_len, n_units, from, to);
|
||||
}
|
||||
}
|
||||
|
||||
static int swap2(int n, void *from, void *to)
|
||||
{
|
||||
char *fromc = from;
|
||||
char *toc = to;
|
||||
char tmp;
|
||||
|
||||
while(n--){
|
||||
tmp = fromc[0];
|
||||
toc[0] = fromc[1];
|
||||
toc[0] = tmp;
|
||||
fromc+= 2;
|
||||
toc += 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int swap4(int n, void *from, void *to)
|
||||
{
|
||||
char *toc = to;
|
||||
char *fromc = from;
|
||||
char tmp;
|
||||
|
||||
while(n--){
|
||||
tmp = fromc[3];
|
||||
toc[3] = fromc[0];
|
||||
toc[0] = tmp;
|
||||
tmp = fromc[2];
|
||||
toc[2] = fromc[1];
|
||||
toc[1] = tmp;
|
||||
fromc += 4;
|
||||
toc += 4;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int swap8(int n, void *from, void *to)
|
||||
{
|
||||
char *toc = to;
|
||||
char *fromc = from;
|
||||
char tmp;
|
||||
|
||||
while(n--){
|
||||
tmp = fromc[7];
|
||||
toc[7] = fromc[0];
|
||||
toc[0] = tmp;
|
||||
tmp = fromc[6];
|
||||
toc[6] = fromc[1];
|
||||
toc[1] = tmp;
|
||||
tmp = fromc[5];
|
||||
toc[5] = fromc[2];
|
||||
toc[2] = tmp;
|
||||
tmp = fromc[4];
|
||||
toc[4] = fromc[3];
|
||||
toc[3] = tmp;
|
||||
fromc += 8;
|
||||
toc += 8;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int swapgen(int unit_len, int nunits, void *from, void *to)
|
||||
{
|
||||
char *toc = to;
|
||||
char *fromc = from;
|
||||
char tmp;
|
||||
int i;
|
||||
|
||||
while(nunits--){
|
||||
for(i=0; i<unit_len/2; i++){
|
||||
tmp = fromc[unit_len-i];
|
||||
toc[unit_len-i] = fromc[i];
|
||||
toc[i] = tmp;
|
||||
toc += unit_len;
|
||||
fromc += unit_len;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
161
external/libsdf/libsw/chn.c
vendored
Normal file
161
external/libsdf/libsw/chn.c
vendored
Normal file
|
@ -0,0 +1,161 @@
|
|||
/*
|
||||
* Copyright (c) 1989, 1990 John Salmon & Mike Warren,
|
||||
* California Institute of Technology, Pasadena, CA.
|
||||
*/
|
||||
|
||||
/*
|
||||
CHN.C: Routines for allocating and freeing memory
|
||||
in fixed length blocks. CHN is mnemonic for either 'chain' or 'chunk'.
|
||||
The idea is that malloc is called infrequently to get large chunks
|
||||
which are broken down into smaller pieces which are chained together
|
||||
to make a freelist. ChnAlloc and ChnFree are very fast O(1), and
|
||||
use memory efficiently even for small objects. In contrast,
|
||||
malloc and free are often slow and typically waste several bytes per
|
||||
allocated object. The down side is that fragmentation problems can be
|
||||
magnified. Once a large chunk is allocated it never gets freed, even
|
||||
if all the objects in it have been freed.
|
||||
* Entry points:
|
||||
* void ChnInit(Chn *id, int sz, int nalloc,
|
||||
* void *(realloc_like)(void *, size_t));
|
||||
* void *ChnAlloc(Chn *id);
|
||||
* void ChnFree(Chn *id, Void *p);
|
||||
* void ChnFreeAll(Chn *id);
|
||||
* void ChnTerminate(Chn *id);
|
||||
* int ChnCheck(Chn *id);
|
||||
* It wouldn't be hard to write "ChnCrunch" which would look for chunks
|
||||
* that have been completely freed, and return them to the system. This
|
||||
* has limited utility, but it might be handy when running near the edge
|
||||
* of memory.
|
||||
*/
|
||||
|
||||
#define CHNdotC
|
||||
#include <stddef.h>
|
||||
#include "Assert.h"
|
||||
#include "chn.h"
|
||||
#include "Msgs.h"
|
||||
#include "malloc.h"
|
||||
|
||||
/* The Chain macro is used to chain together 'freed' nodes. */
|
||||
/* We write a pointer on top of the first word and a magic */
|
||||
/* number on top of the second word. */
|
||||
#if !defined(ChnNext) || !defined(ChnMagic) || !defined(ChnMAGIC)
|
||||
# error Chn macros undefined
|
||||
#endif
|
||||
|
||||
/* STOLEN FROM OBSTACK.C */
|
||||
#ifdef __STDC__
|
||||
#define PTR_INT_TYPE ptrdiff_t
|
||||
#else
|
||||
#define PTR_INT_TYPE long
|
||||
#endif
|
||||
/* Determine default alignment. */
|
||||
struct fooalign {char x; double d;};
|
||||
#define DEFAULT_ALIGNMENT \
|
||||
((PTR_INT_TYPE) ((char *)&((struct fooalign *) 0)->d - (char *)0))
|
||||
/* END OF STOLEN CODE */
|
||||
#define ALIGNMENT_MASK (DEFAULT_ALIGNMENT-1)
|
||||
#define Align(x) ((x)+ALIGNMENT_MASK)&(~(ALIGNMENT_MASK))
|
||||
#define ChnHDRSZ (Align(sizeof(int)+sizeof(void *)))
|
||||
|
||||
void ChnInit(Chn *new, int sz, int nalloc,
|
||||
void *(*realloc_like)(void *, size_t))
|
||||
{
|
||||
if(sz < ChnHDRSZ)
|
||||
sz = ChnHDRSZ;
|
||||
|
||||
new->sz = Align(sz);
|
||||
Msgf(("chn=%#lx, sz=%d, new->sz=%d\n", (unsigned long)new, sz, new->sz));
|
||||
new->nalloc = nalloc;
|
||||
new->free_list = NULL;
|
||||
new->free_cnt = 0;
|
||||
new->nmalloced = 0;
|
||||
new->realloc_like = realloc_like;
|
||||
new->first_chunk = NULL;
|
||||
}
|
||||
|
||||
void ChnFreeAll(Chn *id)
|
||||
{
|
||||
void *chunk, *nextchunk;
|
||||
|
||||
Msgf(("ChnFreeAll(%#lx)\n", (unsigned long)id));
|
||||
for(chunk=id->first_chunk; chunk ; chunk = nextchunk){
|
||||
nextchunk = ChnNext(chunk);
|
||||
Msgf(("ChnFree(%#lx)\n", (unsigned long)chunk));
|
||||
id->realloc_like(chunk, 0);
|
||||
}
|
||||
id->free_cnt = 0;
|
||||
id->free_list = NULL;
|
||||
id->nmalloced = 0;
|
||||
}
|
||||
|
||||
void ChnTerminate(Chn *id)
|
||||
{
|
||||
ChnFreeAll(id);
|
||||
id->realloc_like = NULL;
|
||||
}
|
||||
|
||||
int ChnCheck(Chn *id)
|
||||
/* Return < 0 if there is something wrong with the freelist. */
|
||||
/* Return 0 if all is ok. */
|
||||
{
|
||||
int i=0;
|
||||
void *p = id->free_list;
|
||||
|
||||
while(p){
|
||||
if(ChnMagic(p) != ChnMAGIC)
|
||||
return -1;
|
||||
if(i++ < id->free_cnt)
|
||||
return -2;
|
||||
p = ChnNext(p);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ChnMoreMem: grab some more memory for a Chn.
|
||||
*/
|
||||
int ChnMoreMem(Chn *id)
|
||||
{
|
||||
void *newchunk;
|
||||
int i, sz, nnew;
|
||||
char *p;
|
||||
|
||||
if( id->free_cnt == 0 && id->free_list != NULL ){
|
||||
SeriousWarning("Impossible situation in ChnMoreMem, freecnt=0, free_list = %#lx\n", (unsigned long)id->free_list);
|
||||
malloc_print();
|
||||
}
|
||||
|
||||
nnew = id->nalloc;
|
||||
sz = id->sz;
|
||||
while( (newchunk=id->realloc_like(NULL, nnew*sz + ChnHDRSZ)) == 0 &&
|
||||
nnew > 0 )
|
||||
nnew /= 2;
|
||||
if(newchunk == 0){
|
||||
return -1;
|
||||
}
|
||||
Msgf(("ChnMoreMem(chn=%#lx, newsz=%ld, address=%#lx)\n",
|
||||
(unsigned long)id, (unsigned long)(nnew*sz+ChnHDRSZ),
|
||||
(unsigned long)newchunk));
|
||||
|
||||
id->nmalloced += nnew;
|
||||
ChnNext(newchunk) = id->first_chunk;
|
||||
ChnMagic(newchunk) = ChnMAGIC;
|
||||
id->first_chunk = newchunk;
|
||||
newchunk = (char *)newchunk + ChnHDRSZ;
|
||||
|
||||
p = (char *)newchunk;
|
||||
for(i=0; i<nnew-1; i++){
|
||||
ChnNext(p) = (int *)(p + sz);
|
||||
ChnMagic(p) = ChnMAGIC;
|
||||
p += sz;
|
||||
}
|
||||
ChnNext(p) = id->free_list;
|
||||
ChnMagic(p) = ChnMAGIC;
|
||||
id->free_list = newchunk;
|
||||
id->free_cnt += nnew;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* end of: CHN.C
|
||||
*/
|
96
external/libsdf/libsw/class_params.c
vendored
Normal file
96
external/libsdf/libsw/class_params.c
vendored
Normal file
|
@ -0,0 +1,96 @@
|
|||
#include "class.h"
|
||||
#include "cosmo.h"
|
||||
#include "Malloc.h"
|
||||
#include "error.h"
|
||||
|
||||
#define class_fail(function, \
|
||||
error_message_from_function, \
|
||||
error_message_output) \
|
||||
do { \
|
||||
if (function == _FAILURE_) { \
|
||||
ErrorMsg Transmit_Error_Message; \
|
||||
sprintf(Transmit_Error_Message,"%s(L:%d) : error in %s;\n=>%s", \
|
||||
__func__,__LINE__,#function,error_message_from_function); \
|
||||
Error("%s",Transmit_Error_Message); \
|
||||
} \
|
||||
} while(0);
|
||||
|
||||
struct class_s {
|
||||
struct precision pr; /* for precision parameters */
|
||||
struct background ba; /* for cosmological background */
|
||||
struct thermo th; /* for thermodynamics */
|
||||
struct perturbs pt; /* for source functions */
|
||||
struct bessels bs; /* for bessel functions */
|
||||
struct transfers tr; /* for transfer functions */
|
||||
struct primordial pm; /* for primordial spectra */
|
||||
struct spectra sp; /* for output spectra */
|
||||
struct nonlinear nl; /* for non-linear spectra */
|
||||
struct lensing le; /* for lensed spectra */
|
||||
struct output op; /* for output files */
|
||||
};
|
||||
|
||||
void
|
||||
class_params(cosmology *c, char *class_ini)
|
||||
{
|
||||
struct file_content fc;
|
||||
struct class_s *p;
|
||||
double *pvec;
|
||||
ErrorMsg errmsg;
|
||||
|
||||
fc.size = 0;
|
||||
|
||||
p = Calloc(1,sizeof(struct class_s));
|
||||
|
||||
class_fail(parser_read_file(class_ini,&fc,errmsg),
|
||||
errmsg,errmsg);
|
||||
|
||||
class_fail(input_init(&fc, &p->pr, &p->ba, &p->th, &p->pt, &p->bs, &p->tr,
|
||||
&p->pm, &p->sp, &p->nl, &p->le, &p->op, errmsg),
|
||||
errmsg, errmsg);
|
||||
|
||||
class_fail(parser_free(&fc),errmsg,errmsg);
|
||||
|
||||
p->ba.background_verbose = 0;
|
||||
|
||||
class_fail(background_init(&p->pr, &p->ba),errmsg,errmsg);
|
||||
|
||||
pvec = Malloc(p->ba.bg_size*sizeof(double));
|
||||
class_fail(background_functions(&p->ba, 1.0, p->ba.long_info, pvec),
|
||||
errmsg, errmsg);
|
||||
c->Omega0_m = pvec[p->ba.index_bg_Omega_m];
|
||||
c->Omega0_r = pvec[p->ba.index_bg_Omega_r];
|
||||
Free(pvec);
|
||||
|
||||
c->Omega0 = p->ba.Omega0_g + p->ba.Omega0_b;
|
||||
if (p->ba.has_cdm == _TRUE_) {
|
||||
c->Omega0 += p->ba.Omega0_cdm;
|
||||
}
|
||||
if (p->ba.has_ncdm == _TRUE_) {
|
||||
c->Omega0 += p->ba.Omega0_ncdm_tot;
|
||||
}
|
||||
if (p->ba.has_lambda == _TRUE_) {
|
||||
c->Omega0 += p->ba.Omega0_lambda;
|
||||
}
|
||||
if (p->ba.has_fld == _TRUE_) {
|
||||
c->Omega0 += p->ba.Omega0_fld;
|
||||
}
|
||||
if (p->ba.has_ur == _TRUE_) {
|
||||
c->Omega0 += p->ba.Omega0_ur;
|
||||
}
|
||||
c->h_100 = p->ba.h;
|
||||
c->H0 = p->ba.H0*_Gyr_over_Mpc_;
|
||||
c->Omega0_cdm = p->ba.Omega0_cdm;
|
||||
c->Omega0_ncdm_tot = p->ba.Omega0_ncdm_tot;
|
||||
c->Omega0_b = p->ba.Omega0_b;
|
||||
c->Omega0_g = p->ba.Omega0_g;
|
||||
c->Omega0_ur = p->ba.Omega0_ur;
|
||||
c->Omega0_lambda = p->ba.Omega0_lambda;
|
||||
c->Omega0_fld = p->ba.Omega0_fld;
|
||||
c->w0_fld = p->ba.w0_fld;
|
||||
c->wa_fld = p->ba.wa_fld;
|
||||
c->age = p->ba.age;
|
||||
c->Gnewt = GM_cgs*(g_Msol10/g_Msol)*pow(sec_Gyr, 2)/pow(cm_kpc,3);
|
||||
|
||||
class_fail(background_free(&p->ba),errmsg,errmsg);
|
||||
Free(p);
|
||||
}
|
366
external/libsdf/libsw/class_wrap.c
vendored
Normal file
366
external/libsdf/libsw/class_wrap.c
vendored
Normal file
|
@ -0,0 +1,366 @@
|
|||
#include "class.h"
|
||||
#include "cosmo.h"
|
||||
#include "Malloc.h"
|
||||
#include "error.h"
|
||||
|
||||
#define ERRTOL 5e-8
|
||||
|
||||
#define class_fail(function, \
|
||||
error_message_from_function, \
|
||||
error_message_output) \
|
||||
do { \
|
||||
if (function == _FAILURE_) { \
|
||||
ErrorMsg Transmit_Error_Message; \
|
||||
sprintf(Transmit_Error_Message,"%s(L:%d) : error in %s;\n=>%s", \
|
||||
__func__,__LINE__,#function,error_message_from_function); \
|
||||
Error("%s",Transmit_Error_Message); \
|
||||
} \
|
||||
} while(0);
|
||||
|
||||
|
||||
struct class_s {
|
||||
struct precision pr; /* for precision parameters */
|
||||
struct background ba; /* for cosmological background */
|
||||
struct thermo th; /* for thermodynamics */
|
||||
struct perturbs pt; /* for source functions */
|
||||
struct bessels bs; /* for bessel functions */
|
||||
struct transfers tr; /* for transfer functions */
|
||||
struct primordial pm; /* for primordial spectra */
|
||||
struct spectra sp; /* for output spectra */
|
||||
struct nonlinear nl; /* for non-linear spectra */
|
||||
struct lensing le; /* for lensed spectra */
|
||||
struct output op; /* for output files */
|
||||
};
|
||||
|
||||
static void
|
||||
class_background_at_tau(cosmology *c, double tau)
|
||||
{
|
||||
struct class_s *p = c->private;
|
||||
int idx;
|
||||
double *pvec;
|
||||
ErrorMsg errmsg;
|
||||
|
||||
pvec = Malloc(p->ba.bg_size*sizeof(double));
|
||||
class_fail(background_at_tau(&p->ba, tau, p->ba.long_info, p->ba.inter_normal,
|
||||
&idx, pvec), errmsg, errmsg);
|
||||
|
||||
c->a = pvec[p->ba.index_bg_a];
|
||||
c->z = 1.0/c->a - 1.0;
|
||||
c->t = pvec[p->ba.index_bg_time]/_Gyr_over_Mpc_;
|
||||
c->tau = tau;
|
||||
c->H = pvec[p->ba.index_bg_H]*_Gyr_over_Mpc_;
|
||||
c->conf_distance = pvec[p->ba.index_bg_conf_distance]*1000.0; /* kpc */
|
||||
c->kick = pvec[p->ba.index_bg_kick]/_Gyr_over_Mpc_;
|
||||
c->drift = pvec[p->ba.index_bg_drift]/_Gyr_over_Mpc_;
|
||||
c->Omega_r = pvec[p->ba.index_bg_Omega_r];
|
||||
c->Omega_m = pvec[p->ba.index_bg_Omega_m];
|
||||
Free(pvec);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
class_background_at_z(cosmology *c, double z)
|
||||
{
|
||||
struct class_s *p = c->private;
|
||||
double tau;
|
||||
double err;
|
||||
ErrorMsg errmsg;
|
||||
|
||||
class_fail(background_tau_of_z(&p->ba, z, &tau), errmsg, errmsg);
|
||||
class_background_at_tau(c, tau);
|
||||
err = (1.0+c->z)/(1.0+z) - 1.0;
|
||||
if (fabs(err) > ERRTOL)
|
||||
Error("Poor precision in background_at_z, relerr = %g\n", err);
|
||||
}
|
||||
|
||||
static void
|
||||
class_background_at_t(cosmology *c, double t)
|
||||
{
|
||||
struct class_s *p = c->private;
|
||||
double tau;
|
||||
double err;
|
||||
ErrorMsg errmsg;
|
||||
|
||||
class_fail(background_tau_of_t(&p->ba, t*_Gyr_over_Mpc_, &tau),
|
||||
errmsg, errmsg);
|
||||
class_background_at_tau(c, tau);
|
||||
err = c->t/t - 1.0;
|
||||
if (fabs(err) > ERRTOL)
|
||||
Error("Poor precision in background_at_t, relerr = %g\n", err);
|
||||
}
|
||||
|
||||
static double
|
||||
class_t_at_z(cosmology *c, double z)
|
||||
{
|
||||
if (c->z != z) class_background_at_z(c, z);
|
||||
return(c->t);
|
||||
}
|
||||
|
||||
static double
|
||||
class_z_at_t(cosmology *c, double t)
|
||||
{
|
||||
if (c->t != t) class_background_at_t(c, t);
|
||||
return(c->z);
|
||||
}
|
||||
|
||||
static double
|
||||
class_a_at_t(cosmology *c, double t)
|
||||
{
|
||||
if (c->t != t) class_background_at_t(c, t);
|
||||
return(c->a);
|
||||
}
|
||||
|
||||
static double
|
||||
class_t_at_a(cosmology *c, double a)
|
||||
{
|
||||
if (c->a != a) class_background_at_z(c, 1.0/a-1.0);
|
||||
return(c->t);
|
||||
}
|
||||
|
||||
static double
|
||||
class_H_at_z(cosmology *c, double z)
|
||||
{
|
||||
struct class_s *p = c->private;
|
||||
double *pvec;
|
||||
ErrorMsg errmsg;
|
||||
double a = 1.0/(1.0+z);
|
||||
double H;
|
||||
|
||||
pvec = Malloc(p->ba.bg_size_normal*sizeof(double));
|
||||
class_fail(background_functions(&p->ba, a, p->ba.short_info, pvec),
|
||||
errmsg, errmsg);
|
||||
H = pvec[p->ba.index_bg_H]*_Gyr_over_Mpc_;
|
||||
Free(pvec);
|
||||
return(H);
|
||||
}
|
||||
|
||||
static double
|
||||
class_H_at_t(cosmology *c, double t)
|
||||
{
|
||||
if (c->t != t) class_background_at_t(c, t);
|
||||
return(c->H);
|
||||
}
|
||||
|
||||
|
||||
static double
|
||||
class_conformal_distance_at_z(cosmology *c, double z)
|
||||
{
|
||||
if (c->z != z) class_background_at_z(c, z);
|
||||
return(c->conf_distance);
|
||||
}
|
||||
|
||||
static double
|
||||
class_conformal_distance_at_t(cosmology *c, double t)
|
||||
{
|
||||
if (c->t != t) class_background_at_t(c, t);
|
||||
return(c->conf_distance);
|
||||
}
|
||||
|
||||
static double
|
||||
class_angular_diameter_distance_at_z(cosmology *c, double z)
|
||||
{
|
||||
if (c->z != z) class_background_at_z(c, z);
|
||||
return(c->conf_distance/(1.0+z));
|
||||
}
|
||||
|
||||
static double
|
||||
class_angular_diameter_distance_at_t(cosmology *c, double t)
|
||||
{
|
||||
if (c->t != t) class_background_at_t(c, t);
|
||||
return(c->conf_distance/(1.0+c->z));
|
||||
}
|
||||
|
||||
static double
|
||||
class_luminosity_distance_at_z(cosmology *c, double z)
|
||||
{
|
||||
if (c->z != z) class_background_at_z(c, z);
|
||||
return(c->conf_distance*(1.0+z));
|
||||
}
|
||||
|
||||
static double
|
||||
class_luminosity_distance_at_t(cosmology *c, double t)
|
||||
{
|
||||
if (c->t != t) class_background_at_t(c, t);
|
||||
return(c->conf_distance*(1.0+c->z));
|
||||
}
|
||||
|
||||
static double
|
||||
class_growthfac_at_z(cosmology *c, double z)
|
||||
{
|
||||
struct class_s *p = c->private;
|
||||
double pk, pk0, *pk_ic=NULL;
|
||||
double k = 1e-7;
|
||||
ErrorMsg errmsg;
|
||||
|
||||
class_fail(spectra_pk_at_k_and_z(&p->ba, &p->pm, &p->sp, k, 0.0, &pk0, pk_ic),
|
||||
errmsg, errmsg);
|
||||
|
||||
class_fail(spectra_pk_at_k_and_z(&p->ba, &p->pm, &p->sp, k, z, &pk, pk_ic),
|
||||
errmsg, errmsg);
|
||||
|
||||
return sqrt(pk/pk0);
|
||||
}
|
||||
|
||||
static double
|
||||
class_growthfac_at_t(cosmology *c, double t)
|
||||
{
|
||||
return(class_growthfac_at_z(c, class_z_at_t(c, t)));
|
||||
}
|
||||
|
||||
static double
|
||||
class_kick_t0_t1(cosmology *c, double t0, double t1)
|
||||
{
|
||||
double k0, k1;
|
||||
class_background_at_t(c, t0);
|
||||
k0 = c->kick;
|
||||
class_background_at_t(c, t1);
|
||||
k1 = c->kick;
|
||||
return(k1-k0);
|
||||
}
|
||||
|
||||
|
||||
static double
|
||||
class_drift_t0_t1(cosmology *c, double t0, double t1)
|
||||
{
|
||||
double d0, d1;
|
||||
class_background_at_t(c, t0);
|
||||
d0 = c->drift;
|
||||
class_background_at_t(c, t1);
|
||||
d1 = c->drift;
|
||||
return(d1-d0);
|
||||
}
|
||||
|
||||
static void
|
||||
class_free(cosmology *c)
|
||||
{
|
||||
struct class_s *p = c->private;
|
||||
ErrorMsg errmsg;
|
||||
|
||||
class_fail(spectra_free(&p->sp),errmsg,errmsg);
|
||||
class_fail(primordial_free(&p->pm),errmsg,errmsg);
|
||||
class_fail(transfer_free(&p->tr),errmsg,errmsg);
|
||||
class_fail(perturb_free(&p->pt),errmsg,errmsg);
|
||||
class_fail(thermodynamics_free(&p->th),errmsg,errmsg);
|
||||
class_fail(background_free(&p->ba),errmsg,errmsg);
|
||||
Free(p);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
class_init(cosmology *c, char *class_ini, char *class_pre, double zmax)
|
||||
{
|
||||
struct file_content fc;
|
||||
struct file_content fc_input;
|
||||
struct file_content fc_precision;
|
||||
struct class_s *p;
|
||||
ErrorMsg errmsg;
|
||||
|
||||
fc.size = 0;
|
||||
fc_input.size = 0;
|
||||
fc_precision.size = 0;
|
||||
|
||||
memset(c, 0, sizeof(cosmology));
|
||||
p = Calloc(1,sizeof(struct class_s));
|
||||
|
||||
if (class_ini)
|
||||
class_fail(parser_read_file(class_ini,&fc_input,errmsg),
|
||||
errmsg,errmsg);
|
||||
|
||||
if (class_pre)
|
||||
class_fail(parser_read_file(class_pre,&fc_precision,errmsg),
|
||||
errmsg, errmsg);
|
||||
|
||||
if (class_ini || class_pre)
|
||||
class_fail(parser_cat(&fc_input,&fc_precision,&fc,errmsg),
|
||||
errmsg, errmsg);
|
||||
|
||||
class_fail(parser_free(&fc_input),errmsg,errmsg);
|
||||
class_fail(parser_free(&fc_precision),errmsg,errmsg);
|
||||
|
||||
class_fail(input_init(&fc, &p->pr, &p->ba, &p->th, &p->pt, &p->bs, &p->tr,
|
||||
&p->pm, &p->sp, &p->nl, &p->le, &p->op, errmsg),
|
||||
errmsg, errmsg);
|
||||
|
||||
class_fail(parser_free(&fc),errmsg,errmsg);
|
||||
|
||||
p->ba.background_verbose = 0;
|
||||
p->th.thermodynamics_verbose = 0;
|
||||
p->pt.perturbations_verbose = 0;
|
||||
p->tr.transfer_verbose = 0;
|
||||
p->pm.primordial_verbose = 0;
|
||||
p->sp.spectra_verbose = 0;
|
||||
|
||||
if (p->sp.z_max_pk < zmax) p->sp.z_max_pk = zmax;
|
||||
|
||||
class_fail(background_init(&p->pr, &p->ba),errmsg,errmsg);
|
||||
|
||||
class_fail(thermodynamics_init(&p->pr,&p->ba,&p->th),errmsg,errmsg);
|
||||
|
||||
class_fail(perturb_init(&p->pr,&p->ba,&p->th,&p->pt),errmsg,errmsg);
|
||||
|
||||
class_fail(transfer_init(&p->pr,&p->ba,&p->th,&p->pt,&p->bs,&p->tr),
|
||||
errmsg,errmsg);
|
||||
|
||||
class_fail(primordial_init(&p->pr,&p->pt,&p->pm),errmsg,errmsg);
|
||||
|
||||
class_fail(spectra_init(&p->pr,&p->ba,&p->pt,&p->tr,&p->pm,&p->sp),
|
||||
errmsg,errmsg);
|
||||
|
||||
c->Omega0 = p->ba.Omega0_g + p->ba.Omega0_b;
|
||||
if (p->ba.has_cdm == _TRUE_) {
|
||||
c->Omega0 += p->ba.Omega0_cdm;
|
||||
}
|
||||
if (p->ba.has_ncdm == _TRUE_) {
|
||||
c->Omega0 += p->ba.Omega0_ncdm_tot;
|
||||
}
|
||||
if (p->ba.has_lambda == _TRUE_) {
|
||||
c->Omega0 += p->ba.Omega0_lambda;
|
||||
}
|
||||
if (p->ba.has_fld == _TRUE_) {
|
||||
c->Omega0 += p->ba.Omega0_fld;
|
||||
}
|
||||
if (p->ba.has_ur == _TRUE_) {
|
||||
c->Omega0 += p->ba.Omega0_ur;
|
||||
}
|
||||
c->h_100 = p->ba.h;
|
||||
c->H0 = p->ba.H0*_Gyr_over_Mpc_;
|
||||
c->Omega0_cdm = p->ba.Omega0_cdm;
|
||||
c->Omega0_ncdm_tot = p->ba.Omega0_ncdm_tot;
|
||||
c->Omega0_b = p->ba.Omega0_b;
|
||||
c->Omega0_g = p->ba.Omega0_g;
|
||||
c->Omega0_ur = p->ba.Omega0_ur;
|
||||
c->Omega0_lambda = p->ba.Omega0_lambda;
|
||||
c->Omega0_fld = p->ba.Omega0_fld;
|
||||
c->w0_fld = p->ba.w0_fld;
|
||||
c->wa_fld = p->ba.wa_fld;
|
||||
c->age = p->ba.age;
|
||||
c->Gnewt = GNEWT;
|
||||
|
||||
c->private = p;
|
||||
class_background_at_z(c, 0.0);
|
||||
c->Omega0_m = c->Omega_m;
|
||||
c->Omega0_r = c->Omega_r;
|
||||
|
||||
/* Function pointers */
|
||||
c->background_at_z = class_background_at_z;
|
||||
c->background_at_t = class_background_at_t;
|
||||
c->background_at_tau = class_background_at_tau;
|
||||
c->t_at_z = class_t_at_z;
|
||||
c->z_at_t = class_z_at_t;
|
||||
c->a_at_t = class_a_at_t;
|
||||
c->t_at_a = class_t_at_a;
|
||||
c->H_at_z = class_H_at_z;
|
||||
c->H_at_t = class_H_at_t;
|
||||
c->conformal_distance_at_z = class_conformal_distance_at_z;
|
||||
c->conformal_distance_at_t = class_conformal_distance_at_t;
|
||||
c->angular_diameter_distance_at_z = class_angular_diameter_distance_at_z;
|
||||
c->angular_diameter_distance_at_t = class_angular_diameter_distance_at_t;
|
||||
c->luminosity_distance_at_z = class_luminosity_distance_at_z;
|
||||
c->luminosity_distance_at_t = class_luminosity_distance_at_t;
|
||||
c->growthfac_at_z = class_growthfac_at_z;
|
||||
c->growthfac_at_t = class_growthfac_at_t;
|
||||
c->kick_t0_t1 = class_kick_t0_t1;
|
||||
c->drift_t0_t1 = class_drift_t0_t1;
|
||||
c->free = class_free;
|
||||
}
|
||||
|
288
external/libsdf/libsw/cosmo.c
vendored
Normal file
288
external/libsdf/libsw/cosmo.c
vendored
Normal file
|
@ -0,0 +1,288 @@
|
|||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include "Msgs.h"
|
||||
#include "qromo.h"
|
||||
#include "cosmo.h"
|
||||
|
||||
static struct cosmo_s C;
|
||||
|
||||
static double
|
||||
adot(double a)
|
||||
{
|
||||
return C.H0*sqrt(C.Omega_m/a + C.Omega_r/(a*a) + C.Lambda*a*a + (1.0 - C.Omega0 - C.Lambda));
|
||||
}
|
||||
|
||||
static double
|
||||
addot(double a)
|
||||
{ /* factor of a? */
|
||||
return C.H0 * C.H0 * (C.Lambda*a-C.Omega_r/(a*a*a)-0.5*C.Omega_m/(a*a));
|
||||
}
|
||||
|
||||
static double
|
||||
integrand(double a)
|
||||
{
|
||||
double x;
|
||||
|
||||
x = adot(a);
|
||||
return 1.0/(x*x*x);
|
||||
|
||||
}
|
||||
|
||||
static double
|
||||
t_integrand(double a)
|
||||
{
|
||||
double x;
|
||||
|
||||
x = adot(a);
|
||||
return 1.0/x;
|
||||
}
|
||||
|
||||
static double
|
||||
dp_integrand(double a)
|
||||
{
|
||||
double x;
|
||||
|
||||
x = adot(a);
|
||||
return 1.0/(a*x);
|
||||
|
||||
}
|
||||
|
||||
static double
|
||||
kick_integrand(double t)
|
||||
{
|
||||
double a;
|
||||
|
||||
a = Anow(&C, t);
|
||||
return 1.0/a;
|
||||
|
||||
}
|
||||
|
||||
static double
|
||||
drift_integrand(double t)
|
||||
{
|
||||
double a;
|
||||
|
||||
a = Anow(&C, t);
|
||||
return 1.0/(a*a);
|
||||
}
|
||||
|
||||
double
|
||||
growthfac_from_Z(struct cosmo_s *c, double z)
|
||||
{
|
||||
double a = 1.0/(1.0+z);
|
||||
C = *c;
|
||||
return 2.5*c->H0*c->H0*adot(a)*qromod(integrand, 0.0, a, midpntd)/a;
|
||||
}
|
||||
|
||||
double
|
||||
velfac_from_Z(struct cosmo_s *c, double z)
|
||||
{
|
||||
double d, a_dot;
|
||||
double a = 1.0/(1.0+z);
|
||||
C = *c;
|
||||
d = qromod(integrand, 0.0, a, midpntd);
|
||||
a_dot = adot(a);
|
||||
return addot(a)
|
||||
*a/(a_dot*a_dot) - 1.0 + a/(a_dot*a_dot*a_dot*d);
|
||||
}
|
||||
|
||||
double
|
||||
velfac_approx_from_Z(struct cosmo_s *c, double z)
|
||||
{
|
||||
double aomega;
|
||||
double a = 1.0/(1.0+z);
|
||||
C = *c;
|
||||
aomega = C.Omega_m + C.Omega_r/a + C.Lambda*a*a*a + (1.0 - C.Omega0 - C.Lambda)*a;
|
||||
return pow(C.Omega0/aomega, 0.6);
|
||||
}
|
||||
|
||||
double
|
||||
t_from_Z(struct cosmo_s *c, double z)
|
||||
{
|
||||
double d;
|
||||
double a = 1.0/(1.0+z);
|
||||
C = *c;
|
||||
d = qromod(t_integrand, 0.0, a, midpntd);
|
||||
return (d);
|
||||
}
|
||||
|
||||
|
||||
double
|
||||
dp_from_Z(struct cosmo_s *c, double z)
|
||||
{
|
||||
double d;
|
||||
double a = 1.0/(1.0+z);
|
||||
if (a == 1.0) return 0.0;
|
||||
C = *c;
|
||||
d = qromod(dp_integrand, a, 1.0, midpntd);
|
||||
return (d);
|
||||
}
|
||||
|
||||
double
|
||||
comoving_distance_from_Z(struct cosmo_s *c, double z)
|
||||
{
|
||||
return speed_of_light*(one_Gyr/one_kpc)*dp_from_Z(c, z);
|
||||
}
|
||||
|
||||
double
|
||||
hubble_from_Z(struct cosmo_s *c, double z)
|
||||
{
|
||||
double a = 1.0/(1.0+z);
|
||||
C = *c;
|
||||
return adot(a)/a;
|
||||
}
|
||||
|
||||
double
|
||||
kick_delta(struct cosmo_s *c, double t0, double t1)
|
||||
{
|
||||
double d;
|
||||
C = *c;
|
||||
Msgf(("kick_delta %lf %lf\n", t0, t1));
|
||||
if (t0 == t1) return 0.0;
|
||||
d = qromod(kick_integrand, t0, t1, midpntd);
|
||||
return (d);
|
||||
}
|
||||
|
||||
double
|
||||
drift_delta(struct cosmo_s *c, double t0, double t1)
|
||||
{
|
||||
double d;
|
||||
C = *c;
|
||||
Msgf(("drift_delta %lf %lf\n", t0, t1));
|
||||
if (t0 == t1) return 0.0;
|
||||
d = qromod(drift_integrand, t0, t1, midpntd);
|
||||
return (d);
|
||||
}
|
||||
|
||||
double
|
||||
Anow(struct cosmo_s *c, double time)
|
||||
{
|
||||
struct cosmo_s foo;
|
||||
|
||||
foo = *c;
|
||||
CosmoPush(&foo, time);
|
||||
return foo.a;
|
||||
}
|
||||
|
||||
double
|
||||
Znow(struct cosmo_s *c, double time)
|
||||
{
|
||||
return 1.0/Anow(c, time) - 1.0;
|
||||
}
|
||||
|
||||
double
|
||||
Hnow(struct cosmo_s *c, double time)
|
||||
{
|
||||
struct cosmo_s foo;
|
||||
|
||||
foo = *c;
|
||||
CosmoPush(&foo, time);
|
||||
C = *c;
|
||||
return adot(foo.a)/foo.a;
|
||||
}
|
||||
|
||||
void CosmoPush(struct cosmo_s *p, double time)
|
||||
{
|
||||
double Omega0 = p->Omega0;
|
||||
double Omega_r = p->Omega_r;
|
||||
double Omega_m = p->Omega_m;
|
||||
double Lambda = p->Lambda;
|
||||
double H0 = p->H0;
|
||||
double H, a2, a3, aold, anew, a2dot;
|
||||
double deltat, dt;
|
||||
int i;
|
||||
int nstep;
|
||||
|
||||
/* The cosmo structure holds,H0, Omega0, Lambda' = Lambda/3H0^2, a
|
||||
and t. We integrate (forward or backward) to the new 'time' */
|
||||
|
||||
deltat = time - p->t;
|
||||
if (deltat == 0.0)
|
||||
return;
|
||||
|
||||
/* Felten et al do all their integrals with dt=1/(400 H0). We can
|
||||
do the same by choosing Nstep appropriately. In fact, we can
|
||||
do better by ensuring dt < 1/(800 H). */
|
||||
aold = p->a;
|
||||
a2 = aold*aold;
|
||||
H = (H0 / aold) * sqrt(Omega_m/aold + Omega_r/a2 + Lambda*a2 + (1.0 - Omega0 - Lambda));
|
||||
nstep = (int)(800.*H*fabs(deltat)) + 1;
|
||||
Msgf(("Cosmo push %d steps, deltat=%g, H*deltat=%g\n",
|
||||
nstep, deltat, deltat*H));
|
||||
dt = deltat/(double)nstep;
|
||||
|
||||
anew = p->a;
|
||||
for (i = 0; i < nstep; i++) {
|
||||
aold = anew;
|
||||
a2 = aold*aold;
|
||||
a3 = a2*aold;
|
||||
H = (H0 / aold) * sqrt(Omega_m/aold + Omega_r/a2 + Lambda*a2 + (1.0 - Omega0 - Lambda));
|
||||
/* Follow the advice of Felten et al. Do this to second-order */
|
||||
a2dot = H0*H0*(-0.5*Omega_m/a2 - Omega_r/a3 + Lambda*aold);
|
||||
anew = aold + dt*H*aold + 0.5*dt*dt*a2dot;
|
||||
}
|
||||
Msgf(("After push Z=%g\n", 1./anew - 1.));
|
||||
p->a = anew;
|
||||
p->t = time;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Crays don't have acosh */
|
||||
static double Acosh(double x)
|
||||
{
|
||||
return log(x + sqrt(x*x-1.0));
|
||||
}
|
||||
|
||||
static double
|
||||
growthfac_from_Z(double Omega0, double H0, double Z)
|
||||
{
|
||||
/* This is just the growing mode */
|
||||
/* See Weinberg 15.9.27--15.9.31 or Peebles LSS 11.16 */
|
||||
double d, d0;
|
||||
|
||||
if (Omega0 == 1.0) {
|
||||
d = 1.0/(1.0+Z);
|
||||
d0 = 1.0;
|
||||
} else if(Omega0 < 1.0) {
|
||||
/* Using doubles can cause roundoff problems near Omega0=1 */
|
||||
double psi, coshpsi;
|
||||
coshpsi = 1.0 + 2.0*(1.0 - Omega0)/(Omega0*(1.0+Z));
|
||||
psi = Acosh(coshpsi);
|
||||
d = - 3.0 * psi * sinh(psi)/((coshpsi-1.0)*(coshpsi-1.0))
|
||||
+ (5.0+coshpsi)/(coshpsi-1.0);
|
||||
coshpsi = 1.0 + 2.0*(1.0 - Omega0)/Omega0;
|
||||
psi = Acosh(coshpsi);
|
||||
d0 = - 3.0 * psi * sinh(psi)/((coshpsi-1.0)*(coshpsi-1.0))
|
||||
+ (5.0+coshpsi)/(coshpsi-1.0);
|
||||
} else {
|
||||
double theta, costheta;
|
||||
costheta = 1.0 - 2.0*(Omega0-1.0)/(Omega0*(1.0+Z));
|
||||
theta = acos(costheta);
|
||||
d = - 3.0 * theta * sin(theta)/((1.0-costheta)*(1.0-costheta))
|
||||
+ (5.0+costheta)/(1.0-costheta);
|
||||
costheta = 1.0 - 2.0*(Omega0-1.0)/Omega0;
|
||||
theta = acos(costheta);
|
||||
d0 = - 3.0 * theta * sin(theta)/((1.0-costheta)*(1.0-costheta))
|
||||
+ (5.0+costheta)/(1.0-costheta);
|
||||
}
|
||||
return d/d0;
|
||||
}
|
||||
|
||||
static double
|
||||
t_from_Z(double Omega0, double H0, double Z)
|
||||
{
|
||||
double t, theta, psi;
|
||||
|
||||
if(Omega0 == 1.0){
|
||||
t = (2.0/3.0) * pow(1.0+Z, -1.5);
|
||||
}else if(Omega0 < 1.0){
|
||||
psi = Acosh( 1.0 + 2.0*(1.0 - Omega0)/(Omega0*(1.0+Z)) );
|
||||
t = (Omega0/2.0)*pow(1.0-Omega0, -1.5)*(sinh(psi) - psi) ;
|
||||
}else{
|
||||
theta = acos( 1.0 - 2.0*(Omega0-1.)/(Omega0*(1.0+Z)) );
|
||||
t = (Omega0/2.0)*pow(Omega0-1.0, -1.5)*(theta-sin(theta));
|
||||
}
|
||||
t /= H0;
|
||||
return t;
|
||||
}
|
||||
#endif
|
575
external/libsdf/libsw/cosmo_tbl.c
vendored
Normal file
575
external/libsdf/libsw/cosmo_tbl.c
vendored
Normal file
|
@ -0,0 +1,575 @@
|
|||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "cosmo.h"
|
||||
#include "Malloc.h"
|
||||
#include "error.h"
|
||||
#include "macr.h"
|
||||
|
||||
#define _SUCCESS_ 0
|
||||
#define _FAILURE_ 1
|
||||
#define _ERRORMSGSIZE_ 256
|
||||
typedef char ErrorMsg[_ERRORMSGSIZE_];
|
||||
#define _SPLINE_NATURAL_ 0
|
||||
#define _SPLINE_EST_DERIV_ 1
|
||||
|
||||
#define _Gyr_over_Mpc_ 3.06601394e2
|
||||
|
||||
struct tbl_s {
|
||||
int bt_size, bg_size;
|
||||
double *tau_tbl, *z_tbl, *t_tbl, *tbl;
|
||||
double *d2tau_dz2_tbl, *d2tau_dt2_tbl, *d2b_dtau2_tbl;
|
||||
ErrorMsg error_message;
|
||||
};
|
||||
|
||||
static int
|
||||
array_spline_table_lines(
|
||||
double * x, /* vector of size x_size */
|
||||
int x_size,
|
||||
double * y_array, /* array of size x_size*y_size with elements
|
||||
y_array[index_x*y_size+index_y] */
|
||||
int y_size,
|
||||
double * ddy_array, /* array of size x_size*y_size */
|
||||
short spline_mode,
|
||||
ErrorMsg errmsg
|
||||
) {
|
||||
double * p;
|
||||
double * qn;
|
||||
double * un;
|
||||
double * u;
|
||||
double sig;
|
||||
int index_x;
|
||||
int index_y;
|
||||
double dy_first;
|
||||
double dy_last;
|
||||
|
||||
u = Malloc((x_size-1) * y_size * sizeof(double));
|
||||
p = Malloc(y_size * sizeof(double));
|
||||
qn = Malloc(y_size * sizeof(double));
|
||||
un = Malloc(y_size * sizeof(double));
|
||||
|
||||
index_x=0;
|
||||
|
||||
if (spline_mode == _SPLINE_NATURAL_) {
|
||||
for (index_y=0; index_y < y_size; index_y++) {
|
||||
ddy_array[index_x*y_size+index_y] = u[index_x*y_size+index_y] = 0.0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (spline_mode == _SPLINE_EST_DERIV_) {
|
||||
|
||||
for (index_y=0; index_y < y_size; index_y++) {
|
||||
|
||||
dy_first =
|
||||
((x[2]-x[0])*(x[2]-x[0])*
|
||||
(y_array[1*y_size+index_y]-y_array[0*y_size+index_y])-
|
||||
(x[1]-x[0])*(x[1]-x[0])*
|
||||
(y_array[2*y_size+index_y]-y_array[0*y_size+index_y]))/
|
||||
((x[2]-x[0])*(x[1]-x[0])*(x[2]-x[1]));
|
||||
|
||||
ddy_array[index_x*y_size+index_y] = -0.5;
|
||||
|
||||
u[index_x*y_size+index_y] =
|
||||
(3./(x[1] - x[0]))*
|
||||
((y_array[1*y_size+index_y]-y_array[0*y_size+index_y])/
|
||||
(x[1] - x[0])-dy_first);
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
sprintf(errmsg,"%s(L:%d) Spline mode not identified: %d",__func__,__LINE__,spline_mode);
|
||||
return _FAILURE_;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (index_x=1; index_x < x_size-1; index_x++) {
|
||||
|
||||
sig = (x[index_x] - x[index_x-1])/(x[index_x+1] - x[index_x-1]);
|
||||
|
||||
for (index_y=0; index_y < y_size; index_y++) {
|
||||
|
||||
p[index_y] = sig * ddy_array[(index_x-1)*y_size+index_y] + 2.0;
|
||||
|
||||
ddy_array[index_x*y_size+index_y] = (sig-1.0)/p[index_y];
|
||||
|
||||
u[index_x*y_size+index_y] =
|
||||
(y_array[(index_x+1)*y_size+index_y] - y_array[index_x*y_size+index_y])
|
||||
/ (x[index_x+1] - x[index_x])
|
||||
- (y_array[index_x*y_size+index_y] - y_array[(index_x-1)*y_size+index_y])
|
||||
/ (x[index_x] - x[index_x-1]);
|
||||
|
||||
u[index_x*y_size+index_y] = (6.0 * u[index_x*y_size+index_y] /
|
||||
(x[index_x+1] - x[index_x-1])
|
||||
- sig * u[(index_x-1)*y_size+index_y]) / p[index_y];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (spline_mode == _SPLINE_NATURAL_) {
|
||||
|
||||
for (index_y=0; index_y < y_size; index_y++) {
|
||||
qn[index_y]=un[index_y]=0.0;
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
if (spline_mode == _SPLINE_EST_DERIV_) {
|
||||
|
||||
for (index_y=0; index_y < y_size; index_y++) {
|
||||
|
||||
dy_last =
|
||||
((x[x_size-3]-x[x_size-1])*(x[x_size-3]-x[x_size-1])*
|
||||
(y_array[(x_size-2)*y_size+index_y]-y_array[(x_size-1)*y_size+index_y])-
|
||||
(x[x_size-2]-x[x_size-1])*(x[x_size-2]-x[x_size-1])*
|
||||
(y_array[(x_size-3)*y_size+index_y]-y_array[(x_size-1)*y_size+index_y]))/
|
||||
((x[x_size-3]-x[x_size-1])*(x[x_size-2]-x[x_size-1])*(x[x_size-3]-x[x_size-2]));
|
||||
|
||||
qn[index_y]=0.5;
|
||||
|
||||
un[index_y]=
|
||||
(3./(x[x_size-1] - x[x_size-2]))*
|
||||
(dy_last-(y_array[(x_size-1)*y_size+index_y] - y_array[(x_size-2)*y_size+index_y])/
|
||||
(x[x_size-1] - x[x_size-2]));
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
sprintf(errmsg,"%s(L:%d) Spline mode not identified: %d",__func__,__LINE__,spline_mode);
|
||||
return _FAILURE_;
|
||||
}
|
||||
}
|
||||
|
||||
index_x=x_size-1;
|
||||
|
||||
for (index_y=0; index_y < y_size; index_y++) {
|
||||
ddy_array[index_x*y_size+index_y] =
|
||||
(un[index_y] - qn[index_y] * u[(index_x-1)*y_size+index_y]) /
|
||||
(qn[index_y] * ddy_array[(index_x-1)*y_size+index_y] + 1.0);
|
||||
}
|
||||
|
||||
for (index_x=x_size-2; index_x >= 0; index_x--) {
|
||||
for (index_y=0; index_y < y_size; index_y++) {
|
||||
|
||||
ddy_array[index_x*y_size+index_y] = ddy_array[index_x*y_size+index_y] *
|
||||
ddy_array[(index_x+1)*y_size+index_y] + u[index_x*y_size+index_y];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Free(qn);
|
||||
Free(un);
|
||||
Free(p);
|
||||
Free(u);
|
||||
|
||||
return _SUCCESS_;
|
||||
}
|
||||
|
||||
/**
|
||||
* interpolate to get y_i(x), when x and y_i are in different arrays
|
||||
*
|
||||
*/
|
||||
static int
|
||||
array_interpolate_spline(
|
||||
double * x_array,
|
||||
int n_lines,
|
||||
double * array,
|
||||
double * array_splined,
|
||||
int n_columns,
|
||||
double x,
|
||||
int * last_index,
|
||||
double * result,
|
||||
int result_size, /** from 1 to n_columns */
|
||||
ErrorMsg errmsg) {
|
||||
|
||||
int inf,sup,mid,i;
|
||||
double h,a,b;
|
||||
|
||||
inf=0;
|
||||
sup=n_lines-1;
|
||||
|
||||
if (x_array[inf] < x_array[sup]){
|
||||
|
||||
if (x < x_array[inf]) {
|
||||
sprintf(errmsg,"%s(L:%d) : x=%e < x_min=%e",__func__,__LINE__,x,x_array[inf]);
|
||||
return _FAILURE_;
|
||||
}
|
||||
|
||||
if (x > x_array[sup]) {
|
||||
sprintf(errmsg,"%s(L:%d) : x=%e > x_max=%e",__func__,__LINE__,x,x_array[sup]);
|
||||
return _FAILURE_;
|
||||
}
|
||||
|
||||
while (sup-inf > 1) {
|
||||
|
||||
mid=(int)(0.5*(inf+sup));
|
||||
if (x < x_array[mid]) {sup=mid;}
|
||||
else {inf=mid;}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
if (x < x_array[sup]) {
|
||||
sprintf(errmsg,"%s(L:%d) : x=%e < x_min=%e",__func__,__LINE__,x,x_array[sup]);
|
||||
return _FAILURE_;
|
||||
}
|
||||
|
||||
if (x > x_array[inf]) {
|
||||
sprintf(errmsg,"%s(L:%d) : x=%e > x_max=%e",__func__,__LINE__,x,x_array[inf]);
|
||||
return _FAILURE_;
|
||||
}
|
||||
|
||||
while (sup-inf > 1) {
|
||||
|
||||
mid=(int)(0.5*(inf+sup));
|
||||
if (x > x_array[mid]) {sup=mid;}
|
||||
else {inf=mid;}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
*last_index = inf;
|
||||
|
||||
h = x_array[sup] - x_array[inf];
|
||||
b = (x-x_array[inf])/h;
|
||||
a = 1-b;
|
||||
|
||||
for (i=0; i<result_size; i++)
|
||||
*(result+i) =
|
||||
a * *(array+inf*n_columns+i) +
|
||||
b * *(array+sup*n_columns+i) +
|
||||
((a*a*a-a)* *(array_splined+inf*n_columns+i) +
|
||||
(b*b*b-b)* *(array_splined+sup*n_columns+i))*h*h/6.;
|
||||
|
||||
return _SUCCESS_;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
tbl_background_at_tau(cosmology *c, double tau)
|
||||
{
|
||||
struct tbl_s *p = c->private;
|
||||
int last_index;
|
||||
double *pvec = Malloc(p->bg_size*sizeof(double));
|
||||
|
||||
array_interpolate_spline(p->tau_tbl,
|
||||
p->bt_size,
|
||||
p->tbl,
|
||||
p->d2b_dtau2_tbl,
|
||||
p->bg_size,
|
||||
tau,
|
||||
&last_index,
|
||||
pvec,
|
||||
p->bg_size,
|
||||
p->error_message);
|
||||
c->z = pvec[0];
|
||||
c->t = pvec[1]/_Gyr_over_Mpc_;
|
||||
c->tau = tau;
|
||||
c->a = 1.0/(1.0+c->z);
|
||||
c->H = pvec[2]*_Gyr_over_Mpc_;
|
||||
c->conf_distance = pvec[3]*1000.0; /* kpc */
|
||||
c->kick = tau/_Gyr_over_Mpc_;;
|
||||
c->drift = pvec[4]/_Gyr_over_Mpc_;
|
||||
c->growthfac = pvec[5];
|
||||
/* c->velfac = pow(c->Omega0_m/(c->a*c->a*c->a)*c->H0*c->H0/(c->H*c->H), 0.6); */
|
||||
c->velfac = pvec[7];
|
||||
c->velfac2 = 2.0*pow(c->Omega0_m/(c->a*c->a*c->a)*c->H0*c->H0/(c->H*c->H), 4./7.);
|
||||
Free(pvec);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
tbl_background_at_z(cosmology *c, double z)
|
||||
{
|
||||
struct tbl_s *p = c->private;
|
||||
int last_index;
|
||||
double tau;
|
||||
|
||||
array_interpolate_spline(p->z_tbl,
|
||||
p->bt_size,
|
||||
p->tau_tbl,
|
||||
p->d2tau_dz2_tbl,
|
||||
1,
|
||||
z,
|
||||
&last_index,
|
||||
&tau,
|
||||
1,
|
||||
p->error_message);
|
||||
tbl_background_at_tau(c, tau);
|
||||
}
|
||||
|
||||
static void
|
||||
tbl_background_at_t(cosmology *c, double t)
|
||||
{
|
||||
struct tbl_s *p = c->private;
|
||||
int last_index;
|
||||
double tau;
|
||||
|
||||
array_interpolate_spline(p->t_tbl,
|
||||
p->bt_size,
|
||||
p->tau_tbl,
|
||||
p->d2tau_dt2_tbl,
|
||||
1,
|
||||
t*_Gyr_over_Mpc_,
|
||||
&last_index,
|
||||
&tau,
|
||||
1,
|
||||
p->error_message);
|
||||
tbl_background_at_tau(c, tau);
|
||||
}
|
||||
|
||||
static double
|
||||
tbl_t_at_z(cosmology *c, double z)
|
||||
{
|
||||
tbl_background_at_z(c, z);
|
||||
return(c->t);
|
||||
}
|
||||
|
||||
static double
|
||||
tbl_z_at_t(cosmology *c, double t)
|
||||
{
|
||||
tbl_background_at_t(c, t);
|
||||
return(c->z);
|
||||
}
|
||||
|
||||
static double
|
||||
tbl_a_at_t(cosmology *c, double t)
|
||||
{
|
||||
tbl_background_at_t(c, t);
|
||||
return(c->a);
|
||||
}
|
||||
|
||||
static double
|
||||
tbl_t_at_a(cosmology *c, double a)
|
||||
{
|
||||
tbl_background_at_z(c, 1.0/a-1.0);
|
||||
return(c->t);
|
||||
}
|
||||
|
||||
static double
|
||||
tbl_H_at_z(cosmology *c, double z)
|
||||
{
|
||||
tbl_background_at_z(c, z);
|
||||
return(c->H);
|
||||
}
|
||||
|
||||
static double
|
||||
tbl_H_at_t(cosmology *c, double t)
|
||||
{
|
||||
tbl_background_at_t(c, t);
|
||||
return(c->H);
|
||||
}
|
||||
|
||||
static double
|
||||
tbl_conformal_distance_at_z(cosmology *c, double z)
|
||||
{
|
||||
tbl_background_at_z(c, z);
|
||||
return(c->conf_distance);
|
||||
}
|
||||
|
||||
static double
|
||||
tbl_conformal_distance_at_t(cosmology *c, double t)
|
||||
{
|
||||
tbl_background_at_t(c, t);
|
||||
return(c->conf_distance);
|
||||
}
|
||||
|
||||
static double
|
||||
tbl_angular_diameter_distance_at_z(cosmology *c, double z)
|
||||
{
|
||||
tbl_background_at_z(c, z);
|
||||
return(c->conf_distance/(1.0+z));
|
||||
}
|
||||
|
||||
static double
|
||||
tbl_angular_diameter_distance_at_t(cosmology *c, double t)
|
||||
{
|
||||
tbl_background_at_t(c, t);
|
||||
return(c->conf_distance/(1.0+c->z));
|
||||
}
|
||||
|
||||
static double
|
||||
tbl_luminosity_distance_at_z(cosmology *c, double z)
|
||||
{
|
||||
tbl_background_at_z(c, z);
|
||||
return(c->conf_distance*(1.0+z));
|
||||
}
|
||||
|
||||
static double
|
||||
tbl_luminosity_distance_at_t(cosmology *c, double t)
|
||||
{
|
||||
tbl_background_at_t(c, t);
|
||||
return(c->conf_distance*(1.0+c->z));
|
||||
}
|
||||
|
||||
static double
|
||||
tbl_growthfac_at_z(cosmology *c, double z)
|
||||
{
|
||||
tbl_background_at_z(c, z);
|
||||
return(c->growthfac);
|
||||
}
|
||||
|
||||
static double
|
||||
tbl_growthfac_at_t(cosmology *c, double t)
|
||||
{
|
||||
tbl_background_at_t(c, t);
|
||||
return(c->growthfac);
|
||||
}
|
||||
|
||||
static double
|
||||
tbl_velfac_at_z(cosmology *c, double z)
|
||||
{
|
||||
tbl_background_at_z(c, z);
|
||||
return(c->velfac);
|
||||
}
|
||||
|
||||
static double
|
||||
tbl_velfac_at_t(cosmology *c, double t)
|
||||
{
|
||||
tbl_background_at_t(c, t);
|
||||
return(c->velfac);
|
||||
}
|
||||
|
||||
static double
|
||||
tbl_kick_t0_t1(cosmology *c, double t0, double t1)
|
||||
{
|
||||
double k0, k1;
|
||||
tbl_background_at_t(c, t0);
|
||||
k0 = c->kick;
|
||||
tbl_background_at_t(c, t1);
|
||||
k1 = c->kick;
|
||||
return(k1-k0);
|
||||
}
|
||||
|
||||
static double
|
||||
tbl_drift_t0_t1(cosmology *c, double t0, double t1)
|
||||
{
|
||||
double d0, d1;
|
||||
tbl_background_at_t(c, t0);
|
||||
d0 = c->drift;
|
||||
tbl_background_at_t(c, t1);
|
||||
d1 = c->drift;
|
||||
return(d1-d0);
|
||||
}
|
||||
|
||||
static void
|
||||
tbl_free(cosmology *c)
|
||||
{
|
||||
struct tbl_s *p = c->private;
|
||||
|
||||
Free(p->d2tau_dz2_tbl);
|
||||
Free(p->d2tau_dt2_tbl);
|
||||
Free(p->d2b_dtau2_tbl );
|
||||
Free(p->tbl);
|
||||
Free(p->t_tbl);
|
||||
Free(p->z_tbl);
|
||||
Free(p->tau_tbl);
|
||||
Free(p);
|
||||
c->private = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
tbl_init(cosmology *c, char *tbl)
|
||||
{
|
||||
char line[1024];
|
||||
FILE *fp;
|
||||
int i;
|
||||
double tau, z, t, H, R, drift, growth, growth_cdm, velfac;
|
||||
struct tbl_s *p = Malloc(sizeof(struct tbl_s));
|
||||
p->bt_size = 8192;
|
||||
p->bg_size = 8;
|
||||
|
||||
p->tau_tbl = Malloc(p->bt_size*sizeof(double));
|
||||
p->z_tbl = Malloc(p->bt_size*sizeof(double));
|
||||
p->t_tbl = Malloc(p->bt_size*sizeof(double));
|
||||
p->tbl = Malloc(p->bg_size*p->bt_size*sizeof(double));
|
||||
Fopen(fp, tbl, "r");
|
||||
i = 0;
|
||||
while (fgets(line, sizeof(line), fp)) {
|
||||
if (line[0] == '#') continue;
|
||||
if (sscanf(line, "%lg %lg %lg %lg %lg %lg %lg %lg %lg\n",
|
||||
&tau, &z, &t, &H, &R, &drift, &growth, &growth_cdm, &velfac) != 9)
|
||||
Error("Did not parse %s", line);
|
||||
p->tau_tbl[i] = tau;
|
||||
p->z_tbl[i] = z;
|
||||
p->t_tbl[i] = t;
|
||||
p->tbl[i*p->bg_size+0] = z;
|
||||
p->tbl[i*p->bg_size+1] = t;
|
||||
p->tbl[i*p->bg_size+2] = H;
|
||||
p->tbl[i*p->bg_size+3] = R;
|
||||
p->tbl[i*p->bg_size+4] = drift;
|
||||
p->tbl[i*p->bg_size+5] = growth;
|
||||
p->tbl[i*p->bg_size+6] = growth_cdm;
|
||||
p->tbl[i*p->bg_size+7] = velfac;
|
||||
i++;
|
||||
if (i >= p->bt_size) {
|
||||
p->bt_size *= 2;
|
||||
p->tau_tbl = Realloc(p->tau_tbl, p->bt_size*sizeof(double));
|
||||
p->z_tbl = Realloc(p->z_tbl, p->bt_size*sizeof(double));
|
||||
p->t_tbl = Realloc(p->t_tbl, p->bt_size*sizeof(double));
|
||||
p->tbl = Realloc(p->tbl, p->bg_size*p->bt_size*sizeof(double));
|
||||
}
|
||||
}
|
||||
Fclose(fp);
|
||||
p->bt_size = i;
|
||||
p->tau_tbl = Realloc(p->tau_tbl, p->bt_size*sizeof(double));
|
||||
p->z_tbl = Realloc(p->z_tbl, p->bt_size*sizeof(double));
|
||||
p->t_tbl = Realloc(p->t_tbl, p->bt_size*sizeof(double));
|
||||
p->tbl = Realloc(p->tbl, p->bg_size*p->bt_size*sizeof(double));
|
||||
|
||||
p->d2tau_dz2_tbl = Malloc(p->bt_size*sizeof(double));
|
||||
p->d2tau_dt2_tbl = Malloc(p->bt_size*sizeof(double));
|
||||
p->d2b_dtau2_tbl = Malloc(p->bg_size*p->bt_size*sizeof(double));
|
||||
|
||||
array_spline_table_lines(p->z_tbl,
|
||||
p->bt_size,
|
||||
p->tau_tbl,
|
||||
1,
|
||||
p->d2tau_dz2_tbl,
|
||||
_SPLINE_EST_DERIV_,
|
||||
p->error_message);
|
||||
array_spline_table_lines(p->t_tbl,
|
||||
p->bt_size,
|
||||
p->tau_tbl,
|
||||
1,
|
||||
p->d2tau_dt2_tbl,
|
||||
_SPLINE_EST_DERIV_,
|
||||
p->error_message);
|
||||
array_spline_table_lines(p->tau_tbl,
|
||||
p->bt_size,
|
||||
p->tbl,
|
||||
p->bg_size,
|
||||
p->d2b_dtau2_tbl,
|
||||
_SPLINE_EST_DERIV_,
|
||||
p->error_message);
|
||||
|
||||
c->private = p;
|
||||
|
||||
/* Function pointers */
|
||||
c->background_at_z = tbl_background_at_z;
|
||||
c->background_at_t = tbl_background_at_t;
|
||||
c->background_at_tau = tbl_background_at_tau;
|
||||
c->t_at_z = tbl_t_at_z;
|
||||
c->z_at_t = tbl_z_at_t;
|
||||
c->a_at_t = tbl_a_at_t;
|
||||
c->t_at_a = tbl_t_at_a;
|
||||
c->H_at_z = tbl_H_at_z;
|
||||
c->H_at_t = tbl_H_at_t;
|
||||
c->conformal_distance_at_z = tbl_conformal_distance_at_z;
|
||||
c->conformal_distance_at_t = tbl_conformal_distance_at_t;
|
||||
c->angular_diameter_distance_at_z = tbl_angular_diameter_distance_at_z;
|
||||
c->angular_diameter_distance_at_t = tbl_angular_diameter_distance_at_t;
|
||||
c->luminosity_distance_at_z = tbl_luminosity_distance_at_z;
|
||||
c->luminosity_distance_at_t = tbl_luminosity_distance_at_t;
|
||||
c->growthfac_at_z = tbl_growthfac_at_z;
|
||||
c->growthfac_at_t = tbl_growthfac_at_t;
|
||||
c->velfac_at_z = tbl_velfac_at_z;
|
||||
c->velfac_at_t = tbl_velfac_at_t;
|
||||
c->kick_t0_t1 = tbl_kick_t0_t1;
|
||||
c->drift_t0_t1 = tbl_drift_t0_t1;
|
||||
c->free = tbl_free;
|
||||
}
|
123
external/libsdf/libsw/counters.c
vendored
Normal file
123
external/libsdf/libsw/counters.c
vendored
Normal file
|
@ -0,0 +1,123 @@
|
|||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include "Malloc.h"
|
||||
#include "timers.h"
|
||||
#include "mpmy.h"
|
||||
#include "Assert.h"
|
||||
|
||||
#define MAXENABLED 100
|
||||
|
||||
static Counter_t *enabled_counters[MAXENABLED];
|
||||
static int nenabled_counters;
|
||||
|
||||
void ClearCounter(Counter_t *c){
|
||||
c->counter = 0;
|
||||
}
|
||||
|
||||
void ClearEnabledCounters(void){
|
||||
int i;
|
||||
for(i=0; i<nenabled_counters; i++){
|
||||
ClearCounter(enabled_counters[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void EnableCounter(Counter_t *c, char *name){
|
||||
assert(nenabled_counters < MAXENABLED);
|
||||
enabled_counters[nenabled_counters++] = c;
|
||||
c->name = Malloc(strlen(name)+1);
|
||||
strcpy(c->name, name);
|
||||
c->enabled = 1;
|
||||
c->counter = 0;
|
||||
}
|
||||
|
||||
void DisableCounter(Counter_t *t){
|
||||
int i;
|
||||
|
||||
for(i=0; i<nenabled_counters; i++){
|
||||
if( enabled_counters[i] == t )
|
||||
break;
|
||||
}
|
||||
assert(i < nenabled_counters);
|
||||
t->enabled = 0;
|
||||
Free(t->name);
|
||||
t->name = NULL;
|
||||
enabled_counters[i] = enabled_counters[--nenabled_counters];
|
||||
}
|
||||
|
||||
void SumCounters(void){
|
||||
double nprocinv;
|
||||
Counter_t *c;
|
||||
int i;
|
||||
MPMY_Comm_request req;
|
||||
|
||||
MPMY_ICombine_Init(&req);
|
||||
for(i=0; i<nenabled_counters; i++){
|
||||
c = enabled_counters[i];
|
||||
c->sum = c->min = c->max = c->counter;
|
||||
MPMY_ICombine(&c->min, &c->min, 1, MPMY_INT64, MPMY_MIN, req);
|
||||
MPMY_ICombine(&c->max, &c->max, 1, MPMY_INT64, MPMY_MAX, req);
|
||||
MPMY_ICombine(&c->sum, &c->sum, 1, MPMY_DOUBLE, MPMY_SUM, req);
|
||||
}
|
||||
MPMY_ICombine_Wait(req);
|
||||
|
||||
/* Now loop a second time and divide the mean by Nproc */
|
||||
nprocinv = 1./MPMY_Nproc();
|
||||
for(i=0; i<nenabled_counters; i++){
|
||||
c = enabled_counters[i];
|
||||
c->mean = c->sum * nprocinv;
|
||||
}
|
||||
}
|
||||
|
||||
void OutputCounters(int (*Printf_Like)(const char *, ...)){
|
||||
int i;
|
||||
Counter_t *c;
|
||||
|
||||
SumCounters();
|
||||
Printf_Like("%12s %12s %12s %15s %14s\n",
|
||||
"Counters", "Min", "Max", "Sum", "Avg");
|
||||
for (i = 0; i < nenabled_counters; i++) {
|
||||
c = enabled_counters[i];
|
||||
if( c->enabled && c->name )
|
||||
Printf_Like("%12s %12ld %12ld %15.0f %14.2f\n", c->name,
|
||||
c->min, c->max, c->sum, c->mean);
|
||||
}
|
||||
}
|
||||
|
||||
void OutputIndividualCounters(int (*Printf_Like)(const char *, ...)){
|
||||
int i;
|
||||
Counter_t *c;
|
||||
|
||||
Printf_Like("%12s %12s\n", "Counters", "Count");
|
||||
for (i = 0; i < nenabled_counters; i++) {
|
||||
c = enabled_counters[i];
|
||||
if( c->enabled && c->name )
|
||||
Printf_Like("%12s %12ld\n", c->name, c->counter);
|
||||
}
|
||||
}
|
||||
|
||||
int64_t ReadCounter(Counter_t *c){
|
||||
return c->counter;
|
||||
}
|
||||
|
||||
int64_t ReadCounter64(Counter_t *c){
|
||||
return c->counter;
|
||||
}
|
||||
|
||||
static void SumOneCounter(Counter_t *c){
|
||||
MPMY_Comm_request req;
|
||||
MPMY_ICombine_Init(&req);
|
||||
c->sum = c->min = c->max = c->counter;
|
||||
MPMY_ICombine(&c->min, &c->min, 1, MPMY_INT64, MPMY_MIN, req);
|
||||
MPMY_ICombine(&c->max, &c->max, 1, MPMY_INT64, MPMY_MAX, req);
|
||||
MPMY_ICombine(&c->sum, &c->sum, 1, MPMY_DOUBLE, MPMY_SUM, req);
|
||||
MPMY_ICombine_Wait(req);
|
||||
c->mean = c->sum / MPMY_Nproc();
|
||||
}
|
||||
|
||||
void OutputOneCounter(Counter_t *c, int (*Printf_Like)(const char *, ...)){
|
||||
SumOneCounter(c);
|
||||
Printf_Like("%12s %12ld %12ld %14.0g %14.2g\n",
|
||||
(c->name)?c->name:"(noname)",
|
||||
c->min, c->max, c->sum, c->mean);
|
||||
}
|
36
external/libsdf/libsw/dbg.c
vendored
Normal file
36
external/libsdf/libsw/dbg.c
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
#include <nx.h>
|
||||
|
||||
#define FORCE(t) ( (t) | (1<<30))
|
||||
#define DBG_REQUEST_TYPE FORCE(0x1a2b3c4)
|
||||
|
||||
#define WHAT_DBGBUF 1
|
||||
#define WHAT_MEMORY 2
|
||||
#define WHAT_STACK 3
|
||||
#define WHAT_CODE 4
|
||||
|
||||
typedef struct {
|
||||
int what;
|
||||
} dbg_request_t;
|
||||
|
||||
void PrintMemfile();
|
||||
static dbg_request_t dbg_request;
|
||||
|
||||
void
|
||||
jab_dbg_handler(int proc)
|
||||
{
|
||||
csend(DBG_REQUEST_TYPE, (char *)&dbg_request, sizeof(dbg_request), proc,0);
|
||||
{
|
||||
|
||||
void
|
||||
set_dbg_handler(void){
|
||||
hrecv(DBG_REQUEST_TYPE, (char *)&dbg_request,
|
||||
sizeof(dbg_request), dbg_handler);
|
||||
}
|
||||
|
||||
static void
|
||||
dbg_handler(long type, long count, long node, long pid)
|
||||
{
|
||||
PrintMemfile();
|
||||
set_dbg_handler();
|
||||
return;
|
||||
}
|
237
external/libsdf/libsw/dll.c
vendored
Normal file
237
external/libsdf/libsw/dll.c
vendored
Normal file
|
@ -0,0 +1,237 @@
|
|||
/* DLL: doubly linked lists.
|
||||
|
||||
Support:
|
||||
insertion either before or after a given element (Above, Below).
|
||||
deletion.
|
||||
traversal in either direction. (Up, Down)
|
||||
|
||||
Use a vertical metaphor for mnemonics. You can grow the data
|
||||
structure up, down, or outward from the middle. It makes
|
||||
absolutely no difference.
|
||||
|
||||
The implementation uses two 'sentinels'. The one above the topmost
|
||||
element is called 'Sup' and the one below the lowest element is
|
||||
called 'Inf'. These are good places to start and end 'for' loops, e.g.,
|
||||
|
||||
for(p=DllTop(dll); p!=DllInf(dll); p = DllDown(dll, p))...
|
||||
|
||||
or
|
||||
|
||||
for(p=DllBottom(dll); p!=DllSup(dll); p = DllUp(dll, p))...
|
||||
|
||||
Space for 'user' data of size 'sz' is allocated with each element.
|
||||
This is ideal if you want to allocate associate a fixed size object
|
||||
with each list element. If you want more flexibility, there's
|
||||
nothing stopping you from making that fixed size object a void*
|
||||
that points to something else.
|
||||
|
||||
*/
|
||||
|
||||
#include "chn.h"
|
||||
#include "dll.h"
|
||||
#include "Malloc.h"
|
||||
|
||||
/* Initializing is a two step process because we have to do some
|
||||
funny stuff to get a chain allocating chunks just slightly bigger than
|
||||
what the user asks for. The resulting chain can be ChnTerminated
|
||||
at the caller's leisure. */
|
||||
void DllCreateChn(Chn *chn, int sz, int n){
|
||||
n+=2;
|
||||
if( sz > sizeof(int) )
|
||||
sz -= sizeof(int);
|
||||
ChnInit(chn, sizeof(Dll_elmt)+sz, n, Realloc_f);
|
||||
}
|
||||
|
||||
void DllCreate(Dll *dll, Chn *chn){
|
||||
dll->chn = chn;
|
||||
dll->Sup.down = &dll->Inf;
|
||||
dll->Sup.up = NULL;
|
||||
dll->Inf.down = NULL;
|
||||
dll->Inf.up = &dll->Sup;
|
||||
dll->length = 0;
|
||||
}
|
||||
|
||||
/* Terminate a dll */
|
||||
void DllTerminate(Dll *dll){
|
||||
/* Hmmm. There's really nothing to do since the user is now
|
||||
empowered to free the chain. We can't even do a FreeAll because
|
||||
there might be other stuff (other DLL's?) using the chain. */
|
||||
}
|
||||
|
||||
/* Insert closer to the Top */
|
||||
Dll_elmt *DllInsertAbove(Dll *dll, Dll_elmt *down){
|
||||
Dll_elmt *new = ChnAlloc(dll->chn);
|
||||
Dll_elmt *up = down->up;
|
||||
|
||||
if( new == NULL ){
|
||||
Shout("ChnAlloc returns null in DllInsertAbove\n");
|
||||
return NULL;
|
||||
}
|
||||
dll->length++;
|
||||
new->up = up;
|
||||
new->down = down;
|
||||
down->up = new;
|
||||
up->down = new;
|
||||
return new;
|
||||
}
|
||||
|
||||
/* Insert closer to the bottom */
|
||||
Dll_elmt *DllInsertBelow(Dll *dll, Dll_elmt *up){
|
||||
Dll_elmt *new = ChnAlloc(dll->chn);
|
||||
Dll_elmt *down = up->down;
|
||||
|
||||
if( new == NULL ){
|
||||
Shout("ChnAlloc returns null in DllInsertBelow\n");
|
||||
return NULL;
|
||||
}
|
||||
dll->length++;
|
||||
new->up = up;
|
||||
new->down = down;
|
||||
down->up = new;
|
||||
up->down = new;
|
||||
return new;
|
||||
}
|
||||
|
||||
/* These two should be inlined, with __inline__ ... */
|
||||
/* Insert at the bottom */
|
||||
Dll_elmt *DllInsertAtBottom(Dll *dll){
|
||||
return DllInsertAbove(dll, &(dll->Inf));
|
||||
}
|
||||
|
||||
/* Insert at the top */
|
||||
Dll_elmt *DllInsertAtTop(Dll *dll){
|
||||
return DllInsertBelow(dll, &(dll->Sup));
|
||||
}
|
||||
|
||||
/* These three are VERY similar, but they are useful for traversals iin
|
||||
different directions. Otherwise the caller needs to save the 'up' or
|
||||
'down' element */
|
||||
/* Delete an entry. Return nothing. */
|
||||
void DllDelete(Dll *dll, Dll_elmt *old){
|
||||
Dll_elmt *up = old->up;
|
||||
Dll_elmt *down = old->down;
|
||||
|
||||
dll->length--;
|
||||
up->down = down;
|
||||
down->up = up;
|
||||
ChnFree(dll->chn, old);
|
||||
}
|
||||
|
||||
/* Delete an entry. Return the entry that used to be above it. */
|
||||
Dll_elmt *DllDeleteUp(Dll *dll, Dll_elmt *old){
|
||||
Dll_elmt *up = old->up;
|
||||
Dll_elmt *down = old->down;
|
||||
|
||||
dll->length--;
|
||||
up->down = down;
|
||||
down->up = up;
|
||||
ChnFree(dll->chn, old);
|
||||
return up;
|
||||
}
|
||||
|
||||
/* Delete an entry. Return the entry that used to be below it. */
|
||||
Dll_elmt *DllDeleteDown(Dll *dll, Dll_elmt *old){
|
||||
Dll_elmt *up = old->up;
|
||||
Dll_elmt *down = old->down;
|
||||
|
||||
dll->length--;
|
||||
up->down = down;
|
||||
down->up = up;
|
||||
ChnFree(dll->chn, old);
|
||||
return down;
|
||||
}
|
||||
|
||||
/* The next two have two plausible returns: the item directly above or
|
||||
below the original position of the mover. Rather than confuse
|
||||
things, I won't return either, and leave it up to the caller to keep
|
||||
track of whatever he wants. */
|
||||
|
||||
/* Extract the 'mover' and place it immediately below 'up'.
|
||||
Like DllDelete, followed by DllInsertBelow, but preserve the
|
||||
data in the object. */
|
||||
void DllMoveBelow(Dll *dll, Dll_elmt *mover, Dll_elmt *up){
|
||||
Dll_elmt *down;
|
||||
/* Extract the mover */
|
||||
mover->down->up = mover->up;
|
||||
mover->up->down = mover->down;
|
||||
/* Now insert it below up */
|
||||
down = up->down;
|
||||
mover->up = up;
|
||||
mover->down = down;
|
||||
down->up = mover;
|
||||
up->down = mover;
|
||||
}
|
||||
|
||||
/* Extract the 'mover' and place it immediately above 'down'.
|
||||
Like DllDelete, followed by DllInsertAbove, but preserve the
|
||||
data in the object. */
|
||||
void DllMoveAbove(Dll *dll, Dll_elmt *mover, Dll_elmt *down){
|
||||
Dll_elmt *up;
|
||||
/* Extract the mover */
|
||||
mover->down->up = mover->up;
|
||||
mover->up->down = mover->down;
|
||||
/* Now insert it above down */
|
||||
up = down->up;
|
||||
mover->up = up;
|
||||
mover->down = down;
|
||||
down->up = mover;
|
||||
up->down = mover;
|
||||
}
|
||||
|
||||
/* These should be inlined... */
|
||||
/* Move to bottom */
|
||||
void DllMoveToBottom(Dll *dll, Dll_elmt *mover){
|
||||
DllMoveAbove(dll, mover, &(dll->Inf));
|
||||
}
|
||||
|
||||
/* Move to top */
|
||||
void DllMoveToTop(Dll *dll, Dll_elmt *mover){
|
||||
DllMoveBelow(dll, mover, &(dll->Sup));
|
||||
}
|
||||
|
||||
/* These are generally 'inlined' with appropriate #defines in dll.h.
|
||||
They're simple enough to allow use of the pre-processor instead of
|
||||
__inline__. */
|
||||
#undef DllLength
|
||||
int DllLength(Dll *dll){
|
||||
return dll->length;
|
||||
}
|
||||
|
||||
#undef DllSup
|
||||
Dll_elmt *DllSup(Dll *dll){
|
||||
return &dll->Sup;
|
||||
}
|
||||
|
||||
#undef DllInf
|
||||
Dll_elmt *DllInf(Dll *dll){
|
||||
return &dll->Inf;
|
||||
}
|
||||
|
||||
/* The highest 'real' element */
|
||||
#undef DllTop
|
||||
Dll_elmt *DllTop(Dll *dll){
|
||||
return dll->Sup.down;
|
||||
}
|
||||
|
||||
/* The lowest 'real' element */
|
||||
#undef DllBottom
|
||||
Dll_elmt *DllBottom(Dll *dll){
|
||||
return dll->Inf.up;
|
||||
}
|
||||
|
||||
#undef DllData
|
||||
void *DllData(Dll_elmt *elmt){
|
||||
return &elmt->stuff;
|
||||
}
|
||||
|
||||
#undef DllUp
|
||||
Dll_elmt *DllUp(Dll_elmt *elmt){
|
||||
return elmt->up;
|
||||
}
|
||||
|
||||
#undef DllDown
|
||||
Dll_elmt *DllDown(Dll_elmt *elmt){
|
||||
return elmt->down;
|
||||
}
|
||||
|
||||
|
211
external/libsdf/libsw/dofZ.c
vendored
Normal file
211
external/libsdf/libsw/dofZ.c
vendored
Normal file
|
@ -0,0 +1,211 @@
|
|||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include "qromo.h"
|
||||
#include "dofz.h"
|
||||
|
||||
static double Omega0;
|
||||
static double Omega_m;
|
||||
static double Omega_r;
|
||||
static double Omega_de;
|
||||
static double w0;
|
||||
static double wa;
|
||||
static double Lambda_prime;
|
||||
static double H0;
|
||||
|
||||
static double
|
||||
adot(double a)
|
||||
{
|
||||
return H0*sqrt(Omega_m/a + Omega_r/(a*a) + Lambda_prime*a*a + (1.0 - Omega0 - Lambda_prime));
|
||||
}
|
||||
|
||||
static double
|
||||
addot(double a)
|
||||
{
|
||||
return H0 * H0 * (Lambda_prime*a-Omega_r/(a*a*a)-0.5*Omega_m/(a*a));
|
||||
}
|
||||
|
||||
static double
|
||||
integrand(double a)
|
||||
{
|
||||
double x;
|
||||
|
||||
x = adot(a);
|
||||
return 1.0/(x*x*x);
|
||||
|
||||
}
|
||||
|
||||
static double
|
||||
t_integrand(double a)
|
||||
{
|
||||
double x;
|
||||
|
||||
x = adot(a);
|
||||
return 1.0/x;
|
||||
}
|
||||
|
||||
static double
|
||||
dp_integrand(double a)
|
||||
{
|
||||
double x;
|
||||
|
||||
x = adot(a);
|
||||
return 1.0/(a*x);
|
||||
|
||||
}
|
||||
|
||||
double
|
||||
growthfac_from_Z(double omega0, double h0, double lambda_prime, double z)
|
||||
{
|
||||
double z0gf;
|
||||
double a = 1.0/(1.0+z);
|
||||
double h = 10.0*h0*(one_kpc/one_Gyr);
|
||||
Omega0 = omega0;
|
||||
Omega_r = omega_r / (h * h);
|
||||
Omega_m = omega0-Omega_r;
|
||||
H0 = h0;
|
||||
Lambda_prime = lambda_prime;
|
||||
return 2.5*H0*H0*adot(a)*qromod(integrand, 0.0, a, midpntd)/a;
|
||||
}
|
||||
|
||||
double
|
||||
velfac_from_Z(double omega0, double h0, double lambda_prime, double z)
|
||||
{
|
||||
double d, a_dot;
|
||||
double a = 1.0/(1.0+z);
|
||||
double h = 10.0*h0*(one_kpc/one_Gyr);
|
||||
Omega0 = omega0;
|
||||
Omega_r = omega_r / (h * h);
|
||||
Omega_m = omega0-Omega_r;
|
||||
H0 = h0;
|
||||
Lambda_prime = lambda_prime;
|
||||
d = qromod(integrand, 0.0, a, midpntd);
|
||||
a_dot = adot(a);
|
||||
return addot(a)
|
||||
*a/(a_dot*a_dot) - 1.0 + a/(a_dot*a_dot*a_dot*d);
|
||||
}
|
||||
|
||||
double
|
||||
t_from_Z(double omega0, double h0, double lambda_prime, double z)
|
||||
{
|
||||
double d;
|
||||
double a = 1.0/(1.0+z);
|
||||
double h = 10.0*h0*(one_kpc/one_Gyr);
|
||||
Omega0 = omega0;
|
||||
Omega_r = omega_r / (h * h);
|
||||
Omega_m = omega0-Omega_r;
|
||||
H0 = h0;
|
||||
Lambda_prime = lambda_prime;
|
||||
d = qromod(t_integrand, 0.0, a, midpntd);
|
||||
return (d);
|
||||
}
|
||||
|
||||
double
|
||||
dp_from_Z(double omega0, double h0, double lambda_prime, double z)
|
||||
{
|
||||
double d;
|
||||
double a = 1.0/(1.0+z);
|
||||
double h = 10.0*h0*(one_kpc/one_Gyr);
|
||||
if (a == 1.0) return 0.0;
|
||||
Omega0 = omega0;
|
||||
Omega_r = omega_r / (h * h);
|
||||
Omega_m = omega0-Omega_r;
|
||||
H0 = h0;
|
||||
Lambda_prime = lambda_prime;
|
||||
d = qromod(dp_integrand, a, 1.0, midpntd);
|
||||
return (d);
|
||||
}
|
||||
|
||||
double
|
||||
hubble_from_Z(double omega0, double h0, double lambda_prime, double z)
|
||||
{
|
||||
double a = 1.0/(1.0+z);
|
||||
double h = 10.0*h0*(one_kpc/one_Gyr);
|
||||
Omega0 = omega0;
|
||||
Omega_r = omega_r / (h * h);
|
||||
Omega_m = omega0-Omega_r;
|
||||
H0 = h0;
|
||||
Lambda_prime = lambda_prime;
|
||||
return adot(a)/a;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Crays don't have acosh */
|
||||
static double Acosh(double x)
|
||||
{
|
||||
return log(x + sqrt(x*x-1.0));
|
||||
}
|
||||
|
||||
static double
|
||||
growthfac_from_Z(double Omega0, double H0, double Z)
|
||||
{
|
||||
/* This is just the growing mode */
|
||||
/* See Weinberg 15.9.27--15.9.31 or Peebles LSS 11.16 */
|
||||
double d, d0;
|
||||
|
||||
if (Omega0 == 1.0) {
|
||||
d = 1.0/(1.0+Z);
|
||||
d0 = 1.0;
|
||||
} else if(Omega0 < 1.0) {
|
||||
/* Using doubles can cause roundoff problems near Omega0=1 */
|
||||
double psi, coshpsi;
|
||||
coshpsi = 1.0 + 2.0*(1.0 - Omega0)/(Omega0*(1.0+Z));
|
||||
psi = Acosh(coshpsi);
|
||||
d = - 3.0 * psi * sinh(psi)/((coshpsi-1.0)*(coshpsi-1.0))
|
||||
+ (5.0+coshpsi)/(coshpsi-1.0);
|
||||
coshpsi = 1.0 + 2.0*(1.0 - Omega0)/Omega0;
|
||||
psi = Acosh(coshpsi);
|
||||
d0 = - 3.0 * psi * sinh(psi)/((coshpsi-1.0)*(coshpsi-1.0))
|
||||
+ (5.0+coshpsi)/(coshpsi-1.0);
|
||||
} else {
|
||||
double theta, costheta;
|
||||
costheta = 1.0 - 2.0*(Omega0-1.0)/(Omega0*(1.0+Z));
|
||||
theta = acos(costheta);
|
||||
d = - 3.0 * theta * sin(theta)/((1.0-costheta)*(1.0-costheta))
|
||||
+ (5.0+costheta)/(1.0-costheta);
|
||||
costheta = 1.0 - 2.0*(Omega0-1.0)/Omega0;
|
||||
theta = acos(costheta);
|
||||
d0 = - 3.0 * theta * sin(theta)/((1.0-costheta)*(1.0-costheta))
|
||||
+ (5.0+costheta)/(1.0-costheta);
|
||||
}
|
||||
return d/d0;
|
||||
}
|
||||
|
||||
static double
|
||||
t_from_Z(double Omega0, double H0, double Z)
|
||||
{
|
||||
double t, theta, psi;
|
||||
|
||||
if(Omega0 == 1.0){
|
||||
t = (2.0/3.0) * pow(1.0+Z, -1.5);
|
||||
}else if(Omega0 < 1.0){
|
||||
psi = Acosh( 1.0 + 2.0*(1.0 - Omega0)/(Omega0*(1.0+Z)) );
|
||||
t = (Omega0/2.0)*pow(1.0-Omega0, -1.5)*(sinh(psi) - psi) ;
|
||||
}else{
|
||||
theta = acos( 1.0 - 2.0*(Omega0-1.)/(Omega0*(1.0+Z)) );
|
||||
t = (Omega0/2.0)*pow(Omega0-1.0, -1.5)*(theta-sin(theta));
|
||||
}
|
||||
t /= H0;
|
||||
return t;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef STANDALONE
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
double z;
|
||||
double omega0 = atof(argv[1]);
|
||||
double h0 = atof(argv[2]);
|
||||
double lp = atof(argv[3]);
|
||||
|
||||
for (z = 0; z <= 100; z++) {
|
||||
printf("%g %g %g %g %g\n", z, growthfac_from_Z(omega0, h0, lp, z),
|
||||
velfac_from_Z(omega0, h0, lp, z), t_from_Z(omega0, h0, lp, z),
|
||||
dp_from_Z(omega0, h0, lp, z));
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
#endif
|
201
external/libsdf/libsw/error.c
vendored
Normal file
201
external/libsdf/libsw/error.c
vendored
Normal file
|
@ -0,0 +1,201 @@
|
|||
/*
|
||||
* Copyright 1991 Michael S. Warren and John K. Salmon. All Rights Reserved.
|
||||
*/
|
||||
#ifdef __SRV__
|
||||
# error This file should not use SRV
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include "error.h"
|
||||
#include "Msgs.h"
|
||||
#include "mpmy.h"
|
||||
#include "mpmy_abnormal.h"
|
||||
#include "gccextensions.h"
|
||||
#include "protos.h"
|
||||
#include "memfile.h"
|
||||
|
||||
#undef Error
|
||||
#undef SinglError
|
||||
#undef Warning
|
||||
#undef SinglWarning
|
||||
#undef SeriousWarning
|
||||
#undef Shout
|
||||
#undef SinglShout
|
||||
|
||||
static int recursion;
|
||||
|
||||
/* We call this SWError because of a namespace conflict when linking SDF
|
||||
into perl5. error.h should do the switcheroo automatically... */
|
||||
void SWError(const char * mesg, ...)
|
||||
{
|
||||
va_list alist;
|
||||
|
||||
if( recursion++ )
|
||||
MPMY_SystemAbort(); /* errors within errors. A very bad sign */
|
||||
|
||||
va_start(alist, mesg);
|
||||
fprintf(stderr, "ERROR: Node %d (%s) ", MPMY_Procnum(), MPMY_Physnode());
|
||||
vfprintf(stderr, mesg, alist);
|
||||
fflush(stderr);
|
||||
va_end(alist);
|
||||
Msg_do("ERROR: ");
|
||||
va_start(alist, mesg);
|
||||
Msg_doalist(mesg, alist);
|
||||
va_end(alist);
|
||||
Msg_flush();
|
||||
MPMY_Abort();
|
||||
}
|
||||
|
||||
/* Is this right? Is it even possible? Can I pass the same va_list
|
||||
to two different subroutines? I can't use va_start and va_end because
|
||||
this isn't a varargs function! It works in Msgs, so it ought to work
|
||||
here too.*/
|
||||
void vError(const char * mesg, va_list alist)
|
||||
{
|
||||
if( recursion++ )
|
||||
MPMY_SystemAbort(); /* errors within errors. A very bad sign */
|
||||
|
||||
fprintf(stderr, "ERROR: Node %d (%s) ", MPMY_Procnum(), MPMY_Physnode());
|
||||
vfprintf(stderr, mesg, alist);
|
||||
fflush(stderr);
|
||||
|
||||
Msg_do("ERROR: ");
|
||||
Msg_doalist(mesg, alist);
|
||||
Msg_flush();
|
||||
PrintMemfile();
|
||||
MPMY_Abort();
|
||||
}
|
||||
|
||||
void SinglError(const char * mesg, ...)
|
||||
{
|
||||
va_list alist;
|
||||
|
||||
if( recursion++ )
|
||||
MPMY_SystemAbort();
|
||||
if( MPMY_Procnum() == 0 ){
|
||||
va_start(alist, mesg);
|
||||
fprintf(stderr, "Single ERROR: ");
|
||||
vfprintf(stderr, mesg, alist);
|
||||
fflush(stderr);
|
||||
va_end(alist);
|
||||
Msg_do("Single ERROR: ");
|
||||
va_start(alist, mesg);
|
||||
Msg_doalist(mesg, alist);
|
||||
va_end(alist);
|
||||
PrintMemfile();
|
||||
Msg_flush();
|
||||
}
|
||||
MPMY_Abort();
|
||||
}
|
||||
|
||||
void
|
||||
Warning(const char *mesg, ...)
|
||||
{
|
||||
va_list alist;
|
||||
|
||||
if( recursion++ ){
|
||||
--recursion;
|
||||
return;
|
||||
}
|
||||
Msg_do("WARNING: ");
|
||||
va_start(alist, mesg);
|
||||
Msg_doalist(mesg, alist);
|
||||
va_end(alist);
|
||||
Msg_flush();
|
||||
--recursion;
|
||||
}
|
||||
|
||||
void
|
||||
SinglWarning(const char *mesg, ...)
|
||||
{
|
||||
va_list alist;
|
||||
|
||||
if( recursion++ ){
|
||||
--recursion;
|
||||
return;
|
||||
}
|
||||
if( MPMY_Procnum() == 0 ){
|
||||
/* Since there's only one, it's safe to send it to stderr too... */
|
||||
va_start(alist, mesg);
|
||||
fprintf(stderr, "WARNING: (single): ");
|
||||
vfprintf(stderr, mesg, alist);
|
||||
fflush(stderr);
|
||||
va_end(alist);
|
||||
Msg_do("WARNING (Single mode): ");
|
||||
va_start(alist, mesg);
|
||||
Msg_doalist(mesg, alist);
|
||||
va_end(alist);
|
||||
Msg_flush();
|
||||
}
|
||||
--recursion;
|
||||
}
|
||||
|
||||
/* This one goes to stderr, for all to see immediately */
|
||||
void
|
||||
SeriousWarning(const char *mesg, ...)
|
||||
{
|
||||
va_list alist;
|
||||
|
||||
if( recursion++ ){
|
||||
--recursion;
|
||||
return;
|
||||
}
|
||||
va_start(alist, mesg);
|
||||
fprintf(stderr, "WARNING: Node %d ", MPMY_Procnum());
|
||||
vfprintf(stderr, mesg, alist);
|
||||
fflush(stderr);
|
||||
va_end(alist);
|
||||
Msg_do("WARNING: ");
|
||||
va_start(alist, mesg);
|
||||
Msg_doalist(mesg, alist);
|
||||
va_end(alist);
|
||||
Msg_flush();
|
||||
--recursion;
|
||||
}
|
||||
|
||||
/* No "WARNING", no line numbers, etc... Just the arguments */
|
||||
void
|
||||
Shout(const char *mesg, ...)
|
||||
{
|
||||
va_list alist;
|
||||
|
||||
if( recursion++ ){
|
||||
--recursion;
|
||||
return;
|
||||
}
|
||||
va_start(alist, mesg);
|
||||
vfprintf(stderr, mesg, alist);
|
||||
fflush(stderr);
|
||||
va_end(alist);
|
||||
va_start(alist, mesg);
|
||||
Msg_doalist(mesg, alist);
|
||||
va_end(alist);
|
||||
Msg_flush();
|
||||
--recursion;
|
||||
}
|
||||
|
||||
void
|
||||
SinglShout(const char *mesg, ...)
|
||||
{
|
||||
va_list alist;
|
||||
|
||||
if( recursion++ ){
|
||||
--recursion;
|
||||
return;
|
||||
}
|
||||
if( MPMY_Procnum() == 0 ){
|
||||
va_start(alist, mesg);
|
||||
vfprintf(stderr, mesg, alist);
|
||||
fflush(stderr);
|
||||
va_end(alist);
|
||||
va_start(alist, mesg);
|
||||
Msg_doalist(mesg, alist);
|
||||
va_end(alist);
|
||||
Msg_flush();
|
||||
}
|
||||
--recursion;
|
||||
}
|
||||
|
59
external/libsdf/libsw/files.c
vendored
Normal file
59
external/libsdf/libsw/files.c
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
/* Some common routines for dealing with files. */
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include "protos.h"
|
||||
#include "Malloc.h"
|
||||
#include "mpmy.h"
|
||||
|
||||
int fexists(const char *name){
|
||||
int fd, ret;
|
||||
|
||||
ret = 0;
|
||||
if( MPMY_Procnum() == 0 ){
|
||||
/* We could call stat, but then we'd have to deal with the */
|
||||
/* complications of different flavors of struct stat on different */
|
||||
/* machines...Yuck. */
|
||||
if( (fd=open(name, O_RDONLY)) >= 0 ){
|
||||
close(fd);
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
MPMY_Combine(&ret, &ret, 1, MPMY_INT, MPMY_SUM);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int fexists_and_unlink(const char *name){
|
||||
int fd, ret;
|
||||
|
||||
ret = 0;
|
||||
if( MPMY_Procnum() == 0 ){
|
||||
/* We could call stat, but then we'd have to deal with the */
|
||||
/* complications of different flavors of struct stat on different */
|
||||
/* machines...Yuck. */
|
||||
if( (fd=open(name, O_RDONLY)) >= 0 ){
|
||||
close(fd);
|
||||
ret = 1;
|
||||
}
|
||||
unlink(name);
|
||||
}
|
||||
MPMY_Combine(&ret, &ret, 1, MPMY_INT, MPMY_SUM);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
ForceCheckpoint(void)
|
||||
{
|
||||
return fexists_and_unlink("_ForceCheckpoint_") || fexists("_ForceStop_");
|
||||
}
|
||||
|
||||
int
|
||||
ForceOutput(void)
|
||||
{
|
||||
return fexists_and_unlink("_ForceOutput_");
|
||||
}
|
||||
|
||||
int
|
||||
ForceStop(void)
|
||||
{
|
||||
return fexists_and_unlink("_ForceStop_");
|
||||
}
|
11
external/libsdf/libsw/finite.c
vendored
Normal file
11
external/libsdf/libsw/finite.c
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
/* This really should be implemented for us... */
|
||||
/* Nevertheless, we should do better.. */
|
||||
#include <math.h>
|
||||
#ifndef HUGE
|
||||
#define HUGE 1.e38
|
||||
#endif
|
||||
|
||||
int finite(double x){
|
||||
return x<HUGE && x>-HUGE;
|
||||
}
|
||||
|
180
external/libsdf/libsw/gc.c
vendored
Normal file
180
external/libsdf/libsw/gc.c
vendored
Normal file
|
@ -0,0 +1,180 @@
|
|||
/* little functions for doing gray-code stuff. */
|
||||
|
||||
#include <limits.h>
|
||||
#include <sys/types.h>
|
||||
#include "gc.h"
|
||||
|
||||
/* Both parity and firstbit could be sped up with some lookup tables. */
|
||||
/* Who cares? */
|
||||
unsigned int parity(unsigned int num)
|
||||
{
|
||||
unsigned int answer = 0;
|
||||
while( num ){
|
||||
if( num&1 )
|
||||
answer ^= 1;
|
||||
num >>= 1;
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
int hibit(unsigned int num){
|
||||
/* return the index of the highest bit in num. */
|
||||
/* -1 if num == 0 */
|
||||
int bit = -1;
|
||||
|
||||
while(num) {
|
||||
bit++;
|
||||
num >>= 1;
|
||||
}
|
||||
return bit;
|
||||
}
|
||||
|
||||
int lobit(unsigned int num){
|
||||
/* Return the index of the lowest bit in num */
|
||||
/* Return BITS_PER_WORD in if num==0. This relies on overflow in left-
|
||||
shift returning 0 */
|
||||
unsigned int m=1;
|
||||
int bit = 0;
|
||||
|
||||
while((num&m) != m){
|
||||
m <<= 1;
|
||||
bit++;
|
||||
}
|
||||
return bit;
|
||||
}
|
||||
|
||||
int ilog2(unsigned int n){
|
||||
return hibit(n);
|
||||
}
|
||||
|
||||
unsigned int cksum(const void *buf, unsigned int n){
|
||||
unsigned int sum = 0;
|
||||
unsigned int leftover;
|
||||
const unsigned int *ip = buf;
|
||||
const unsigned char *cp;
|
||||
|
||||
/* Worthwhile to make the result independent of word-ordering, wordsize,
|
||||
etc?? Not now... */
|
||||
leftover = n%sizeof(unsigned int);
|
||||
n /= sizeof(unsigned int);
|
||||
while(n--){
|
||||
sum ^= *ip++;
|
||||
}
|
||||
cp = (const unsigned char *)ip;
|
||||
for(n=0; n<leftover; n++){
|
||||
sum ^= (*cp++) << (n*CHAR_BIT);
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
unsigned int countbits(unsigned int n){
|
||||
unsigned int ret = 0;
|
||||
do{
|
||||
if( n&1 ) ret++;
|
||||
}while((n >>= 1));
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* My two neighbors are obtained by :
|
||||
a) toggle the lowest bit of procnum
|
||||
b) toggle one past the lowest turned-on bit
|
||||
( but be careful when there are no turned on bits, or only the highest
|
||||
is turned on).
|
||||
*/
|
||||
int Gcup(unsigned int proc, unsigned int nproc){
|
||||
if( proc == nproc>>1 ){
|
||||
return -1;
|
||||
}else if( parity(proc) ){
|
||||
return proc^(1<<lobit(proc));
|
||||
}else{
|
||||
return proc^1;
|
||||
}
|
||||
}
|
||||
|
||||
int Gcdown(unsigned int proc, unsigned int nproc){
|
||||
if(proc == 0){
|
||||
return -1;
|
||||
}else if(parity(proc)){
|
||||
return proc^1;
|
||||
}else{
|
||||
return proc^(1<<lobit(proc));
|
||||
}
|
||||
}
|
||||
|
||||
void NobjInitial(int gnobj, int nproc, int procnum, int *nobj, int *start)
|
||||
{
|
||||
int leftover;
|
||||
|
||||
*nobj = gnobj / nproc;
|
||||
*start = (*nobj)*procnum;
|
||||
leftover = gnobj - (*nobj)*nproc;
|
||||
if (procnum < leftover){
|
||||
++(*nobj);
|
||||
*start += procnum;
|
||||
}else{
|
||||
*start += leftover;
|
||||
}
|
||||
}
|
||||
|
||||
void NobjInitial64(int64_t gnobj, int nproc, int procnum, int *nobj, int64_t *start)
|
||||
{
|
||||
int leftover;
|
||||
|
||||
*nobj = gnobj / nproc;
|
||||
*start = (int64_t)(*nobj)*procnum;
|
||||
leftover = gnobj - (*nobj)*nproc;
|
||||
if (procnum < leftover){
|
||||
++(*nobj);
|
||||
*start += procnum;
|
||||
}else{
|
||||
*start += leftover;
|
||||
}
|
||||
}
|
||||
|
||||
/* Both these routines came from alt.sources. */
|
||||
/* From: eillihca@drizzle.StanFord.EDU ( Achille Hui, the Day Dreamer ) */
|
||||
unsigned long
|
||||
bin2gray(unsigned long b){
|
||||
return b ^ (b>>1);
|
||||
}
|
||||
|
||||
/* If you look back at the property of ^ and >>, you will notice ^ behave
|
||||
like an addtion:
|
||||
|
||||
x + y = y + x <-> x ^ y = y ^ x
|
||||
(x + y) + z = x + (y + z) <-> (x ^ y) ^ z = x ^ (y ^ z)
|
||||
|
||||
and >> behave like a linear operator L:
|
||||
|
||||
L(x + y) = L(x) + L(y) <-> (x ^ y)>>1 = (x>>1) ^ (y>>1)
|
||||
|
||||
Hence the bin2gray operation behave just like the linear operator:
|
||||
|
||||
1 + L
|
||||
|
||||
with inverse
|
||||
-1 2 3 2 4 8
|
||||
(1+L) = 1 - L + L - L + ... = (1 - L)(1 + L )(1 + L )(1 + L )... (*)
|
||||
|
||||
Since x ^ y ^ y = x, addition is just the same as subaction. Furthurmore,
|
||||
x>>32 = 0 for any 32 bit integer and hence all of
|
||||
32 64
|
||||
(1 + L ) , (1 + L ), .... equal to 1.
|
||||
|
||||
As a result, your just need to keep the first 5 terms of RHS of (*)
|
||||
*/
|
||||
unsigned long
|
||||
gray2bin(unsigned long g){
|
||||
register unsigned long t = g;
|
||||
t ^= t>>1; /* 1 - L */
|
||||
/* 2 */
|
||||
t ^= t>>2; /* 1 + L */
|
||||
/* 4 */
|
||||
t ^= t>>4; /* 1 + L */
|
||||
/* 8 */
|
||||
t ^= t>>8; /* 1 + L */
|
||||
/* 16 */
|
||||
t ^= t>>16; /* 1 + L */
|
||||
return t;
|
||||
}
|
269
external/libsdf/libsw/gnusort.c
vendored
Normal file
269
external/libsdf/libsw/gnusort.c
vendored
Normal file
|
@ -0,0 +1,269 @@
|
|||
/* Use a static buffer instead of malloc for small 'size' */
|
||||
/* Fixed a bug when called with total_elems=0, ptr=NULL */
|
||||
/* The default is now to not use alloca unless ALLOCA_PREFERRED is defined */
|
||||
/* -DNO_ALLOCA and -DC_ALLOCA are equivalent. Neither uses alloca herein. */
|
||||
/* Changed alloca -> Malloc/Free (johns) */
|
||||
/* Hacked by msw for even more speed (2x - 3x) */
|
||||
/* Assumes size is a multiple of sizeof(int) */
|
||||
/* Originally from glibc-1.03.tar.Z stdlib/qsort.c */
|
||||
|
||||
/* Copyright (C) 1991 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Written by Douglas C. Schmidt (schmidt@ics.uci.edu).
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifndef ALLOCA_PREFERRED
|
||||
#include "Malloc.h"
|
||||
static char static_pivot[128];
|
||||
#endif
|
||||
#include "error.h"
|
||||
|
||||
/* Int-wise swap two items of size SIZE. */
|
||||
#define SWAP(a, b, size) \
|
||||
do \
|
||||
{ \
|
||||
register size_t __size = (size)/sizeof(int); \
|
||||
register int *__a = (int *)(a), *__b = (int *)(b); \
|
||||
do \
|
||||
{ \
|
||||
int __tmp = *__a; \
|
||||
*__a++ = *__b; \
|
||||
*__b++ = __tmp; \
|
||||
} while (--__size > 0); \
|
||||
} while (0)
|
||||
|
||||
/* Discontinue quicksort algorithm when partition gets below this size.
|
||||
This particular magic number was chosen to work best on a Sun 4/260. */
|
||||
#define MAX_THRESH 4
|
||||
|
||||
/* Stack node declarations used to store unfulfilled partition obligations. */
|
||||
typedef struct
|
||||
{
|
||||
char *lo;
|
||||
char *hi;
|
||||
} stack_node;
|
||||
|
||||
/* The next 4 #defines implement a very fast in-line stack abstraction. */
|
||||
#define STACK_SIZE (8 * sizeof(unsigned long int))
|
||||
#define PUSH(low, high) ((void) ((top->lo = (low)), (top->hi = (high)), ++top))
|
||||
#define POP(low, high) ((void) (--top, (low = top->lo), (high = top->hi)))
|
||||
#define STACK_NOT_EMPTY (stack < top)
|
||||
|
||||
|
||||
/* Order size using quicksort. This implementation incorporates
|
||||
four optimizations discussed in Sedgewick:
|
||||
|
||||
1. Non-recursive, using an explicit stack of pointer that store the
|
||||
next array partition to sort. To save time, this maximum amount
|
||||
of space required to store an array of MAX_INT is allocated on the
|
||||
stack. Assuming a 32-bit integer, this needs only 32 *
|
||||
sizeof(stack_node) == 136 bits. Pretty cheap, actually.
|
||||
|
||||
2. Chose the pivot element using a median-of-three decision tree.
|
||||
This reduces the probability of selecting a bad pivot value and
|
||||
eliminates certain extraneous comparisons.
|
||||
|
||||
3. Only quicksorts TOTAL_ELEMS / MAX_THRESH partitions, leaving
|
||||
insertion sort to order the MAX_THRESH items within each partition.
|
||||
This is a big win, since insertion sort is faster for small, mostly
|
||||
sorted array segements.
|
||||
|
||||
4. The larger of the two sub-partitions is always pushed onto the
|
||||
stack first, with the algorithm then concentrating on the
|
||||
smaller partition. This *guarantees* no more than log (n)
|
||||
stack size is needed (actually O(1) in this case)! */
|
||||
|
||||
/* STDC says it's void, but Sun knows better, but SRV knows better still... */
|
||||
#if defined(__SRV__) || defined(__SUN_CC_UNPROTO__) || defined(__SUN5__) || !defined(sparc)
|
||||
void
|
||||
#else
|
||||
int
|
||||
#endif
|
||||
qsort(void *pbase, size_t total_elems, size_t size,
|
||||
int (*cmp)(const void *, const void *))
|
||||
{
|
||||
register char *base_ptr = (char *) pbase;
|
||||
|
||||
/* Allocating SIZE bytes for a pivot buffer facilitates a better
|
||||
algorithm below since we can do comparisons directly on the pivot. */
|
||||
#ifdef ALLOCA_PREFERRED
|
||||
char *pivot_buffer = (char *) alloca (size);
|
||||
#else
|
||||
char *pivot_buffer = (size > sizeof(static_pivot)) ? (char *)Malloc(size) : static_pivot;
|
||||
#endif
|
||||
const size_t max_thresh = MAX_THRESH * size;
|
||||
|
||||
if (size % sizeof(int) || (int)pbase % sizeof(int))
|
||||
Error("This qsort only works on int aligned stuff\n");
|
||||
|
||||
if (total_elems > MAX_THRESH)
|
||||
{
|
||||
char *lo = base_ptr;
|
||||
char *hi = &lo[size * (total_elems - 1)];
|
||||
/* Largest size needed for 32-bit int!!! */
|
||||
stack_node stack[STACK_SIZE];
|
||||
stack_node *top = stack + 1;
|
||||
|
||||
while (STACK_NOT_EMPTY)
|
||||
{
|
||||
char *left_ptr;
|
||||
char *right_ptr;
|
||||
|
||||
char *pivot = pivot_buffer;
|
||||
|
||||
/* Select median value from among LO, MID, and HI. Rearrange
|
||||
LO and HI so the three values are sorted. This lowers the
|
||||
probability of picking a pathological pivot value and
|
||||
skips a comparison for both the LEFT_PTR and RIGHT_PTR. */
|
||||
|
||||
char *mid = lo + size * ((hi - lo) / size >> 1);
|
||||
|
||||
if ((*cmp)((void *) mid, (void *) lo) < 0)
|
||||
SWAP(mid, lo, size);
|
||||
if ((*cmp)((void *) hi, (void *) mid) < 0)
|
||||
SWAP(mid, hi, size);
|
||||
else
|
||||
goto jump_over;
|
||||
if ((*cmp)((void *) mid, (void *) lo) < 0)
|
||||
SWAP(mid, lo, size);
|
||||
jump_over:;
|
||||
memcpy(pivot, mid, size);
|
||||
pivot = pivot_buffer;
|
||||
|
||||
left_ptr = lo + size;
|
||||
right_ptr = hi - size;
|
||||
|
||||
/* Here's the famous ``collapse the walls'' section of quicksort.
|
||||
Gotta like those tight inner loops! They are the main reason
|
||||
that this algorithm runs much faster than others. */
|
||||
do
|
||||
{
|
||||
while ((*cmp)((void *) left_ptr, (void *) pivot) < 0)
|
||||
left_ptr += size;
|
||||
|
||||
while ((*cmp)((void *) pivot, (void *) right_ptr) < 0)
|
||||
right_ptr -= size;
|
||||
|
||||
if (left_ptr < right_ptr)
|
||||
{
|
||||
SWAP(left_ptr, right_ptr, size);
|
||||
left_ptr += size;
|
||||
right_ptr -= size;
|
||||
}
|
||||
else if (left_ptr == right_ptr)
|
||||
{
|
||||
left_ptr += size;
|
||||
right_ptr -= size;
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (left_ptr <= right_ptr);
|
||||
|
||||
/* Set up pointers for next iteration. First determine whether
|
||||
left and right partitions are below the threshold size. If so,
|
||||
ignore one or both. Otherwise, push the larger partition's
|
||||
bounds on the stack and continue sorting the smaller one. */
|
||||
|
||||
if ((size_t) (right_ptr - lo) <= max_thresh)
|
||||
{
|
||||
if ((size_t) (hi - left_ptr) <= max_thresh)
|
||||
/* Ignore both small partitions. */
|
||||
POP(lo, hi);
|
||||
else
|
||||
/* Ignore small left partition. */
|
||||
lo = left_ptr;
|
||||
}
|
||||
else if ((size_t) (hi - left_ptr) <= max_thresh)
|
||||
/* Ignore small right partition. */
|
||||
hi = right_ptr;
|
||||
else if ((right_ptr - lo) > (hi - left_ptr))
|
||||
{
|
||||
/* Push larger left partition indices. */
|
||||
PUSH(lo, right_ptr);
|
||||
lo = left_ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Push larger right partition indices. */
|
||||
PUSH(left_ptr, hi);
|
||||
hi = right_ptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Once the BASE_PTR array is partially sorted by quicksort the rest
|
||||
is completely sorted using insertion sort, since this is efficient
|
||||
for partitions below MAX_THRESH size. BASE_PTR points to the beginning
|
||||
of the array to sort, and END_PTR points at the very last element in
|
||||
the array (*not* one beyond it!). */
|
||||
|
||||
#define min(x, y) ((x) < (y) ? (x) : (y))
|
||||
|
||||
/* johns - avoid potential segfault if total_elems==0 and base_ptr == 0 !*/
|
||||
if( total_elems > 0 )
|
||||
{
|
||||
char *const end_ptr = &base_ptr[size * (total_elems - 1)];
|
||||
char *tmp_ptr = base_ptr;
|
||||
char *thresh = min(end_ptr, base_ptr + max_thresh);
|
||||
register char *run_ptr;
|
||||
|
||||
/* Find smallest element in first threshold and place it at the
|
||||
array's beginning. This is the smallest array element,
|
||||
and the operation speeds up insertion sort's inner loop. */
|
||||
|
||||
for (run_ptr = tmp_ptr + size; run_ptr <= thresh; run_ptr += size)
|
||||
if ((*cmp)((void *) run_ptr, (void *) tmp_ptr) < 0)
|
||||
tmp_ptr = run_ptr;
|
||||
|
||||
if (tmp_ptr != base_ptr)
|
||||
SWAP(tmp_ptr, base_ptr, size);
|
||||
|
||||
/* Insertion sort, running from left-hand-side up to right-hand-side. */
|
||||
|
||||
run_ptr = base_ptr + size;
|
||||
while ((run_ptr += size) <= end_ptr)
|
||||
{
|
||||
tmp_ptr = run_ptr - size;
|
||||
while ((*cmp)((void *) run_ptr, (void *) tmp_ptr) < 0)
|
||||
tmp_ptr -= size;
|
||||
|
||||
tmp_ptr += size;
|
||||
if (tmp_ptr != run_ptr)
|
||||
{
|
||||
int *trav;
|
||||
|
||||
trav = (int *)(run_ptr + size);
|
||||
while (--trav >= (int *)run_ptr)
|
||||
{
|
||||
int c = *trav;
|
||||
int *hi, *lo;
|
||||
|
||||
for (hi = lo = trav;
|
||||
(lo -= size/sizeof(int)) >= (int *)tmp_ptr; hi = lo)
|
||||
*hi = *lo;
|
||||
*hi = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifndef ALLOCA_PREFERRED
|
||||
if( pivot_buffer != static_pivot)
|
||||
Free(pivot_buffer);
|
||||
#endif
|
||||
}
|
87
external/libsdf/libsw/heap.c
vendored
Normal file
87
external/libsdf/libsw/heap.c
vendored
Normal file
|
@ -0,0 +1,87 @@
|
|||
/* Super-fast priority queue. ? Completely inlined by gcc. */
|
||||
/* Assume that each pointer points at */
|
||||
/* a key, AND whatever else the caller is interested in keeping. */
|
||||
|
||||
#ifndef assert
|
||||
#include "Assert.h"
|
||||
#endif
|
||||
#include <stddef.h>
|
||||
#include <float.h>
|
||||
#include "Malloc.h"
|
||||
#define HEAPdotC
|
||||
#include "heap.h"
|
||||
|
||||
#if !defined(HeapKey) || !defined(HeapLeft)
|
||||
# error Heap macros undefined
|
||||
#endif
|
||||
|
||||
/* These save us from an extra comparison inside our loops */
|
||||
const float HeapMinf = -FLT_MAX;
|
||||
const float HeapInf = FLT_MAX;
|
||||
|
||||
/* I wonder if some const decls would be correct? */
|
||||
void HeapInit(Heap *hp, unsigned int sz){
|
||||
assert(sz > 0);
|
||||
hp->arr = Malloc( (sz+1)*sizeof(*(hp->arr)) );
|
||||
assert(hp->arr);
|
||||
hp->sz = sz;
|
||||
hp->cnt = 1;
|
||||
hp->arr[0] = &HeapInf;
|
||||
}
|
||||
|
||||
void HeapTerminate(Heap *hp){
|
||||
Free((void *)hp->arr);
|
||||
hp->arr = NULL;
|
||||
hp->sz = hp->cnt = 0;
|
||||
}
|
||||
|
||||
int HeapIsBad(const Heap *hp){
|
||||
unsigned int i, ri, li;
|
||||
const float **arr = hp->arr;
|
||||
|
||||
for( i=1, li=2, ri=3;
|
||||
li < hp->cnt;
|
||||
i++, li = HeapLeft(i), ri = li+1){
|
||||
if( HeapKey(i) < HeapKey(li) )
|
||||
return li;
|
||||
if( ri < hp->cnt && HeapKey(i) < HeapKey(ri) )
|
||||
return ri;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef STANDALONE
|
||||
#include <stdio.h>
|
||||
|
||||
float data[] = {5., 1., 3., 2., 7., 3., 4.};
|
||||
|
||||
void HeapPrint(Heap *hp){
|
||||
unsigned int i;
|
||||
for(i=1; i<hp->cnt; i++){
|
||||
printf("%d %g\n", i, *(hp->arr[i]));
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv){
|
||||
Heap H;
|
||||
float *top;
|
||||
unsigned int i;
|
||||
unsigned int ndata;
|
||||
|
||||
HeapInit(&H, 2);
|
||||
ndata = sizeof(data)/sizeof(*data);
|
||||
for(i=0; i<ndata; i++){
|
||||
HeapPush(&H, &data[i]);
|
||||
printf("Inserted %g\n", data[i]);
|
||||
HeapPrint(&H);
|
||||
}
|
||||
|
||||
for(i=0; i<ndata; i++){
|
||||
HeapPop(&H, &top);
|
||||
printf("popped %g\n", *top);
|
||||
HeapPrint(&H);
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
/* Undefine our private macros because this file might be #include'ed */
|
91
external/libsdf/libsw/hwclock.c
vendored
Normal file
91
external/libsdf/libsw/hwclock.c
vendored
Normal file
|
@ -0,0 +1,91 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "error.h"
|
||||
#include "hwclock.h"
|
||||
|
||||
static double hwtick_val;
|
||||
#define two_to_32 4294967296.0
|
||||
|
||||
static double hwclock_offset;
|
||||
|
||||
#if defined(__x86_64__) && defined(__GNUC__)
|
||||
#define DEFAULT_MHZ 1200.e6
|
||||
static double
|
||||
mhz_from_proc(){
|
||||
FILE *fp = fopen("/proc/cpuinfo", "r");
|
||||
char line[512];
|
||||
|
||||
if( fp == NULL ){
|
||||
Warning("Can't open /proc/cpuinfo\n");
|
||||
return DEFAULT_MHZ;
|
||||
}
|
||||
|
||||
while( fgets(line, sizeof(line), fp) ){
|
||||
char *m;
|
||||
int nscan;
|
||||
double mhz;
|
||||
|
||||
if( (m = strstr(line, "cpu MHz")) ){
|
||||
/* sscanf should match any amount of whitespace around the : */
|
||||
nscan = sscanf(m, "cpu MHz : %lf\n", &mhz);
|
||||
if( nscan == 1 ){
|
||||
fclose(fp);
|
||||
return mhz*1.0e6;
|
||||
}else{
|
||||
Warning("sscanf returns %d, on '%s' of /proc/cpuinfo mhz line failed\n", nscan, line);
|
||||
fclose(fp);
|
||||
return DEFAULT_MHZ; /* let's just guess 200Mhz */
|
||||
}
|
||||
}
|
||||
}
|
||||
Warning("Did not find cpu MHz in /proc/cpuinfo\n");
|
||||
fclose(fp);
|
||||
return DEFAULT_MHZ;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* This doesn't belong here, but I can't be bothered to figure out where
|
||||
it does belong! */
|
||||
double
|
||||
hwclock(void)
|
||||
{
|
||||
#if defined(__x86_64__)
|
||||
static int init = 1;
|
||||
unsigned int counter[2];
|
||||
|
||||
__asm__("rdtsc \n\t"
|
||||
"movl %%eax,%0 \n\t"
|
||||
"movl %%edx,%1 \n\t"
|
||||
: "=m" (((unsigned *)counter)[0]), "=m" (((unsigned *)counter)[1])
|
||||
:
|
||||
: "eax" , "edx");
|
||||
|
||||
if (init) {
|
||||
init = 0;
|
||||
hwtick_val = 1.0/mhz_from_proc();
|
||||
hwclock_offset = hwtick_val*((double)counter[1]*two_to_32 + (double)counter[0]);
|
||||
return 0.0;
|
||||
}
|
||||
return(hwtick_val*((double)counter[1]*two_to_32 + (double)counter[0])-hwclock_offset);
|
||||
#else
|
||||
{
|
||||
struct timeval tp;
|
||||
struct timezone tzp;
|
||||
|
||||
gettimeofday(&tp,&tzp);
|
||||
return ( (double) tp.tv_sec + (double) tp.tv_usec * 1.e-6 );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
zero_hwclock(void)
|
||||
{
|
||||
hwclock_offset += hwclock();
|
||||
}
|
||||
|
||||
double
|
||||
hwtick(void)
|
||||
{
|
||||
return hwtick_val;
|
||||
}
|
54
external/libsdf/libsw/ivfprintf.c
vendored
Normal file
54
external/libsdf/libsw/ivfprintf.c
vendored
Normal file
|
@ -0,0 +1,54 @@
|
|||
#ifdef __SRV__
|
||||
# error This file should not be compiled with srv
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#ifndef FORCE_TYPE
|
||||
/* mesh.h is not protected against multiple inclusion ! */
|
||||
#include <mesh.h>
|
||||
#endif
|
||||
|
||||
/* Why isn't this in mesh.h? */
|
||||
extern void iowait(int);
|
||||
|
||||
/* A fast asynchronous disk message primitive */
|
||||
|
||||
/* There is circumstantial evidence that the delta dies if we have many */
|
||||
/* iwrites pending and call ifflush ???? (maybe fixed - johns ) ????*/
|
||||
|
||||
static int id[] = {-1, -1, -1, -1, -1, -1, -1, -1};
|
||||
#define NID (sizeof(id)/sizeof(id[0]))
|
||||
static int nid = 0;
|
||||
static char buf[NID][1024];
|
||||
|
||||
void
|
||||
ivfprintf(FILE *stream, const char *fmt, va_list args)
|
||||
{
|
||||
if (id[nid] != -1){
|
||||
iowait(id[nid]);
|
||||
}
|
||||
vsprintf(buf[nid], fmt, args);
|
||||
id[nid] = iwrite(fileno(stream), buf[nid], strlen(buf[nid]));
|
||||
if( ++nid == NID )
|
||||
nid = 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ifflush(FILE *stream)
|
||||
{
|
||||
int i;
|
||||
int ii;
|
||||
|
||||
/* stream not used. Just wait for all the pending i/o */
|
||||
for (ii = nid, i = 0; i < NID; i++){
|
||||
if (id[ii] != -1) {
|
||||
iowait(id[ii]);
|
||||
id[ii] = -1;
|
||||
}
|
||||
if( ++ii == NID )
|
||||
ii = 0;
|
||||
}
|
||||
}
|
79
external/libsdf/libsw/key.c
vendored
Normal file
79
external/libsdf/libsw/key.c
vendored
Normal file
|
@ -0,0 +1,79 @@
|
|||
#define KEYdotC
|
||||
/* Most of the definitions are in key.h */
|
||||
#include <stdio.h> /* just for sprintf */
|
||||
#include "key.h"
|
||||
#include "protos.h"
|
||||
|
||||
/* Non-inlined definitions go here. */
|
||||
|
||||
char *
|
||||
PrintKey(Key_t key)
|
||||
{
|
||||
static char str[128];
|
||||
|
||||
if (NK == 1)
|
||||
sprintf(str, "%lo", key.k[0]);
|
||||
else {
|
||||
if (key.k[1] == 0) {
|
||||
sprintf(str, "%lo", key.k[0]);
|
||||
} else {
|
||||
/* This only works for NDIM==3 */
|
||||
sprintf(str, "%lo%01lo%021lo", key.k[1] >> 2, /* bits 66-126*/
|
||||
((key.k[1] & 03) << 1) | (key.k[0] >> 63), /* bits 63,64,65 */
|
||||
key.k[0] & ~(1L << 63)); /* bits 0-62 */
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
#if 0
|
||||
int
|
||||
TreeLevel(Key_t key, int ndim)
|
||||
{
|
||||
int level;
|
||||
int chubits = (KEYBITS-1)/ndim;
|
||||
Key_t testkey;
|
||||
|
||||
/* First check whether it's a 'body' (at the deepest level.) */
|
||||
/* This will save considerable time... */
|
||||
testkey = KeyLshift(KeyInt(1), chubits*ndim);
|
||||
if( KeyEQ( testkey, KeyAnd(testkey, key) ) )
|
||||
return chubits;
|
||||
|
||||
/* Now start looking from low levels */
|
||||
testkey = KeyInt(1);
|
||||
for (level = 0; level<chubits; level++){
|
||||
if( KeyEQ(key, testkey) )
|
||||
return level;
|
||||
key = KeyRshift(key, ndim);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Find the common level between two 'body'-keys */
|
||||
int
|
||||
CommonLev(Key_t bkey1, Key_t bkey2, int ndim)
|
||||
{
|
||||
int level = (KEYBITS-1)/ndim;
|
||||
Key_t key0 = KeyInt(0);
|
||||
|
||||
for (bkey1 = KeyXOR(bkey1, bkey2); KeyNEQ(bkey1, key0); level--)
|
||||
bkey1 = KeyRshift(bkey1, ndim);
|
||||
|
||||
return(level);
|
||||
}
|
||||
|
||||
int
|
||||
KeyContained(Key_t outer, Key_t key, int ndim)
|
||||
{
|
||||
int ret;
|
||||
int difference;
|
||||
|
||||
/* What if difference is negative?! */
|
||||
difference = TreeLevel(key, ndim) - TreeLevel(outer, ndim);
|
||||
key = KeyRshift(key, ndim*difference);
|
||||
ret = KeyEQ(key, outer);
|
||||
return(ret);
|
||||
}
|
||||
#endif
|
281
external/libsdf/libsw/keycvt.c
vendored
Normal file
281
external/libsdf/libsw/keycvt.c
vendored
Normal file
|
@ -0,0 +1,281 @@
|
|||
/* A non-plug-compatible replacement for physics_generic.[ch]. Use with
|
||||
care, but then, you were using physics_generic.c with care, weren't
|
||||
you? */
|
||||
|
||||
#include <stddef.h>
|
||||
#include <float.h>
|
||||
#include "protos.h"
|
||||
#include "mpmy.h"
|
||||
#include "Msgs.h"
|
||||
#include "Assert.h"
|
||||
#include "key.h"
|
||||
#include "peano.h"
|
||||
#include "keycvt.h"
|
||||
|
||||
#ifndef FLT_MAX
|
||||
/* I wonder what they put in float.h, anyway */
|
||||
#define FLT_MAX 1.e38
|
||||
#endif
|
||||
|
||||
int KeyOutOfBounds;
|
||||
|
||||
/* This gives a tight bounding box around the list of positions. Note
|
||||
that the result is rmin <= pos[i] and rmax >= pos[i]. The equality
|
||||
can be a headache for float-to-int conversions! Consider using
|
||||
InflateBbox and or CubeBbox! */
|
||||
void
|
||||
TightBbox(float *pstart, int nobj, int pstride, int ndim, tbbox *bb){
|
||||
MPMY_Comm_request req;
|
||||
int d;
|
||||
float *pos = pstart;
|
||||
float rmin[MAXNDIMKU];
|
||||
float rmax[MAXNDIMKU];
|
||||
|
||||
assert(ndim < MAXNDIMKU);
|
||||
|
||||
for(d=0; d<ndim; d++){
|
||||
rmin[d] = FLT_MAX;
|
||||
rmax[d] = -FLT_MAX;
|
||||
}
|
||||
bb->ndim = ndim;
|
||||
while(nobj--){
|
||||
for(d=0; d<ndim; d++){
|
||||
float pd = pos[d];
|
||||
if( rmin[d] > pd ) rmin[d] = pd;
|
||||
if( rmax[d] < pd ) rmax[d] = pd;
|
||||
}
|
||||
pos = (float *)(pstride + (char *)pos);
|
||||
}
|
||||
MPMY_ICombine_Init(&req);
|
||||
MPMY_ICombine(rmin, bb->rmin, ndim, MPMY_FLOAT, MPMY_MIN, req);
|
||||
MPMY_ICombine(rmax, rmax, ndim, MPMY_FLOAT, MPMY_MAX, req);
|
||||
MPMY_ICombine_Wait(req);
|
||||
for(d=0; d<ndim; d++){
|
||||
bb->sz[d] = rmax[d] - bb->rmin[d];
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CenterBbox(tbbox *bb, float *center){
|
||||
int d;
|
||||
for(d=0; d<bb->ndim; d++){
|
||||
center[d] = bb->rmin[d] + 0.5F*bb->sz[d];
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
ContainsBbox(tbbox *bb1, tbbox *bb2){
|
||||
/* Return 1 if bb1 completely contains bb2 */
|
||||
int d;
|
||||
|
||||
for(d=0; d<bb1->ndim; d++){
|
||||
if( bb1->rmin[d] > bb2->rmin[d] ||
|
||||
bb1->rmin[d] + bb1->sz[d] < bb2->rmin[d]+bb2->sz[d] )
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Construct bbu, the 'union' of bb1 and bb2 */
|
||||
void
|
||||
UnionBbox(tbbox *bb1, tbbox *bb2, tbbox *bbu){
|
||||
int d;
|
||||
|
||||
bbu->ndim = bb1->ndim;
|
||||
for(d=0; d<bb1->ndim; d++){
|
||||
float max1, max2;
|
||||
float min1, min2;
|
||||
|
||||
/* Read these first in case bbu is equal to bb1 or bb2! */
|
||||
min1 = bb1->rmin[d];
|
||||
min2 = bb2->rmin[d];
|
||||
bbu->rmin[d] = (min1 < min2) ? min1 : min2;
|
||||
max1 = min1 + bb1->sz[d];
|
||||
max2 = min2 + bb2->sz[d];
|
||||
bbu->sz[d] = (max1 > max2) ? max1 - bbu->rmin[d] : max2 - bbu->rmin[d];
|
||||
}
|
||||
}
|
||||
|
||||
/* Make the bbox a cube by expanding the smaller dimensions. */
|
||||
void
|
||||
CubeBbox(tbbox *bb){
|
||||
int d;
|
||||
float maxs, halfmaxs;
|
||||
float center[MAXNDIMKU];
|
||||
|
||||
maxs = 0.;
|
||||
for(d=0; d<bb->ndim; d++) {
|
||||
center[d] = bb->rmin[d] + 0.5f * bb->sz[d];
|
||||
if( maxs < bb->sz[d] )
|
||||
maxs = bb->sz[d];
|
||||
}
|
||||
halfmaxs = 0.5f*maxs;
|
||||
for( d=0; d<bb->ndim; d++){
|
||||
bb->rmin[d] = center[d] - halfmaxs;
|
||||
bb->sz[d] = maxs;
|
||||
}
|
||||
}
|
||||
|
||||
/* Increase the linear dimension by 'factor' on all sides */
|
||||
void
|
||||
InflateBbox(tbbox *bb, float factor){
|
||||
float center;
|
||||
int d;
|
||||
for( d=0; d<bb->ndim; d++){
|
||||
center = 0.5f*bb->sz[d] + bb->rmin[d];
|
||||
bb->sz[d] *= factor;
|
||||
bb->rmin[d] = center - 0.5f*bb->sz[d];
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GenerateKeys(float *pstart, int nobj, int pstride, tbbox *bb,
|
||||
Key_t *kstart, int kstride, int order_type){
|
||||
int i, d;
|
||||
float keyfactor[MAXNDIMKU];
|
||||
unsigned int ik[MAXNDIMKU];
|
||||
unsigned int chubits;
|
||||
Key_t *kp;
|
||||
float *pos;
|
||||
unsigned int maxikey;
|
||||
float fmaxikey;
|
||||
Key_t (*KfI)(unsigned int *xp, int ndim, int nbits);
|
||||
|
||||
chubits = ((KEYBITS-1) / bb->ndim );
|
||||
maxikey = (1U<<chubits) - 1;
|
||||
fmaxikey = (float)maxikey;
|
||||
for(d=0; d<bb->ndim; d++){
|
||||
/* Divide by 0 ?? */
|
||||
keyfactor[d] = (1U<<chubits)/(bb->sz[d]);
|
||||
}
|
||||
pos = pstart;
|
||||
kp = kstart;
|
||||
switch( order_type ){
|
||||
case MORTON_ORDER:
|
||||
KfI = &KeyFromInts;
|
||||
break;
|
||||
case PH_ORDER:
|
||||
assert(bb->ndim == 3); /* assumed by the current implementation*/
|
||||
KfI = &PHKeyFromInts;
|
||||
break;
|
||||
default:
|
||||
Error("Unrecognized order_type in GenerateKeys\n");
|
||||
}
|
||||
|
||||
for(i=0; i<nobj; i++){
|
||||
for(d=0; d<bb->ndim; d++){
|
||||
float fk = keyfactor[d] * (pos[d] - bb->rmin[d]);
|
||||
if( fk < 0. ){
|
||||
KeyOutOfBounds = 1;
|
||||
ik[d] = 0;
|
||||
}else if( fk > fmaxikey ){
|
||||
ik[d] = maxikey;
|
||||
KeyOutOfBounds = 1;
|
||||
}else
|
||||
ik[d] = (unsigned int)fk;
|
||||
}
|
||||
*kp = (*KfI)(ik, bb->ndim, chubits);
|
||||
kp = (Key_t *) ( kstride + (char *)kp);
|
||||
pos = (float *) ( pstride + (char *)pos);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CellBBFromKey(Key_t key, tbbox *bb, tbbox *cellbb, int order_type)
|
||||
{
|
||||
unsigned int icorner[MAXNDIMKU];
|
||||
unsigned int iscale;
|
||||
float factor;
|
||||
int d;
|
||||
|
||||
switch(order_type){
|
||||
case MORTON_ORDER:
|
||||
iscale = (1<<IntsFromKey(key, icorner, bb->ndim));
|
||||
break;
|
||||
case PH_ORDER:
|
||||
iscale = (1<<IntsFromPHKey(key, icorner, bb->ndim));
|
||||
break;
|
||||
default:
|
||||
Error("Unrecognized ordering in CellBBFromKey\n");
|
||||
}
|
||||
|
||||
/* Now scale it back to "physical" units */
|
||||
cellbb->ndim = bb->ndim;
|
||||
for(d=0; d<bb->ndim; d++){
|
||||
factor = (bb->sz[d])/iscale;
|
||||
cellbb->rmin[d] = bb->rmin[d] + factor*icorner[d];
|
||||
cellbb->sz[d] = factor;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
IntsFromFloats(const float *x, unsigned int *ix, tbbox *bb, int nbits){
|
||||
int d;
|
||||
unsigned int iscale = 1<<nbits;
|
||||
|
||||
if (nbits >= CHAR_BIT*sizeof(iscale)) {
|
||||
Error("nbits out of range in IntsFromFloats\n");
|
||||
}
|
||||
for(d=0; d<bb->ndim; d++){
|
||||
ix[d] = iscale * (x[d] - bb->rmin[d]) / (bb->sz[d]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
FloatsFromInts(const int *ix, float *x, tbbox *bb, int nbits){
|
||||
unsigned int iscale = 1<<nbits;
|
||||
int d;
|
||||
if (nbits >= CHAR_BIT*sizeof(iscale)) {
|
||||
Error("nbits out of range in FloatsFromInts\n");
|
||||
}
|
||||
for(d=0; d<bb->ndim; d++){
|
||||
x[d] = ix[d] * ((bb->sz[d])/iscale);
|
||||
}
|
||||
}
|
||||
|
||||
/* These two names conflict with physics_generic.c. Good. It will
|
||||
keep me from using physics_generic.c accidentally. */
|
||||
Key_t
|
||||
KeyFromInts(unsigned int *xp, int ndim, int nbits){
|
||||
Key_t key;
|
||||
unsigned int rshift, bits, dim;
|
||||
|
||||
/* Set first bit. Important! */
|
||||
key = KeyInt(1);
|
||||
for(rshift=nbits; rshift; ){
|
||||
rshift--;
|
||||
bits = 0;
|
||||
for(dim = 0; dim < ndim; dim++ )
|
||||
bits |= ((xp[dim]>>rshift)&1) << dim;
|
||||
key = KeyOrInt(KeyLshift(key, ndim), bits);
|
||||
}
|
||||
return(key);
|
||||
}
|
||||
|
||||
/* Notice that the return value is DIFFERENT FROM physics_generic.c
|
||||
Here, we return the number of bits. It's easier for the caller to do
|
||||
left-shift than ilog2. */
|
||||
int
|
||||
IntsFromKey(Key_t key, unsigned int *ip, int ndim){
|
||||
unsigned int iscale = 1;
|
||||
unsigned int lev = 0;
|
||||
int i;
|
||||
|
||||
for(i=0; i<ndim; i++){
|
||||
ip[i] = 0;
|
||||
}
|
||||
while(KeyGT(key, KeyInt(1))) {
|
||||
for(i=0; i<ndim; i++){
|
||||
if( KeyAndInt(key, (1<<i)) )
|
||||
ip[i] |= iscale;
|
||||
}
|
||||
key = KeyRshift(key, ndim);
|
||||
iscale <<= 1;
|
||||
lev++;
|
||||
if (lev >= CHAR_BIT*sizeof(iscale)) {
|
||||
Error("lev out of range in IntsFromKey\n");
|
||||
}
|
||||
}
|
||||
return lev;
|
||||
}
|
||||
|
792
external/libsdf/libsw/lsv.c
vendored
Normal file
792
external/libsdf/libsw/lsv.c
vendored
Normal file
|
@ -0,0 +1,792 @@
|
|||
/*
|
||||
* Copyright 1992,1993 Michael S. Warren. All Rights Reserved.
|
||||
*/
|
||||
|
||||
/* define this to skip the FIONREAD code entirely */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <signal.h>
|
||||
#ifndef FD_SET
|
||||
/* Sigh. Where o' where is FD_SET found sys/types?, sys/select? */
|
||||
/* Unfortunately, sys/select doesn't always exist! */
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
#include "protos.h"
|
||||
#include "lsv.h"
|
||||
#include "error.h"
|
||||
#include "Msgs.h"
|
||||
#include "Assert.h"
|
||||
#include "Malloc.h"
|
||||
|
||||
#ifdef __DO_SWAP__
|
||||
/* There's probably a better way to do most of the multi-word swaps... */
|
||||
#include "byteswap.h"
|
||||
static int _x, _y;
|
||||
#define Swap(x) (_x=x, Byteswap(sizeof(int), 1, &_x, &_y), _y)
|
||||
#else
|
||||
#define Swap(x) x
|
||||
#endif
|
||||
|
||||
/* This test should be accomplished some other way!! */
|
||||
#if defined(USE_ALARM) && !( defined(__x86_64__) || defined(_AIX) || defined(__SUN5__) )
|
||||
#define HAVE_SIGVEC
|
||||
#endif
|
||||
|
||||
#if defined(__SUN4__)
|
||||
/* These should really be prototyped somewhere else,
|
||||
but this will do for now */
|
||||
int close(int);
|
||||
int getpid(void);
|
||||
#ifdef HAVE_SIGVEC
|
||||
int sigvec(int sig, struct sigvec *vec, struct sigvec *ovec);
|
||||
#endif
|
||||
int ioctl(int fd, int cmd, void *p);
|
||||
int gethostname(char *name, int namelen);
|
||||
char *inet_ntoa(struct in_addr in);
|
||||
int socket(int domain, int type, int protocol);
|
||||
int bind(int s, struct sockaddr *name, int namelen);
|
||||
int recvfrom(int s, void *buf, int len, int flags,
|
||||
struct sockaddr *from, int *fromlen);
|
||||
int sendto(int s, const void *msg, int len,
|
||||
int flags, struct sockaddr *to, int tolen);
|
||||
int select(int width, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
|
||||
struct timeval *timeout);
|
||||
int getsockname(int s, struct sockaddr *name, int *namelen);
|
||||
void bzero(char *b, int length);
|
||||
#endif
|
||||
|
||||
#if defined(__SUN5__)
|
||||
/* This is a bsd-ism. It may not even exist everywhere?! */
|
||||
int gethostname(char *name, int namelen);
|
||||
#endif
|
||||
|
||||
#define MAXDEFER 4000 /* maximum number of messages deferred */
|
||||
#define HLEN (5*sizeof(int)) /* size of packet header */
|
||||
#define MAXLEN 8192 /* size of total packet */
|
||||
#define BLOCK (MAXLEN-HLEN) /* size of basic data packet */
|
||||
#define ACK_TYPE (-1) /* Message type for ack */
|
||||
#define H_MAGIC (0x9f07) /* Magic number for headers */
|
||||
|
||||
#define MAX_PORT_ATTEMPTS 150 /* Number of ports to try before giving up */
|
||||
#define LSV_TYPE 2 /* Type used to communicate with host */
|
||||
#define HOST_NUM (-1) /* can't redefine this without mem adjust. */
|
||||
#ifndef INADDR_NONE
|
||||
#define INADDR_NONE -1 /* 'bad' return from inet_addr */
|
||||
#endif
|
||||
|
||||
static int host_num = HOST_NUM; /* host integer address */
|
||||
static int my_pid; /* my process id */
|
||||
static unsigned int *seqout; /* array of outgoing sequence counters */
|
||||
static unsigned int *seqin; /* array of incoming sequence counters */
|
||||
static unsigned int *nretry; /* array of retry counts */
|
||||
static struct sockaddr_in host_addr;
|
||||
static struct sockaddr_in my_addr;
|
||||
|
||||
static int sock; /* file descriptor for my UDP socket */
|
||||
static struct sockaddr_in *addr; /* sockaddrs for all processors */
|
||||
static char *msgbuf[MAXDEFER]; /* pointers to deferred messages */
|
||||
static int msgcnt; /* number of deferred messages */
|
||||
#ifdef USE_ALARM
|
||||
static volatile int failed; /* flag for recvfrom timeout */
|
||||
static void to_alarm(int);
|
||||
#endif
|
||||
static void sock_init(struct sockaddr_in *acc, int bind_flag);
|
||||
static void common_init(const int n);
|
||||
static int bsend(int s, const void *outbuf, int sent, int dest, int type);
|
||||
static int brecv(int s, void *inb, int sent, int *dest, int type, int block);
|
||||
static int chk_deferw(int type, int *src);
|
||||
static void send_ack(int s, int dest, int seq, struct sockaddr_in *dest_addr);
|
||||
static int chk_defer(int src, int type, int seq);
|
||||
|
||||
int LSV_procnum; /* my integer address (procnum) */
|
||||
int LSV_nproc; /* how many 'elt's */
|
||||
|
||||
/* If hears nothing before its 'block' arg expires, it returns
|
||||
BRECV_TIMEDOUT */
|
||||
#define BRECV_TIMEDOUT (-2)
|
||||
|
||||
/* It sure would be nice to be able to set these at runtime!!! */
|
||||
/* TIMEOUT1 passed to brecv when we're 'blocking', i.e., from Srecv_block. */
|
||||
#define TIMEOUT1 200
|
||||
/* TIMEOUT2 is what we pass when we really expect something, i.e., when
|
||||
we are waiting for subsequent blocks after we have received the first
|
||||
one. */
|
||||
#define TIMEOUT2 50
|
||||
/* Srecv{_block} will allow retry brecv after a timeout this many
|
||||
times before giving up altogether. */
|
||||
#define NRETRY 2
|
||||
/* Ssend waits for an ack from the recipient. It retries this many
|
||||
times, incrementing the timer by one each time, so in the end, the
|
||||
total time waited is ACK_NRETRY*(ACK_NRETRY+1)/2 seconds. Now that
|
||||
the user code is free to use alarm, we can rely on the user to bail out
|
||||
if things seem to be taking too long. Thus, we set this quite high. */
|
||||
#ifndef USE_ALARM
|
||||
#define ACK_NRETRY 100
|
||||
#else
|
||||
#define ACK_NRETRY 20
|
||||
#endif
|
||||
|
||||
void
|
||||
Sclose(void)
|
||||
{
|
||||
close(sock);
|
||||
/* Should we free some of the arrays??? */
|
||||
}
|
||||
|
||||
void
|
||||
Sinit_elt(void)
|
||||
{
|
||||
int suspend_proc;
|
||||
int pid;
|
||||
int nin;
|
||||
int size = sizeof(struct sockaddr_in);
|
||||
int hostport;
|
||||
char *hostip;
|
||||
unsigned long inaddr;
|
||||
|
||||
assert(getenv("LSV_PROCNUM") && getenv("LSV_NPROC")
|
||||
&& getenv("LSV_HOSTPORT") && getenv("LSV_HOST") );
|
||||
|
||||
LSV_procnum = atoi(getenv("LSV_PROCNUM"));
|
||||
LSV_nproc = atoi(getenv("LSV_NPROC"));
|
||||
hostip = getenv("LSV_HOST");
|
||||
hostport = atoi(getenv("LSV_HOSTPORT"));
|
||||
|
||||
/* fill in host_addr here */
|
||||
memset(&host_addr, sizeof(host_addr), 0);
|
||||
host_addr.sin_family = AF_INET;
|
||||
/* Now try to figure out the host's address from hostname */
|
||||
/* Don't bother with gethostbyname here. Assume that the host
|
||||
has worked out its preferred numeric IP address and passed that
|
||||
to us through the environment var LSV_HOST */
|
||||
if ((inaddr = inet_addr(hostip)) != INADDR_NONE) /* it is numeric */
|
||||
host_addr.sin_addr.s_addr = inaddr;
|
||||
else
|
||||
Error("inet_addr(%s) failed, errno=%d\n", hostip, errno);
|
||||
host_addr.sin_port = htons(hostport);
|
||||
Msgf(("hostip: %s, host_addr.sin_addr %s, host_addr.sin_port: %d\n",
|
||||
hostip, inet_ntoa(host_addr.sin_addr), ntohs(host_addr.sin_port)));
|
||||
|
||||
sock_init(&host_addr, 0); /* get host sockaddr */
|
||||
sock_init(&my_addr, 1); /* get my sockaddr */
|
||||
Msgf(("my_addr.sin_addr: %s, my_addr.sin_port: %d\n",
|
||||
inet_ntoa(my_addr.sin_addr), ntohs(my_addr.sin_port)));
|
||||
|
||||
|
||||
common_init(LSV_nproc);
|
||||
|
||||
Ssend(&my_addr, size, HOST_NUM, LSV_TYPE); /* send to host */
|
||||
|
||||
nin = Srecv_block(addr, LSV_nproc * size, LSV_TYPE, &host_num);
|
||||
if (nin != LSV_nproc * size)
|
||||
Error("Bad number of addrs received\n");
|
||||
|
||||
if( getenv("LSV_SUSPEND") && strlen(getenv("LSV_SUSPEND")) > 0 ){
|
||||
pid = getpid();
|
||||
suspend_proc = atoi(getenv("LSV_SUSPEND"));
|
||||
if (suspend_proc == -1) /* suspend all */
|
||||
suspend_proc = LSV_procnum;
|
||||
if (LSV_procnum == suspend_proc){
|
||||
Shout("suspending pid=%d, LSV_procnum=%d\n",
|
||||
pid, LSV_procnum);
|
||||
kill(pid, SIGSTOP);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Sinit_host1 is called BEFORE the host forks off child processes.
|
||||
It has to figure out its own port and hostname, so it can pass it
|
||||
to the children in the environment. */
|
||||
void
|
||||
Sinit_host1(int *portp, char **namep){
|
||||
char *p;
|
||||
|
||||
sock_init(&host_addr, 1);
|
||||
*portp = ntohs(host_addr.sin_port);
|
||||
if( (p=getenv("LSV_HOST")) == NULL ){
|
||||
/* If there is no LSV_HOST in the environment, then ask the system */
|
||||
p = inet_ntoa(host_addr.sin_addr);
|
||||
}
|
||||
*namep = malloc(strlen(p)+1);
|
||||
strcpy(*namep, p);
|
||||
}
|
||||
|
||||
/* Sinit_host is called after the host forks the child processes.
|
||||
Its job is to communicate all the port info with them so they
|
||||
can talk to one another directly. */
|
||||
void
|
||||
Sinit_host(int n) /* n is how many nodes we talk to */
|
||||
{
|
||||
int i, nin;
|
||||
int size = sizeof(struct sockaddr_in);
|
||||
|
||||
common_init(n);
|
||||
Msgf(("After common_init\n"));
|
||||
LSV_procnum = HOST_NUM;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
nin = Srecv_block(&addr[i], size, LSV_TYPE, &i);
|
||||
if (nin != size)
|
||||
Error("Bad recv size (%d) in Sinit_host, i=%d\n", nin, i);
|
||||
Msgf(("Received addr[%d]: family: %d, port: %d, addr: %s\n",
|
||||
i, addr[i].sin_family, ntohs(addr[i].sin_port),
|
||||
inet_ntoa(addr[i].sin_addr)));
|
||||
}
|
||||
Msgf(("All sockaddrs received. Broadcasting to compute processes\n"));
|
||||
for (i = 0; i < n; i++) {
|
||||
Ssend(addr, n * size, i, LSV_TYPE);
|
||||
Msgf(("Sent addrs to %d\n", i));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
common_init(const int n)
|
||||
{
|
||||
#if defined(HAVE_SIGVEC)
|
||||
struct sigvec vec;
|
||||
#endif
|
||||
|
||||
/* to enforce sequencing */
|
||||
seqin = (unsigned int *) calloc(n+1, sizeof(unsigned int));
|
||||
seqout = (unsigned int *) calloc(n+1, sizeof(unsigned int));
|
||||
nretry = (unsigned int *) calloc(n+1, sizeof(unsigned int));
|
||||
addr = (struct sockaddr_in *) calloc(n+1, sizeof(struct sockaddr_in));
|
||||
if (seqin == NULL || seqout == NULL || nretry == NULL || addr == NULL)
|
||||
Error("No more memory in Sinit\n");
|
||||
seqin++; /* allow indexing [-1:n-1] */
|
||||
seqout++;
|
||||
nretry++;
|
||||
addr++;
|
||||
|
||||
/* We use the convention that 0, ..., n-1 are nodes, and -1 is the host */
|
||||
addr[HOST_NUM] = host_addr; /* struct assignment */
|
||||
my_pid = getpid();
|
||||
|
||||
#ifdef USE_ALARM
|
||||
#if defined (HAVE_SIGVEC)
|
||||
vec.sv_handler = to_alarm;
|
||||
vec.sv_flags = SV_INTERRUPT;
|
||||
vec.sv_mask = 0;
|
||||
sigvec(SIGALRM, &vec, NULL);
|
||||
#else
|
||||
signal(SIGALRM, to_alarm);
|
||||
#endif /* HAVE_SIGVEC */
|
||||
#endif /* USE_ALARM */
|
||||
|
||||
}
|
||||
|
||||
#ifdef USE_ALARM
|
||||
static void
|
||||
to_alarm(int sig)
|
||||
{
|
||||
assert( sig == SIGALRM );
|
||||
failed = 1;
|
||||
signal(SIGALRM, to_alarm);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* dest should be last argument */
|
||||
|
||||
void
|
||||
Ssend(const void *outb, int outcnt, int dest, int type)
|
||||
{
|
||||
int sent;
|
||||
const char *buf = outb;
|
||||
int ret;
|
||||
|
||||
Msgf(("Ssend: (%d) to %d len %d\n", type, dest, outcnt));
|
||||
do {
|
||||
sent = (outcnt > BLOCK) ? BLOCK : outcnt;
|
||||
ret = bsend(sock, buf, sent, dest, type);
|
||||
if( ret < 0 ){
|
||||
Error("Ssend: bsend failed, type=%d, dest=%d, outcnt=%d\n",
|
||||
type, dest, outcnt);
|
||||
}
|
||||
outcnt -= sent;
|
||||
buf += sent;
|
||||
} while (outcnt || sent == BLOCK);
|
||||
}
|
||||
|
||||
int
|
||||
Srecv(void *inb, int size, int type, int *from)
|
||||
{
|
||||
int sent, inbytes = 0;
|
||||
char *buf = inb;
|
||||
int timeout;
|
||||
int verbose = 0;
|
||||
|
||||
/* Only the first brecv is non-blocking. We wait for the rest. */
|
||||
sent = brecv(sock, buf+inbytes, size, from, type, 0);
|
||||
if( sent < 0 ){
|
||||
if( sent == BRECV_TIMEDOUT ){
|
||||
return -1; /* nothing available, not an error! */
|
||||
}
|
||||
Error("First brecv failed in Srecv, errno=%d\n", errno);
|
||||
}
|
||||
|
||||
inbytes += sent;
|
||||
size -= sent;
|
||||
timeout = TIMEOUT2;
|
||||
while(sent == BLOCK){
|
||||
tryagain:
|
||||
sent = brecv(sock, buf+inbytes, size, from, type, timeout);
|
||||
if( sent < 0 ){
|
||||
if( sent == BRECV_TIMEDOUT ){
|
||||
Warning("Srecv: brecv timed out, will wait indefinitely now\n");
|
||||
verbose = 1;
|
||||
timeout = -1;
|
||||
goto tryagain;
|
||||
}
|
||||
Error("brecv failed in Srecv, inbytes=%d, errno=%d\n",
|
||||
inbytes, errno);
|
||||
}
|
||||
inbytes += sent;
|
||||
size -= sent;
|
||||
}
|
||||
if( verbose || Msg_test(__FILE__) )
|
||||
Msg_do("Srecv: (%d) from %d ret %d\n", type, *from, inbytes);
|
||||
return(inbytes);
|
||||
}
|
||||
|
||||
/* last arg should not be a pointer */
|
||||
|
||||
int
|
||||
Srecv_block(void *inb, int size, int type, int *from)
|
||||
{
|
||||
int sent, inbytes = 0;
|
||||
char *buf = inb;
|
||||
int timeout = TIMEOUT1;
|
||||
int verbose = 0;
|
||||
|
||||
do {
|
||||
tryagain:
|
||||
sent = brecv(sock, buf+inbytes, size, from, type, timeout);
|
||||
if( sent < 0 ){
|
||||
if( sent == BRECV_TIMEDOUT ){
|
||||
Warning("Srecv_block: brecv(size=%d, from=%d, type=%d, timeout=%d) timed out, inbytes=%d, errno=%d\n",
|
||||
size, *from, type, timeout,
|
||||
inbytes, errno);
|
||||
timeout = -1;
|
||||
verbose = 1;
|
||||
goto tryagain;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
inbytes += sent;
|
||||
size -= sent;
|
||||
timeout = TIMEOUT2;
|
||||
} while (sent == BLOCK);
|
||||
if( verbose || Msg_test(__FILE__) )
|
||||
Msg_do("Srecv_block: (%d) from %d ret %d\n", type, *from, inbytes);
|
||||
return(inbytes);
|
||||
}
|
||||
|
||||
void Sdiag(int (*printf_like)(const char *, ...)){
|
||||
int i;
|
||||
int *buf;
|
||||
printf_like("lsv.c: counters to and from various destinations\n[dest seqout[dest] seqin[dest] nretry[dest]]\n");
|
||||
for(i=-1; i<LSV_nproc; i++){
|
||||
printf_like("%d %d %d %d\n", i, seqout[i], seqin[i], nretry[i]);
|
||||
}
|
||||
printf_like("lsv.c unread message buffers:\n");
|
||||
printf_like("[src seqno type length]\n");
|
||||
for(i=0; i<msgcnt; i++){
|
||||
buf = (int *)msgbuf[i];
|
||||
printf_like("%d %d %d %d\n", buf[1], buf[2], buf[3], buf[4]);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
bsend(int s, const void *outbuf, int sent, int dest, int type)
|
||||
{
|
||||
int incnt;
|
||||
int outb[MAXLEN/sizeof(int)];
|
||||
int inbuf[MAXLEN/sizeof(int)];
|
||||
int src, seq, intype, inlen;
|
||||
struct sockaddr_in src_addr;
|
||||
int len = sizeof(struct sockaddr_in);
|
||||
int retry = 0;
|
||||
int nfail = 0;
|
||||
int nsent;
|
||||
int verbose = 0;
|
||||
#ifndef USE_ALARM
|
||||
struct timeval timeout;
|
||||
fd_set rdset;
|
||||
int selreturn;
|
||||
#endif
|
||||
|
||||
Msgf(("bsend seq:%d type:%d len: %d to %d...", seqout[dest], type, sent, dest));
|
||||
|
||||
outb[0] = Swap(H_MAGIC);
|
||||
outb[1] = Swap(LSV_procnum);
|
||||
outb[2] = Swap(seqout[dest]);
|
||||
outb[3] = Swap(type);
|
||||
outb[4] = Swap(sent);
|
||||
|
||||
memcpy(outb + HLEN/sizeof(int), outbuf, sent);
|
||||
sent += HLEN;
|
||||
|
||||
try_again:
|
||||
errno = 0;
|
||||
retry++;
|
||||
if ((nsent=sendto(s, (void *)outb, sent, 0, (struct sockaddr *)(addr+dest),
|
||||
sizeof(struct sockaddr_in))) != sent) {
|
||||
Shout("sendto: addr: %d %s\n",
|
||||
ntohs(addr[dest].sin_port), inet_ntoa(addr[dest].sin_addr));
|
||||
Error("sendto(s=%d, sent=%d) seqout[%d]=%d returns %d, errno=%d ",
|
||||
s, sent, dest, seqout[dest], nsent, errno);
|
||||
}
|
||||
|
||||
ackrecv:
|
||||
#ifndef USE_ALARM
|
||||
timeout.tv_sec = retry;
|
||||
timeout.tv_usec = 0;
|
||||
FD_ZERO(&rdset);
|
||||
FD_SET(s, &rdset);
|
||||
selreturn = select(s+1, &rdset, NULL, NULL, &timeout);
|
||||
if( selreturn < 0 ){
|
||||
if (errno == EINTR)
|
||||
goto ackrecv; /* SIGPROF interrupts select */
|
||||
else {
|
||||
SeriousWarning("bsend select failed, errno=%d\n", errno);
|
||||
return -1;
|
||||
}
|
||||
}else if(selreturn == 0){
|
||||
/* This warning may indicate a serious problem, or it just may
|
||||
mean that the network or the destination node is saturated. */
|
||||
Warning("bsend timed out waiting for ack for seqout[%d]=%d\n", dest,
|
||||
seqout[dest]);
|
||||
nretry[dest]++;
|
||||
if( retry > ACK_NRETRY ){
|
||||
SeriousWarning("bsend timed out %d times waiting for ack\n",
|
||||
retry);
|
||||
return -1;
|
||||
}
|
||||
verbose = 1;
|
||||
goto try_again;
|
||||
}
|
||||
if( verbose || Msg_test(__FILE__) )
|
||||
Msg_do("bsend ackrecv ready\n");
|
||||
|
||||
memset(&src_addr, 0, sizeof(struct sockaddr_in));
|
||||
incnt = recvfrom(s, (void *)inbuf, MAXLEN, 0, (struct sockaddr *)&src_addr, &len);
|
||||
#else
|
||||
memset(&src_addr, 0, sizeof(struct sockaddr_in));
|
||||
failed = 0;
|
||||
alarm(1+retry);
|
||||
errno = 0;
|
||||
incnt = recvfrom(s, inbuf, MAXLEN, 0, (struct sockaddr *)&src_addr, &len);
|
||||
if (failed) {
|
||||
Msgf(("retry, errno=%d\n", errno));
|
||||
if (retry > ACK_NRETRY) {
|
||||
SeriousWarning("bsend timed out on ack, errno=%d\n", errno);
|
||||
return -1;
|
||||
}
|
||||
goto try_again;
|
||||
}
|
||||
alarm(0);
|
||||
#endif
|
||||
|
||||
if (incnt < 0) {
|
||||
Warning("recvfrom(ack from %d) returns %d, errno=%d\n", dest, incnt, errno);
|
||||
if(nfail++ > 5){
|
||||
SeriousWarning("recvfrom(ack from %d) returns %d, errno=%d\n", dest, incnt, errno);
|
||||
return -1;
|
||||
}
|
||||
goto try_again;
|
||||
}
|
||||
if (Swap(inbuf[0]) != H_MAGIC) {
|
||||
Warning("Bad header in bsend\n");
|
||||
goto ackrecv;
|
||||
}
|
||||
|
||||
#ifdef __DO_SWAP__
|
||||
inbuf[1] = Swap(inbuf[1]);
|
||||
inbuf[2] = Swap(inbuf[2]);
|
||||
inbuf[3] = Swap(inbuf[3]);
|
||||
inbuf[4] = Swap(inbuf[4]);
|
||||
#endif
|
||||
|
||||
src = inbuf[1];
|
||||
seq = inbuf[2];
|
||||
intype = inbuf[3];
|
||||
inlen = inbuf[4];
|
||||
|
||||
if (intype != ACK_TYPE) { /* got a data packet */
|
||||
if (seq < seqin[src])
|
||||
Msgf(("aignore2 %d from %d ", seq, src));
|
||||
else if (chk_defer(src, intype, seq) > -1)
|
||||
Msgf(("aignore %d from %d ", seq, src));
|
||||
else {
|
||||
msgbuf[msgcnt] = Malloc((incnt+8)&~07);
|
||||
memcpy(msgbuf[msgcnt], inbuf, incnt);
|
||||
msgcnt++;
|
||||
if (msgcnt >= MAXDEFER) Error("msgcnt too large\n");
|
||||
Msgf(("adefer seq:%d type:%d, len:%d from %d ",
|
||||
seq, intype, inlen, src));
|
||||
}
|
||||
send_ack(s, src, seq, &src_addr);
|
||||
goto ackrecv;
|
||||
} else {
|
||||
if (incnt != HLEN)
|
||||
Warning("Bad incnt, errno=%d", errno);
|
||||
else if (dest != src || seq != seqout[dest])
|
||||
Msgf(("aduplicate ack %d from %d ", seq, src));
|
||||
else {
|
||||
Msgf(("ack seq: %d, dest: %d\n", seq, dest));
|
||||
seqout[dest]++;
|
||||
return (sent-HLEN);
|
||||
}
|
||||
goto ackrecv;
|
||||
}
|
||||
}
|
||||
|
||||
/* Block is a timeout. We treat a negative value as meaning to block
|
||||
forever*/
|
||||
static int
|
||||
brecv(int s, void *inb, int sent, int *dest, int type, int block)
|
||||
{
|
||||
int src, seq, incnt;
|
||||
struct sockaddr_in src_addr;
|
||||
int len = sizeof(struct sockaddr_in);
|
||||
int inlen, i;
|
||||
int intype;
|
||||
int inbuf[(BLOCK+HLEN)/sizeof(int)];
|
||||
fd_set rdset;
|
||||
struct timeval timeout, *timeoutp;
|
||||
int selreturn;
|
||||
|
||||
Msgf(("brecv(sent=%d, dest=%d, type=%d, block=%d)\n",
|
||||
sent, *dest, type, block));
|
||||
if (*dest == LSV_ANY)
|
||||
i = chk_deferw(type, &src); /* sets src */
|
||||
else
|
||||
i = chk_defer(*dest, type, seqin[*dest]);
|
||||
if (i != -1) {
|
||||
if (*dest == LSV_ANY) *dest = src;
|
||||
inlen = *(int *)(msgbuf[i]+4*sizeof(int));
|
||||
if (inlen > sent) Error("Too much data\n");
|
||||
memcpy(inb, msgbuf[i]+HLEN, inlen);
|
||||
Free(msgbuf[i]);
|
||||
msgbuf[i] = msgbuf[--msgcnt];
|
||||
Msgf(("brecv %d (%d) from %d.\n", seqin[*dest], type, *dest));
|
||||
seqin[*dest]++;
|
||||
return(inlen);
|
||||
}
|
||||
|
||||
datrecv:
|
||||
if( block >= 0 ){
|
||||
timeout.tv_sec = block;
|
||||
timeout.tv_usec = 0;
|
||||
timeoutp = &timeout;
|
||||
}else{
|
||||
timeoutp = NULL;
|
||||
}
|
||||
FD_ZERO(&rdset);
|
||||
FD_SET(s, &rdset);
|
||||
selreturn = select(s+1, &rdset, NULL, NULL, timeoutp);
|
||||
if( selreturn < 0 ){
|
||||
if (errno == EINTR)
|
||||
goto datrecv; /* SIGPROF interrupts select */
|
||||
else {
|
||||
SeriousWarning("select failed, errno=%d\n", errno);
|
||||
return -1;
|
||||
}
|
||||
}else if(selreturn == 0){
|
||||
return BRECV_TIMEDOUT;
|
||||
}
|
||||
Msgf(("brecv any (%d)...", type));
|
||||
|
||||
memset(&src_addr, 0, sizeof(struct sockaddr_in));
|
||||
/* What's the best thing to do here if we timed out?
|
||||
return? goto datrecv? something else?*/
|
||||
incnt = recvfrom(s, (void *)inbuf, MAXLEN, 0, (struct sockaddr *)&src_addr, &len);
|
||||
|
||||
if (incnt < 0) {
|
||||
Warning("brecv: recvfrom, errno=%d", errno);
|
||||
goto datrecv;
|
||||
}
|
||||
if (Swap(inbuf[0]) != H_MAGIC) {
|
||||
Warning("Bad header in brecv (%x,%x,%x,%x), incnt %d\n",
|
||||
Swap(inbuf[0]), Swap(inbuf[1]), Swap(inbuf[2]), Swap(inbuf[3]),
|
||||
incnt);
|
||||
goto datrecv;
|
||||
}
|
||||
|
||||
#ifdef __DO_SWAP__
|
||||
inbuf[1] = Swap(inbuf[1]);
|
||||
inbuf[2] = Swap(inbuf[2]);
|
||||
inbuf[3] = Swap(inbuf[3]);
|
||||
inbuf[4] = Swap(inbuf[4]);
|
||||
#endif
|
||||
|
||||
src = inbuf[1];
|
||||
seq = inbuf[2];
|
||||
intype = inbuf[3];
|
||||
inlen = inbuf[4];
|
||||
|
||||
Msgf((" [%d, %d, %d, %d] ", src, seq, intype, inlen));
|
||||
|
||||
if (intype == ACK_TYPE) {
|
||||
Msgf(("duplicate ack %d from %d ", seq, src));
|
||||
goto datrecv;
|
||||
}
|
||||
else if (inlen != incnt-HLEN) {
|
||||
Shout("Bad inlen in bsend, errno=%d", errno);
|
||||
goto datrecv;
|
||||
}
|
||||
else if (type == intype && seq == seqin[src] &&
|
||||
(*dest == src || *dest == LSV_ANY)) {
|
||||
if (*dest == LSV_ANY) {
|
||||
*dest = src;
|
||||
Msgf(("%d from %d ", seq, src));
|
||||
}
|
||||
send_ack(s, src, seq, &src_addr);
|
||||
if (inlen > sent) Error("Too much data\n");
|
||||
memcpy(inb, inbuf+HLEN/sizeof(int), inlen);
|
||||
seqin[src]++;
|
||||
return(inlen);
|
||||
} else {
|
||||
if (seq < seqin[src])
|
||||
Msgf(("ignore2 %d from %d ", seq, src));
|
||||
else if (chk_defer(src, intype, seq) > -1)
|
||||
Msgf(("ignore3 %d from %d ", seq, src));
|
||||
else if (src != *dest || type != intype || seq != seqin[src]) {
|
||||
msgbuf[msgcnt] = Malloc((incnt+8)&~07);
|
||||
memcpy(msgbuf[msgcnt], inbuf, incnt);
|
||||
msgcnt++;
|
||||
if (msgcnt >= MAXDEFER) Error("msgcnt too large\n");
|
||||
Msgf(("defer %d (%d) seqin[%d]=%d ", seq, intype, src, seqin[src]));
|
||||
}
|
||||
send_ack(s, src, seq, &src_addr);
|
||||
goto datrecv;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
chk_defer(int src, int type, int seq)
|
||||
{
|
||||
int i, insrc, inseq, intype;
|
||||
|
||||
Msgf(("chk_defer(src=%d, type=%d, seq=%d)\n", src, type, seq));
|
||||
for (i = 0; i < msgcnt; i++) {
|
||||
insrc = *(int *)(msgbuf[i]+sizeof(int));
|
||||
inseq = *(int *)(msgbuf[i]+2*sizeof(int));
|
||||
intype = *(int *)(msgbuf[i]+3*sizeof(int));
|
||||
if (src == insrc && type == intype && seq == inseq){
|
||||
Msgf(("deferred match: msgbuf[%d]\n", i));
|
||||
return(i);
|
||||
}
|
||||
}
|
||||
Msgf(("no match\n"));
|
||||
return(-1);
|
||||
}
|
||||
|
||||
static int
|
||||
chk_deferw(int type, int *src)
|
||||
{
|
||||
int i, insrc, inseq, intype;
|
||||
|
||||
for (i = 0; i < msgcnt; i++) {
|
||||
insrc = *(int *)(msgbuf[i]+sizeof(int));
|
||||
inseq = *(int *)(msgbuf[i]+2*sizeof(int));
|
||||
intype = *(int *)(msgbuf[i]+3*sizeof(int));
|
||||
if (type == intype && inseq == seqin[insrc]) {
|
||||
*src = insrc;
|
||||
return(i);
|
||||
}
|
||||
}
|
||||
return(-1);
|
||||
}
|
||||
|
||||
static void
|
||||
send_ack(int s, int dest, int seq, struct sockaddr_in *dest_addr)
|
||||
{
|
||||
int ack[HLEN/sizeof(int)];
|
||||
|
||||
ack[0] = Swap(H_MAGIC);
|
||||
ack[1] = Swap(LSV_procnum);
|
||||
ack[2] = Swap(seq);
|
||||
ack[3] = Swap(ACK_TYPE);
|
||||
ack[4] = Swap(0);
|
||||
if (sendto(s, (void *)ack, HLEN, 0, (struct sockaddr *)dest_addr,
|
||||
sizeof(struct sockaddr_in)) != HLEN)
|
||||
Warning("sendto, errno=%d", errno);
|
||||
else
|
||||
Msgf(("acked\n"));
|
||||
}
|
||||
|
||||
static void
|
||||
sock_init(struct sockaddr_in *acc, int bind_flag)
|
||||
{
|
||||
sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if( sock < 0 ){
|
||||
Error("socket failed, errno=%d\n", errno);
|
||||
}
|
||||
#ifdef SOCKBUF
|
||||
{
|
||||
int sockbuf;
|
||||
/* These appear not to be supported on the delta */
|
||||
sockbuf= SOCKBUF;
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &sockbuf, sizeof(int))) {
|
||||
SeriousWarning("sockopt sndbuf, errno=%d", errno);
|
||||
exit(1);
|
||||
}
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &sockbuf, sizeof(int))) {
|
||||
SeriousWarning("sockopt rcvbuf, errno=%d", errno);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (bind_flag) {
|
||||
int ret;
|
||||
int len = sizeof(struct sockaddr_in);
|
||||
char hostname[256];
|
||||
struct hostent *hp;
|
||||
char *p;
|
||||
|
||||
/* If we're being asked to do a 'bind', then that implies that
|
||||
we should fill in the sockaddr as well */
|
||||
memset(acc, 0, sizeof(struct sockaddr_in));
|
||||
acc->sin_family = AF_INET;
|
||||
acc->sin_addr.s_addr = INADDR_ANY;
|
||||
acc->sin_port = 0; /* INADDR_ANY? */
|
||||
ret = bind(sock,(struct sockaddr *)acc,sizeof(struct sockaddr_in));
|
||||
if (ret < 0 ) {
|
||||
Error("LSV: Can't bind socket. errno=%d\n",
|
||||
errno);
|
||||
}
|
||||
if( getsockname(sock, (struct sockaddr *)acc, &len) ){
|
||||
Error("LSV: Can't getsockname. errno=%d\n", errno);
|
||||
}
|
||||
|
||||
/* Unfortunately, getsockname doesn't replace INADDR_ANY
|
||||
with a valid saddr_in. We should be able to overrule
|
||||
gethostname with an env var or a cmd-line arg */
|
||||
if( (p = getenv("LSV_MYNAME")) ){
|
||||
strncpy(hostname, p, sizeof(hostname));
|
||||
}else{
|
||||
if( gethostname(hostname, sizeof(hostname)) )
|
||||
Error("gethostname failed, errno=%d\n", errno);
|
||||
}
|
||||
hostname[sizeof(hostname)-1] = '\0';
|
||||
if( (hp = gethostbyname(hostname)) == NULL )
|
||||
Error("gethostbyname(%s) failed\n", hostname);
|
||||
memcpy(&(acc->sin_addr), hp->h_addr, hp->h_length);
|
||||
|
||||
/* Now acc holds 'correct' info about the socket */
|
||||
Msgf(("Bound port %d\n", ntohs(acc->sin_port)));
|
||||
errno = 0; /* clear errors */
|
||||
}
|
||||
}
|
1067
external/libsdf/libsw/malloc.c
vendored
Normal file
1067
external/libsdf/libsw/malloc.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
63
external/libsdf/libsw/memfile.c
vendored
Normal file
63
external/libsdf/libsw/memfile.c
vendored
Normal file
|
@ -0,0 +1,63 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "Malloc.h"
|
||||
#include "Msgs.h"
|
||||
#include "error.h"
|
||||
#include "protos.h"
|
||||
#include "mpmy.h"
|
||||
|
||||
/* Here we try to implement a cicular memory buffer which we can use as */
|
||||
/* the vfprintf-like arg to Msg_init */
|
||||
|
||||
static char *memfile;
|
||||
static int memfile_offset;
|
||||
static int memfile_bufsz;
|
||||
|
||||
void
|
||||
memfile_init(int sz)
|
||||
{
|
||||
memfile = Malloc(sz);
|
||||
memfile_offset = 0;
|
||||
memfile_bufsz = sz-1;
|
||||
memfile[sz-1] = 0; /* final null to make wrapped output cleaner */
|
||||
}
|
||||
|
||||
void
|
||||
memfile_delete(void)
|
||||
{
|
||||
Free(memfile);
|
||||
memfile_offset = 0;
|
||||
memfile_bufsz = 0;
|
||||
}
|
||||
|
||||
#define BUFSZ 1024
|
||||
|
||||
void
|
||||
memfile_vfprintf(void *junk, const char *fmt, va_list args)
|
||||
{
|
||||
char tbuf[BUFSZ]; /* This might overflow, but msgs should be small */
|
||||
int i, len;
|
||||
|
||||
vsprintf(tbuf, fmt, args);
|
||||
len = strlen(tbuf);
|
||||
if (len >= BUFSZ) Error("Buffer overflowed in mem_vfprintf\n");
|
||||
for (i = 0; i <= len; i++) {
|
||||
memfile[(memfile_offset+i)%memfile_bufsz] = tbuf[i];
|
||||
}
|
||||
memfile_offset += len;
|
||||
}
|
||||
|
||||
void
|
||||
PrintMemfile(void)
|
||||
{
|
||||
if (memfile_offset == 0) return;
|
||||
printf("----- Messages from procnum %d -----\n", MPMY_Procnum());
|
||||
if (memfile_offset < memfile_bufsz) {
|
||||
printf("%s\n", memfile);
|
||||
} else {
|
||||
printf("Buffer has wrapped\n");
|
||||
printf("%s\n%s\n", memfile+(memfile_offset+1)%memfile_bufsz,
|
||||
memfile);
|
||||
}
|
||||
fflush(stdout);
|
||||
}
|
41
external/libsdf/libsw/memmove.c
vendored
Normal file
41
external/libsdf/libsw/memmove.c
vendored
Normal file
|
@ -0,0 +1,41 @@
|
|||
#include <stddef.h>
|
||||
|
||||
void
|
||||
*memmove(void *s1, const void *s2, size_t n)
|
||||
{
|
||||
#if 0 /* Assume the caller knew this when he decided to use memmove */
|
||||
if ((char *)s1 >= (char *)s2 + n || (char *)s1 + n <= (char *)s2){
|
||||
return memcpy(s1, s2, n);
|
||||
}
|
||||
#endif
|
||||
if(((unsigned long)s1)%sizeof(int)==0 &&
|
||||
((unsigned long)s2)%sizeof(int)==0 &&
|
||||
n%sizeof(int)==0){
|
||||
/* Everything is alligned. We can use int assignment. */
|
||||
int *ip1 = s1;
|
||||
const int *ip2 = s2;
|
||||
n /= sizeof(int);
|
||||
if( ip1 < ip2 ){
|
||||
while(n--)
|
||||
*ip1++ = *ip2++;
|
||||
}else{
|
||||
ip2 += n;
|
||||
ip1 += n;
|
||||
while(n--)
|
||||
*--ip1 = *--ip2;
|
||||
}
|
||||
}else{
|
||||
char *cp1 = s1;
|
||||
const char *cp2 = s2;
|
||||
if(cp1 < cp2) {
|
||||
while(n--)
|
||||
*cp1++ = *cp2++;
|
||||
}else{
|
||||
cp2 += n;
|
||||
cp1 += n;
|
||||
while(n--)
|
||||
*--cp1 = *--cp2;
|
||||
}
|
||||
}
|
||||
return s1;
|
||||
}
|
56
external/libsdf/libsw/mpi_bcast.c
vendored
Normal file
56
external/libsdf/libsw/mpi_bcast.c
vendored
Normal file
|
@ -0,0 +1,56 @@
|
|||
#include "swampi.h"
|
||||
#include "Msgs.h"
|
||||
#include "gc.h" /* for ilog2 */
|
||||
#include "error.h"
|
||||
|
||||
#define TAG 4
|
||||
|
||||
int
|
||||
MPI_Bcast(void *buf, int count, MPI_Datatype type, int srcproc, MPI_Comm comm)
|
||||
{
|
||||
int chan;
|
||||
int doc;
|
||||
int sendproc;
|
||||
int ret;
|
||||
MPI_Request rreq, sreq;
|
||||
MPI_Status status;
|
||||
int procnum = _MPI_Procnum;
|
||||
int nproc = _MPI_Nproc;
|
||||
int nbytes = _MPI_Datasize[type] * count;
|
||||
|
||||
Msgf(("mpi: Bcast\n"));
|
||||
if (srcproc != 0) { /* Is this stupid? */
|
||||
if (_MPI_Procnum == 0) {
|
||||
MPI_Irecv(buf, nbytes, MPI_BYTE, srcproc, TAG, MPI_COMM_PRIVATE,
|
||||
&rreq);
|
||||
MPI_Wait(&rreq, &status);
|
||||
MPI_Get_count(&status, MPI_BYTE, &ret);
|
||||
if (ret != nbytes) Error("Bcast got wrong len\n");
|
||||
} else if (_MPI_Procnum == srcproc) {
|
||||
MPI_Isend(buf, nbytes, MPI_BYTE, 0, TAG, MPI_COMM_PRIVATE, &sreq);
|
||||
MPI_Wait(&sreq, 0);
|
||||
}
|
||||
}
|
||||
|
||||
doc = ilog2(nproc);
|
||||
if (nproc != 1 << doc)
|
||||
doc++; /* for non power-of-two sizes */
|
||||
|
||||
for (chan = 0; chan < doc; chan++) {
|
||||
sendproc = procnum ^ (1 << chan);
|
||||
if (sendproc >= 0 && sendproc < nproc) {
|
||||
if (procnum & (1 << chan)) {
|
||||
MPI_Irecv(buf, nbytes, MPI_BYTE, sendproc, TAG,
|
||||
MPI_COMM_PRIVATE, &rreq);
|
||||
MPI_Wait(&rreq, &status);
|
||||
MPI_Get_count(&status, MPI_BYTE, &ret);
|
||||
if (ret != nbytes) Error("Bcast got wrong len\n");
|
||||
} else {
|
||||
MPI_Isend(buf, nbytes, MPI_BYTE, sendproc, TAG,
|
||||
MPI_COMM_PRIVATE, &sreq);
|
||||
MPI_Wait(&sreq, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
return MPI_SUCCESS;
|
||||
}
|
378
external/libsdf/libsw/mpi_reduce.c
vendored
Normal file
378
external/libsdf/libsw/mpi_reduce.c
vendored
Normal file
|
@ -0,0 +1,378 @@
|
|||
#include <stdlib.h>
|
||||
#include "swampi.h"
|
||||
#include "stk.h"
|
||||
#include "gc.h"
|
||||
#include "Msgs.h"
|
||||
#include "error.h"
|
||||
|
||||
static int setup;
|
||||
static int mask;
|
||||
|
||||
static Stk cstk, outdata;
|
||||
|
||||
#define TAG 5
|
||||
|
||||
struct comb_st {
|
||||
void *recvbuf;
|
||||
int count;
|
||||
MPI_Datatype datatype;
|
||||
union{
|
||||
MPI_Op op;
|
||||
MPI_user_comb_func user_func;
|
||||
} u;
|
||||
};
|
||||
|
||||
/* This currently only works with one request outstanding at a time */
|
||||
|
||||
static int
|
||||
MPI_IreduceInit(MPI_Request *reqp)
|
||||
{
|
||||
StkInitEz(&cstk);
|
||||
StkInitEz(&outdata);
|
||||
setup = 1;
|
||||
mask = ~0;
|
||||
*reqp = 0;
|
||||
return MPI_SUCCESS;
|
||||
}
|
||||
|
||||
static int
|
||||
MPI_Ireduce(void *sendbuf, void *recvbuf, int count,
|
||||
MPI_Datatype datatype, MPI_Op op,
|
||||
MPI_Request req, MPI_Comm comm)
|
||||
{
|
||||
struct comb_st *combuf;
|
||||
int total_size;
|
||||
|
||||
if (setup == 0)
|
||||
Error("MPI_Ireduce with no call to MPI_IreduceInit\n");
|
||||
total_size = count * _MPI_Datasize[datatype];
|
||||
|
||||
StkPushData(&outdata, (void *)sendbuf, total_size);
|
||||
combuf = StkPush(&cstk, sizeof(struct comb_st));
|
||||
|
||||
combuf->recvbuf = recvbuf;
|
||||
combuf->count = count;
|
||||
combuf->datatype = datatype;
|
||||
combuf->u.op = op;
|
||||
|
||||
return MPI_SUCCESS;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int
|
||||
MPI_IreduceFunc(void *sendbuf, void *recvbuf, int size,
|
||||
void (*func)(void *, void *, void*),
|
||||
MPI_Request req)
|
||||
{
|
||||
struct comb_st *combuf;
|
||||
int total_size;
|
||||
|
||||
if (setup == 0)
|
||||
Error("MPI_Ireduce_func with no call to MPI_IreduceInit\n");
|
||||
total_size = size;
|
||||
|
||||
StkPushData(&outdata, (void *)sendbuf, total_size);
|
||||
combuf = StkPush(&cstk, sizeof(struct comb_st));
|
||||
|
||||
combuf->recvbuf = recvbuf;
|
||||
combuf->count = size;
|
||||
combuf->datatype = MPI_USER_DATA;
|
||||
combuf->u.user_func = func;
|
||||
|
||||
return MPI_SUCCESS;
|
||||
}
|
||||
|
||||
static int
|
||||
MPI_Setmask(unsigned int maskval)
|
||||
{
|
||||
mask = maskval;
|
||||
return MPI_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define ALIGN(n) ((n + _STK_DEFAULT_ALIGNMENT)&~_STK_DEFAULT_ALIGNMENT)
|
||||
|
||||
/* gcc with optimization will cause this to fail efence */
|
||||
#define Do_Op(outbuf, op, inbuf, type, cnt) \
|
||||
do{char *oend = (char *)outbuf + ALIGN(cnt*sizeof(type)); \
|
||||
char *iend = (char *)inbuf + ALIGN(cnt*sizeof(type)); \
|
||||
while (cnt--) { \
|
||||
*(type *)(outbuf) op *(type *)(inbuf); \
|
||||
(outbuf) = (char *)(outbuf) + sizeof(type); \
|
||||
(inbuf) = (char *)(inbuf) + sizeof(type); \
|
||||
} \
|
||||
outbuf = oend; \
|
||||
inbuf = iend; \
|
||||
}while(0)
|
||||
|
||||
|
||||
static void
|
||||
do_combine(void *inbuf, void *outbuf, int n, struct comb_st *manifest)
|
||||
{
|
||||
int i;
|
||||
int count;
|
||||
|
||||
for (i = 0; i < n; i++, manifest++) {
|
||||
count = manifest->count;
|
||||
if (count < 0) Error("Bad count in reduce\n");
|
||||
|
||||
Msgf(("mpi: reduce Op %s Datatype %s\n", mpi_op_name[manifest->u.op],
|
||||
mpi_datatype_name[manifest->datatype]));
|
||||
switch(manifest->datatype) {
|
||||
case MPI_FLOAT:
|
||||
#define Type float
|
||||
#include "mpi_template.c"
|
||||
#undef Type
|
||||
break;
|
||||
case MPI_DOUBLE:
|
||||
#define Type double
|
||||
#include "mpi_template.c"
|
||||
#undef Type
|
||||
break;
|
||||
case MPI_LONG_DOUBLE:
|
||||
#define Type double
|
||||
#include "mpi_template.c"
|
||||
#undef Type
|
||||
break;
|
||||
|
||||
#define BIT_OPS /* Turns on bitwise ops in mpi_template.c */
|
||||
case MPI_BYTE:
|
||||
case MPI_CHAR:
|
||||
#define Type char
|
||||
#include "mpi_template.c"
|
||||
#undef Type
|
||||
break;
|
||||
case MPI_SHORT:
|
||||
#define Type short
|
||||
#include "mpi_template.c"
|
||||
#undef Type
|
||||
break;
|
||||
case MPI_INT:
|
||||
#define Type int
|
||||
#include "mpi_template.c"
|
||||
#undef Type
|
||||
break;
|
||||
case MPI_LONG:
|
||||
#define Type long
|
||||
#include "mpi_template.c"
|
||||
#undef Type
|
||||
break;
|
||||
case MPI_LONG_LONG:
|
||||
#define Type long
|
||||
#include "mpi_template.c"
|
||||
#undef Type
|
||||
break;
|
||||
case MPI_UNSIGNED:
|
||||
case MPI_UNSIGNED_INT:
|
||||
#define Type unsigned int
|
||||
#include "mpi_template.c"
|
||||
#undef Type
|
||||
break;
|
||||
case MPI_UNSIGNED_CHAR:
|
||||
#define Type unsigned char
|
||||
#include "mpi_template.c"
|
||||
#undef Type
|
||||
break;
|
||||
case MPI_UNSIGNED_SHORT:
|
||||
#define Type unsigned short
|
||||
#include "mpi_template.c"
|
||||
#undef Type
|
||||
break;
|
||||
case MPI_UNSIGNED_LONG:
|
||||
#define Type unsigned long
|
||||
#include "mpi_template.c"
|
||||
#undef Type
|
||||
break;
|
||||
case MPI_UNSIGNED_LONG_LONG:
|
||||
#define Type unsigned long
|
||||
#include "mpi_template.c"
|
||||
#undef Type
|
||||
break;
|
||||
#undef BIT_OPS
|
||||
|
||||
#define LOC_OPS
|
||||
case MPI_FLOAT_INT:
|
||||
#define Type MPI_float_int
|
||||
#include "mpi_template.c"
|
||||
#undef Type
|
||||
break;
|
||||
case MPI_DOUBLE_INT:
|
||||
#define Type MPI_double_int
|
||||
#include "mpi_template.c"
|
||||
#undef Type
|
||||
break;
|
||||
case MPI_LONG_INT:
|
||||
#define Type MPI_long_int
|
||||
#include "mpi_template.c"
|
||||
#undef Type
|
||||
break;
|
||||
case MPI_2INT:
|
||||
#define Type MPI_2int
|
||||
#include "mpi_template.c"
|
||||
#undef Type
|
||||
break;
|
||||
case MPI_SHORT_INT:
|
||||
#define Type MPI_short_int
|
||||
#include "mpi_template.c"
|
||||
#undef Type
|
||||
break;
|
||||
case MPI_LONG_DOUBLE_INT:
|
||||
#define Type MPI_long_double_int
|
||||
#include "mpi_template.c"
|
||||
#undef Type
|
||||
break;
|
||||
#undef LOC_OPS
|
||||
case MPI_COMPLEX:
|
||||
#define Type MPI_complex
|
||||
{
|
||||
Type *out = outbuf;
|
||||
Type *in = inbuf;
|
||||
outbuf = (char *)outbuf + ALIGN(count*sizeof(Type));
|
||||
inbuf = (char *)inbuf + ALIGN(count*sizeof(Type));
|
||||
switch(manifest->u.op) {
|
||||
case MPI_SUM:
|
||||
while (count--) {
|
||||
out->real += in->real;
|
||||
out->imag += in->imag;
|
||||
out++;
|
||||
in++;
|
||||
}
|
||||
break;
|
||||
case MPI_PROD:
|
||||
while (count--) {
|
||||
out->real = out->real*in->real - out->imag*in->imag;
|
||||
out->imag = out->real*in->imag + out->imag*in->real;
|
||||
out++;
|
||||
in++;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Error("Unknown op in MPI_reduce\n");
|
||||
}
|
||||
}
|
||||
#undef Type
|
||||
break;
|
||||
case MPI_DOUBLE_COMPLEX:
|
||||
#define Type MPI_double_complex
|
||||
{
|
||||
Type *out = outbuf;
|
||||
Type *in = inbuf;
|
||||
outbuf = (char *)outbuf + ALIGN(count*sizeof(Type));
|
||||
inbuf = (char *)inbuf + ALIGN(count*sizeof(Type));
|
||||
switch(manifest->u.op) {
|
||||
case MPI_SUM:
|
||||
while (count--) {
|
||||
out->real += in->real;
|
||||
out->imag += in->imag;
|
||||
out++;
|
||||
in++;
|
||||
}
|
||||
break;
|
||||
case MPI_PROD:
|
||||
while (count--) {
|
||||
out->real = out->real*in->real - out->imag*in->imag;
|
||||
out->imag = out->real*in->imag + out->imag*in->real;
|
||||
out++;
|
||||
in++;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Error("Unknown op in MPI_reduce\n");
|
||||
}
|
||||
}
|
||||
#undef Type
|
||||
break;
|
||||
case MPI_USER_DATA:
|
||||
/* This came from a MPI_ICombine_func */
|
||||
(*manifest->u.user_func)(inbuf, outbuf, outbuf);
|
||||
(outbuf) = (char *)(outbuf) + ALIGN(manifest->count);
|
||||
(inbuf) = (char *)(inbuf) + ALIGN(manifest->count);
|
||||
break;
|
||||
default:
|
||||
Error("Unknown type in Combine\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
MPI_IreduceWait(MPI_Request req, MPI_Comm comm)
|
||||
{
|
||||
int chan;
|
||||
int doc;
|
||||
int i;
|
||||
void *inbuf;
|
||||
void *outbuf = StkBase(&outdata);
|
||||
MPI_Status stat;
|
||||
int ret;
|
||||
int total_size;
|
||||
int sendproc;
|
||||
int procnum = _MPI_Procnum;
|
||||
int nproc = _MPI_Nproc;
|
||||
int bufsz = StkSz(&outdata);
|
||||
struct comb_st *manifest = StkBase(&cstk);
|
||||
int n = StkSz(&cstk)/sizeof(struct comb_st);
|
||||
|
||||
doc = ilog2(nproc);
|
||||
if (nproc != 1 << doc)
|
||||
doc++; /* for non power-of-two sizes */
|
||||
if ((inbuf = malloc(bufsz)) == NULL)
|
||||
Error("out of memory\n");
|
||||
|
||||
for (chan = 0; chan < doc; chan++) {
|
||||
if (mask & (1 << chan)) {
|
||||
sendproc = procnum^(1<<chan);
|
||||
if (sendproc >= 0 && sendproc < nproc) {
|
||||
MPI_Sendrecv(outbuf, bufsz, MPI_BYTE, sendproc, TAG,
|
||||
inbuf, bufsz, MPI_BYTE, sendproc, TAG,
|
||||
comm, &stat);
|
||||
MPI_Get_count(&stat, MPI_BYTE, &ret);
|
||||
if (ret != bufsz)
|
||||
Error("Shift failed, expected %d got %d\n", bufsz, ret);
|
||||
do_combine(inbuf, outbuf, n, manifest);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nproc != 1 << doc) {
|
||||
MPI_Bcast(outbuf, bufsz, MPI_BYTE, 0, comm);
|
||||
}
|
||||
for (i = 0; i < n; i++) {
|
||||
total_size = manifest->count * _MPI_Datasize[manifest->datatype];
|
||||
memcpy(manifest->recvbuf, outbuf, total_size);
|
||||
outbuf = (char *)outbuf + ALIGN(total_size);
|
||||
manifest = (struct comb_st *)((char *)manifest + ALIGN(sizeof(*manifest)));
|
||||
}
|
||||
free(inbuf);
|
||||
StkTerminate(&outdata);
|
||||
StkTerminate(&cstk);
|
||||
setup = 0;
|
||||
return MPI_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
MPI_Allreduce(void *sendbuf, void *recvbuf, int count,
|
||||
MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
|
||||
{
|
||||
MPI_Request req;
|
||||
|
||||
Msgf(("mpi: Allreduce\n"));
|
||||
if (op < 0 || op >= _MPI_NUMOPS) Error("Bad MPI_Op\n");
|
||||
MPI_IreduceInit(&req);
|
||||
MPI_Ireduce(sendbuf, recvbuf, count, datatype, op, req, MPI_COMM_PRIVATE);
|
||||
MPI_IreduceWait(req, MPI_COMM_PRIVATE);
|
||||
return MPI_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
MPI_Reduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype,
|
||||
MPI_Op op, int root, MPI_Comm comm)
|
||||
{
|
||||
Msgf(("mpi: Reduce\n"));
|
||||
if (op < 0 || op >= _MPI_NUMOPS) Error("Bad MPI_Op\n");
|
||||
if (_MPI_Procnum != root)
|
||||
if ((recvbuf = malloc(count * _MPI_Datasize[datatype])) == NULL)
|
||||
Error("out of memory\n");
|
||||
MPI_Allreduce(sendbuf, recvbuf, count, datatype, op, comm);
|
||||
if (_MPI_Procnum != root) free(recvbuf);
|
||||
return MPI_SUCCESS;
|
||||
}
|
||||
|
66
external/libsdf/libsw/mpi_template.c
vendored
Normal file
66
external/libsdf/libsw/mpi_template.c
vendored
Normal file
|
@ -0,0 +1,66 @@
|
|||
|
||||
/* This is a template that is included multiple times in MPI_reduce.c */
|
||||
|
||||
switch(manifest->u.op) {
|
||||
#ifndef LOC_OPS
|
||||
case MPI_SUM:
|
||||
Do_Op(outbuf, +=, inbuf, Type, count);
|
||||
break;
|
||||
case MPI_PROD:
|
||||
Do_Op(outbuf, *=, inbuf, Type, count);
|
||||
break;
|
||||
case MPI_MAX:
|
||||
Do_Op(outbuf,
|
||||
= (*(Type *)outbuf > *(Type *)inbuf) ? *(Type *)outbuf :,
|
||||
inbuf, Type, count);
|
||||
break;
|
||||
case MPI_MIN:
|
||||
Do_Op(outbuf,
|
||||
= (*(Type *)outbuf < *(Type *)inbuf) ? *(Type *)outbuf :,
|
||||
inbuf, Type, count);
|
||||
break;
|
||||
#ifdef BIT_OPS
|
||||
case MPI_BAND:
|
||||
Do_Op(outbuf, &=, inbuf, Type, count);
|
||||
break;
|
||||
case MPI_BOR:
|
||||
Do_Op(outbuf, |=, inbuf, Type, count);
|
||||
break;
|
||||
case MPI_BXOR:
|
||||
Do_Op(outbuf, ^=, inbuf, Type, count);
|
||||
break;
|
||||
case MPI_LAND:
|
||||
Do_Op(outbuf, = *(Type *)outbuf && , inbuf, Type, count);
|
||||
break;
|
||||
case MPI_LOR:
|
||||
Do_Op(outbuf, = *(Type *)outbuf || , inbuf, Type, count);
|
||||
break;
|
||||
case MPI_LXOR: /* cripes */
|
||||
Do_Op(outbuf, = (!*(Type *)outbuf == !*(Type *)inbuf) ?
|
||||
0 : 1 ||, inbuf, Type, count);
|
||||
break;
|
||||
#endif /*BIT_OPS */
|
||||
#else /* LOC_OPS */
|
||||
case MPI_MAXLOC:
|
||||
Do_Op(outbuf, = (((Type *)outbuf)->x > ((Type *)inbuf)->x) ?
|
||||
*(Type *)outbuf :, inbuf, Type, count);
|
||||
break;
|
||||
case MPI_MINLOC:
|
||||
Do_Op(outbuf, = (((Type *)outbuf)->x < ((Type *)inbuf)->x) ?
|
||||
*(Type *)outbuf :, inbuf, Type, count);
|
||||
break;
|
||||
#endif /* LOC_OPS */
|
||||
default:
|
||||
Error("Unknown op in MPI_reduce\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
252
external/libsdf/libsw/mpmy_combine.c
vendored
Normal file
252
external/libsdf/libsw/mpmy_combine.c
vendored
Normal file
|
@ -0,0 +1,252 @@
|
|||
#include <sys/types.h>
|
||||
#include "Malloc.h"
|
||||
#include "mpmy.h"
|
||||
#include "stk.h"
|
||||
#include "gc.h"
|
||||
#include "Msgs.h"
|
||||
|
||||
static int setup;
|
||||
static int mask;
|
||||
|
||||
static Stk cstk, outdata;
|
||||
|
||||
struct comb_st {
|
||||
void *recvbuf;
|
||||
int count;
|
||||
int datatype;
|
||||
union{
|
||||
MPMY_Op op;
|
||||
MPMY_user_comb_func user_func;
|
||||
} u;
|
||||
};
|
||||
|
||||
/* This currently only works with one request outstanding at a time */
|
||||
|
||||
int
|
||||
MPMY_ICombine_Init(MPMY_Comm_request *reqp)
|
||||
{
|
||||
StkInitEz(&cstk);
|
||||
StkInitEz(&outdata);
|
||||
setup = 1;
|
||||
mask = ~0;
|
||||
*reqp = 0;
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
MPMY_ICombine(const void *sendbuf, void *recvbuf, int count,
|
||||
MPMY_Datatype datatype, MPMY_Op op,
|
||||
MPMY_Comm_request req)
|
||||
{
|
||||
struct comb_st *combuf;
|
||||
int total_size;
|
||||
|
||||
if (setup == 0)
|
||||
Error("MPMY_ICombine with no call to Init\n");
|
||||
total_size = count * MPMY_Datasize[datatype];
|
||||
|
||||
StkPushData(&outdata, (void *)sendbuf, total_size);
|
||||
combuf = StkPush(&cstk, sizeof(struct comb_st));
|
||||
|
||||
combuf->recvbuf = recvbuf;
|
||||
combuf->count = count;
|
||||
combuf->datatype = datatype;
|
||||
combuf->u.op = op;
|
||||
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
MPMY_ICombine_func(const void *sendbuf, void *recvbuf, int size,
|
||||
void (*func)(const void *, const void *, void*),
|
||||
MPMY_Comm_request req)
|
||||
{
|
||||
struct comb_st *combuf;
|
||||
int total_size;
|
||||
|
||||
Msgf(("MPMY_Icombine_func(): %p %p %d %p\n",
|
||||
sendbuf, recvbuf, size, func));
|
||||
if (setup == 0)
|
||||
Error("MPMY_ICombine with no call to Init\n");
|
||||
total_size = size;
|
||||
|
||||
StkPushData(&outdata, (void *)sendbuf, total_size);
|
||||
combuf = StkPush(&cstk, sizeof(struct comb_st));
|
||||
|
||||
combuf->recvbuf = recvbuf;
|
||||
combuf->count = size;
|
||||
combuf->datatype = MPMY_USER_DATA;
|
||||
combuf->u.user_func = func;
|
||||
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
MPMY_Combine_Mask(unsigned int maskval)
|
||||
{
|
||||
mask = maskval;
|
||||
}
|
||||
|
||||
|
||||
/* gcc with optimization will cause this to fail efence */
|
||||
#define Do_Op(outbuf, op, inbuf, type, cnt) \
|
||||
do{char *oend = (char *)outbuf + StkAlign(&outdata, cnt*sizeof(type)); \
|
||||
char *iend = (char *)inbuf + StkAlign(&outdata, cnt*sizeof(type)); \
|
||||
while (cnt--) { \
|
||||
*(type *)(outbuf) op *(type *)(inbuf); \
|
||||
(outbuf) = (char *)(outbuf) + sizeof(type); \
|
||||
(inbuf) = (char *)(inbuf) + sizeof(type); \
|
||||
} \
|
||||
outbuf = oend; \
|
||||
inbuf = iend; \
|
||||
}while(0)
|
||||
|
||||
|
||||
static void
|
||||
do_combine(const void *inbuf, void *outbuf, const int n,
|
||||
const struct comb_st *manifest)
|
||||
{
|
||||
int i;
|
||||
int count;
|
||||
|
||||
for (i = 0; i < n; i++, manifest++) {
|
||||
count = manifest->count;
|
||||
if (count < 0) Error("Bad count in Combine\n");
|
||||
Msgf(("do_combine: %p %p %d %d\n",
|
||||
inbuf, outbuf, manifest->datatype, manifest->u.op));
|
||||
switch(manifest->datatype) {
|
||||
case MPMY_FLOAT:
|
||||
#define Type float
|
||||
#include "op_template.c"
|
||||
#undef Type
|
||||
break;
|
||||
case MPMY_DOUBLE:
|
||||
#define Type double
|
||||
#include "op_template.c"
|
||||
#undef Type
|
||||
break;
|
||||
case MPMY_INT:
|
||||
#define BIT_OPS /* Turns on bitwise ops in op_template.c */
|
||||
#define Type int
|
||||
#include "op_template.c"
|
||||
#undef Type
|
||||
break;
|
||||
case MPMY_CHAR:
|
||||
#define Type char
|
||||
#include "op_template.c"
|
||||
#undef Type
|
||||
break;
|
||||
case MPMY_SHORT:
|
||||
#define Type short
|
||||
#include "op_template.c"
|
||||
#undef Type
|
||||
break;
|
||||
case MPMY_LONG:
|
||||
#define Type long
|
||||
#include "op_template.c"
|
||||
#undef Type
|
||||
case MPMY_OFFT:
|
||||
#define Type off_t
|
||||
#include "op_template.c"
|
||||
#undef Type
|
||||
break;
|
||||
case MPMY_INT64:
|
||||
#define Type int64_t
|
||||
#include "op_template.c"
|
||||
#undef Type
|
||||
break;
|
||||
case MPMY_UNSIGNED_INT:
|
||||
#define Type unsigned int
|
||||
#include "op_template.c"
|
||||
#undef Type
|
||||
break;
|
||||
case MPMY_UNSIGNED_CHAR:
|
||||
#define Type unsigned char
|
||||
#include "op_template.c"
|
||||
#undef Type
|
||||
break;
|
||||
case MPMY_UNSIGNED_SHORT:
|
||||
#define Type unsigned short
|
||||
#include "op_template.c"
|
||||
#undef Type
|
||||
break;
|
||||
case MPMY_UNSIGNED_LONG:
|
||||
#define Type unsigned long
|
||||
#include "op_template.c"
|
||||
#undef Type
|
||||
break;
|
||||
#undef BIT_OPS
|
||||
case MPMY_USER_DATA:
|
||||
/* This came from a MPMY_ICombine_func */
|
||||
(*manifest->u.user_func)(inbuf, outbuf, outbuf);
|
||||
(outbuf) = (char *)(outbuf) + StkAlign(&outdata, manifest->count);
|
||||
(inbuf) = (char *)(inbuf) + StkAlign(&outdata, manifest->count);
|
||||
break;
|
||||
default:
|
||||
Error("Unknown type in Combine\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
MPMY_ICombine_Wait(MPMY_Comm_request req)
|
||||
{
|
||||
int chan;
|
||||
int doc;
|
||||
int i;
|
||||
void *inbuf;
|
||||
void *outbuf = StkBase(&outdata);
|
||||
MPMY_Status stat;
|
||||
int ret;
|
||||
int total_size;
|
||||
int sendproc;
|
||||
int procnum = MPMY_Procnum();
|
||||
int nproc = MPMY_Nproc();
|
||||
int bufsz = StkSz(&outdata);
|
||||
const struct comb_st *manifest = StkBase(&cstk);
|
||||
int n = StkSz(&cstk)/sizeof(struct comb_st);
|
||||
|
||||
Msgf(("MPMY_ICombine_Wait()\n"));
|
||||
doc = ilog2(nproc);
|
||||
if (nproc != 1 << doc)
|
||||
doc++; /* for non power-of-two sizes */
|
||||
inbuf = Malloc(bufsz);
|
||||
|
||||
for (chan = 0; chan < doc; chan++) {
|
||||
if (mask & (1 << chan)) {
|
||||
sendproc = procnum^(1<<chan);
|
||||
if (sendproc >= 0 && sendproc < nproc) {
|
||||
MPMY_Shift(sendproc, inbuf, bufsz, outbuf, bufsz, &stat);
|
||||
ret = MPMY_Count(&stat);
|
||||
if (ret != bufsz)
|
||||
Error("Shift failed, expected %d got %d\n", bufsz, ret);
|
||||
do_combine(inbuf, outbuf, n, manifest);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nproc != 1 << doc) {
|
||||
MPMY_Bcast(outbuf, bufsz, MPMY_CHAR, 0);
|
||||
}
|
||||
for (i = 0; i < n; i++) {
|
||||
total_size = manifest->count * MPMY_Datasize[manifest->datatype];
|
||||
memcpy(manifest->recvbuf, outbuf, total_size);
|
||||
outbuf = (char *)outbuf + StkAlign(&outdata, total_size);
|
||||
manifest = (const struct comb_st *)((char *)manifest + StkAlign(&outdata, sizeof(*manifest)));
|
||||
}
|
||||
Free(inbuf);
|
||||
StkTerminate(&outdata);
|
||||
StkTerminate(&cstk);
|
||||
setup = 0;
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
MPMY_Combine(const void *sendbuf, void *recvbuf, const int count,
|
||||
const MPMY_Datatype datatype, const MPMY_Op op)
|
||||
{
|
||||
MPMY_Comm_request req;
|
||||
|
||||
MPMY_ICombine_Init(&req);
|
||||
MPMY_ICombine(sendbuf, recvbuf, count, datatype, op, req);
|
||||
return MPMY_ICombine_Wait(req);
|
||||
}
|
556
external/libsdf/libsw/mpmy_gather.c
vendored
Normal file
556
external/libsdf/libsw/mpmy_gather.c
vendored
Normal file
|
@ -0,0 +1,556 @@
|
|||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include "mpmy.h"
|
||||
#include "Msgs.h"
|
||||
#include "Malloc.h"
|
||||
#include "gc.h" /* for ilog2 */
|
||||
#include "verify.h"
|
||||
|
||||
/* Could we implement gather using MPMY_Combine with MPMY_Op == MPMY_GATHER? */
|
||||
|
||||
|
||||
#define BCAST_DEFAULT_TAG 0x47
|
||||
|
||||
#define GATHER_BCAST_TAG 0x1145
|
||||
#define GATHER_TAG 0x2145
|
||||
#define NGATHER_TAG 0x3145
|
||||
#define ALLTOALL_TAG 0x4145
|
||||
#define ALLTOALL_RTAG 0x4146
|
||||
#define ALLTOALL_NTAG 0x4147
|
||||
|
||||
unsigned int MPMY_Datasize[] =
|
||||
{ sizeof(float), sizeof(double), sizeof(int), sizeof(char), sizeof(short),
|
||||
sizeof(long), sizeof(unsigned int), sizeof(unsigned char),
|
||||
sizeof(unsigned short), sizeof(unsigned long), sizeof(off_t), sizeof(int64_t), 1/*user_data*/
|
||||
};
|
||||
|
||||
void
|
||||
MPMY_send(const void *buf, int cnt, int dest, int tag)
|
||||
{
|
||||
MPMY_Comm_request req;
|
||||
|
||||
MPMY_Isend(buf, cnt, dest, tag, &req);
|
||||
MPMY_Wait(req, 0);
|
||||
if( Msg_test(__FILE__)){
|
||||
int i;
|
||||
int sum = 0;
|
||||
const char *cbuf = buf;
|
||||
for(i=0; i<cnt; i++){
|
||||
sum ^= cbuf[i];
|
||||
}
|
||||
Msg_do("mpmy_gather: send(cnt=%d, dest=%d, tag=%d), sum=%d\n",
|
||||
cnt, dest, tag, sum);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
MPMY_recvn(void *buf, int cnt, int src, int tag)
|
||||
{
|
||||
MPMY_Status stat;
|
||||
MPMY_Comm_request req;
|
||||
|
||||
Verify(MPMY_Irecv(buf, cnt, src, tag, &req)==MPMY_SUCCESS);
|
||||
Verify(MPMY_Wait(req, &stat)==MPMY_SUCCESS);
|
||||
if (MPMY_Count(&stat) != cnt)
|
||||
Error("Recv failed, expected %d got %d\n", cnt, MPMY_Count(&stat));
|
||||
if( Msg_test(__FILE__)){
|
||||
int i;
|
||||
int sum = 0;
|
||||
char *cbuf = buf;
|
||||
for(i=0; i<cnt; i++){
|
||||
sum ^= cbuf[i];
|
||||
}
|
||||
Msg_do("mpmy_gather: recvn(cnt=%d, dest=%d, tag=%d), sum=%d\n",
|
||||
cnt, src, tag, sum);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
MPMY_AllGather(const void *sendbuf, int count, MPMY_Datatype type,
|
||||
void *recvbuf)
|
||||
{
|
||||
int chan;
|
||||
int doc;
|
||||
MPMY_Status stat;
|
||||
int sendproc;
|
||||
int bufsz;
|
||||
unsigned int mask;
|
||||
int ret;
|
||||
void *inptr;
|
||||
const void *outptr;
|
||||
int procnum = MPMY_Procnum();
|
||||
int nproc = MPMY_Nproc();
|
||||
int nbytes = MPMY_Datasize[type] * count;
|
||||
|
||||
doc = ilog2(nproc);
|
||||
if (nproc != 1 << doc) { /* for non power-of-two sizes */
|
||||
MPMY_Gather(sendbuf, count, type, recvbuf, 0);
|
||||
MPMY_BcastTag(recvbuf, nproc*count, type, 0, GATHER_BCAST_TAG);
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
|
||||
inptr = (char *)recvbuf + procnum * nbytes;
|
||||
outptr = sendbuf;
|
||||
|
||||
/* Self contribution */
|
||||
if (inptr != outptr)
|
||||
memcpy(inptr, outptr, nbytes);
|
||||
|
||||
mask = ~0;
|
||||
for (chan = 0; chan < doc; chan++) {
|
||||
sendproc = procnum ^ (1 << chan);
|
||||
bufsz = (1 << chan) * nbytes;
|
||||
inptr = (char *)recvbuf + (sendproc & mask) * nbytes;
|
||||
outptr = (char *)recvbuf + (procnum & mask) * nbytes;
|
||||
MPMY_Shift(sendproc, inptr, bufsz, outptr, bufsz, &stat);
|
||||
ret = MPMY_Count(&stat);
|
||||
if (ret != bufsz)
|
||||
Error("Shift failed, expected %d got %d\n", bufsz, ret);
|
||||
mask <<= 1;
|
||||
}
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
MPMY_Gather(const void *sendbuf, int count, MPMY_Datatype type, void *recvbuf,
|
||||
int recvproc)
|
||||
{
|
||||
int chan;
|
||||
int doc;
|
||||
int sendproc;
|
||||
int inbufsz, outbufsz;
|
||||
int nin, nout;
|
||||
unsigned int mask;
|
||||
void *inptr;
|
||||
const void *outptr;
|
||||
int procnum = MPMY_Procnum();
|
||||
int nproc = MPMY_Nproc();
|
||||
int nbytes = MPMY_Datasize[type] * count;
|
||||
|
||||
if (recvproc != 0) Error("Gather to procnum != 0 not supported yet.\n");
|
||||
|
||||
doc = ilog2(nproc);
|
||||
if (nproc != 1 << doc)
|
||||
doc++; /* for non power-of-two sizes */
|
||||
|
||||
if (procnum != recvproc)
|
||||
recvbuf = Malloc(nproc*nbytes); /* overkill */
|
||||
|
||||
inptr = (char *)recvbuf + procnum * nbytes;
|
||||
outptr = sendbuf;
|
||||
if (inptr != outptr) memcpy(inptr, outptr, nbytes);
|
||||
|
||||
mask = ~0;
|
||||
for (chan = 0; chan < doc; chan++) {
|
||||
sendproc = procnum ^ (1 << chan);
|
||||
if (sendproc >= 0 && sendproc < nproc) {
|
||||
nin = nout = (1 << chan);
|
||||
if (procnum & (1 << chan)) {
|
||||
if (nproc - procnum < nout) nout = nproc - procnum;
|
||||
outbufsz = nout * nbytes;
|
||||
outptr = (char *)recvbuf + (procnum & mask) * nbytes;
|
||||
Msgf(("Gather: to %d, outidx %d, outsz %d\n",
|
||||
sendproc, (procnum & mask), nout));
|
||||
MPMY_send(outptr, outbufsz, sendproc, GATHER_TAG+chan);
|
||||
break;
|
||||
} else {
|
||||
if (nproc - sendproc < nin) nin = nproc - sendproc;
|
||||
inbufsz = nin * nbytes;
|
||||
inptr = (char *)recvbuf + (sendproc & mask) * nbytes;
|
||||
Msgf(("Gather: from %d, inidx %d, insz %d\n",
|
||||
sendproc, (sendproc & mask), nin));
|
||||
MPMY_recvn(inptr, inbufsz, sendproc, GATHER_TAG+chan);
|
||||
}
|
||||
}
|
||||
mask <<= 1;
|
||||
}
|
||||
if (procnum != recvproc)
|
||||
Free(recvbuf);
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
|
||||
/* "count" can vary for each processor in NGather */
|
||||
|
||||
int
|
||||
MPMY_NGather(const void *sendbuf, int count, MPMY_Datatype type,
|
||||
void **recvhndl, int recvproc)
|
||||
{
|
||||
int chan;
|
||||
int doc;
|
||||
int sendproc;
|
||||
int bufsz;
|
||||
int inbytes;
|
||||
unsigned int mask;
|
||||
void *buf;
|
||||
int procnum = MPMY_Procnum();
|
||||
int nproc = MPMY_Nproc();
|
||||
int nbytes = MPMY_Datasize[type] * count;
|
||||
|
||||
if (recvproc != 0) Error("NGather to procnum != 0 not supported yet.\n");
|
||||
|
||||
doc = ilog2(nproc);
|
||||
if (nproc != 1 << doc)
|
||||
doc++; /* for non power-of-two sizes */
|
||||
|
||||
buf = Malloc(nbytes);
|
||||
memcpy(buf, sendbuf, nbytes);
|
||||
bufsz = nbytes;
|
||||
|
||||
mask = ~0;
|
||||
for (chan = 0; chan < doc; chan++) {
|
||||
sendproc = procnum ^ (1 << chan);
|
||||
if (sendproc >= 0 && sendproc < nproc) {
|
||||
if (procnum & (1 << chan)) {
|
||||
Msgf(("NGather: to %d, bufsz %d\n", sendproc, bufsz));
|
||||
MPMY_send(&bufsz, sizeof(int), sendproc, NGATHER_TAG+chan);
|
||||
MPMY_send(buf, bufsz, sendproc, NGATHER_TAG+chan);
|
||||
break;
|
||||
} else {
|
||||
MPMY_recvn(&inbytes, sizeof(int), sendproc, NGATHER_TAG+chan);
|
||||
Msgf(("NGather: from %d, inbytes %d\n", sendproc, inbytes));
|
||||
buf = Realloc(buf, bufsz+inbytes);
|
||||
MPMY_recvn(bufsz+(char*)buf, inbytes, sendproc, NGATHER_TAG+chan);
|
||||
bufsz += inbytes;
|
||||
}
|
||||
}
|
||||
mask <<= 1;
|
||||
}
|
||||
if (procnum != recvproc) {
|
||||
Free(buf);
|
||||
return 0;
|
||||
} else {
|
||||
Msgf(("NGather: Final bufsz %d\n", bufsz));
|
||||
*recvhndl = buf;
|
||||
return bufsz/MPMY_Datasize[type];
|
||||
}
|
||||
}
|
||||
|
||||
int MPMY_Bcast(void *buf, int count, MPMY_Datatype type, int srcproc)
|
||||
{
|
||||
return MPMY_BcastTag(buf, count, type, srcproc, BCAST_DEFAULT_TAG);
|
||||
}
|
||||
|
||||
int
|
||||
MPMY_BcastTag(void *buf, int count, MPMY_Datatype type, int srcproc, int tag)
|
||||
{
|
||||
int chan;
|
||||
int doc;
|
||||
int sendproc;
|
||||
int procnum = MPMY_Procnum();
|
||||
int nproc = MPMY_Nproc();
|
||||
int nbytes = MPMY_Datasize[type] * count;
|
||||
|
||||
if (srcproc != 0) Error("Bcast from procnum != 0 not supported yet.\n");
|
||||
|
||||
Msgf(("MPMYBcast(buf=%p, count=%d, type=%d, srcproc=%d\n",
|
||||
buf, count, type, srcproc)); Msg_flush();
|
||||
doc = ilog2(nproc);
|
||||
if (nproc != 1 << doc)
|
||||
doc++; /* for non power-of-two sizes */
|
||||
|
||||
for (chan = 0; chan < doc; chan++) {
|
||||
sendproc = procnum ^ (1 << chan);
|
||||
if (sendproc >= 0 && sendproc < nproc) {
|
||||
if (procnum & (1 << chan)) {
|
||||
Msgf(("Bcast: recv from %d\n", sendproc));
|
||||
MPMY_recvn(buf, nbytes, sendproc, tag+chan);
|
||||
} else {
|
||||
Msgf(("Bcast: send to %d\n", sendproc));
|
||||
MPMY_send(buf, nbytes, sendproc, tag+chan);
|
||||
}
|
||||
}
|
||||
}
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
MPMY_Alltoall(void *sendbuf, int sendcount, MPMY_Datatype sendtype,
|
||||
void *recvbuf, int recvcount, MPMY_Datatype recvtype)
|
||||
{
|
||||
MPMY_Status stat;
|
||||
int i;
|
||||
int ret;
|
||||
int doc_procs, doc_nodes, relative, dest, proc;
|
||||
int sendbytes = MPMY_Datasize[sendtype] * sendcount;
|
||||
int recvbytes = MPMY_Datasize[recvtype] * recvcount;
|
||||
int my_node = MPMY_Procnum() / PROCS_PER_NODE;
|
||||
int my_leader = my_node * PROCS_PER_NODE;
|
||||
int local_rank = MPMY_Procnum() % PROCS_PER_NODE;
|
||||
int dest_leader;
|
||||
char *tmpbuf_s = NULL;
|
||||
char *tmpbuf_r = NULL;
|
||||
MPMY_Comm_request req;
|
||||
|
||||
doc_nodes = ilog2(MPMY_Nproc()/PROCS_PER_NODE-1) + 1;
|
||||
doc_procs = ilog2(PROCS_PER_NODE-1) + 1;
|
||||
Msgf(("Alltoall my_leader %d, local_rank %d, doc_nodes %d, doc_procs %d\n",
|
||||
my_leader, local_rank, doc_nodes, doc_procs));
|
||||
/* Within a node */
|
||||
for (relative = 0; relative < 1 << doc_procs; relative++) {
|
||||
dest = my_leader + (relative ^ local_rank);
|
||||
if ((dest >= MPMY_Nproc()) || (dest >= my_leader + PROCS_PER_NODE))
|
||||
continue;
|
||||
Msgf(("local Alltoall MPMY_Shift(dest=%d, instart=%p, incnt=%d, outstart=%p, outcnt=%d)\n",
|
||||
dest, recvbuf + dest * recvbytes, recvbytes,
|
||||
sendbuf + dest * sendbytes, sendbytes));
|
||||
MPMY_Shift(dest, recvbuf + dest * recvbytes, recvbytes,
|
||||
sendbuf + dest * sendbytes, sendbytes, &stat);
|
||||
ret = MPMY_Count(&stat);
|
||||
if (ret != recvbytes)
|
||||
Error("Shift failed, expected %d got %d\n", recvbytes, ret);
|
||||
}
|
||||
if (MPMY_Procnum() == my_leader) {
|
||||
tmpbuf_s = Malloc(sendbytes*PROCS_PER_NODE);
|
||||
tmpbuf_r = Malloc(recvbytes*PROCS_PER_NODE);
|
||||
}
|
||||
/* Across nodes */
|
||||
for (relative = 1; relative < 1 << doc_nodes; relative++) {
|
||||
for (proc = 0; proc < PROCS_PER_NODE; proc++) {
|
||||
dest_leader = (relative ^ my_node) * PROCS_PER_NODE;
|
||||
dest = dest_leader + proc;
|
||||
if (dest >= MPMY_Nproc())
|
||||
continue;
|
||||
if (MPMY_Procnum() != my_leader) {
|
||||
MPMY_Isend(sendbuf + dest * sendbytes, sendbytes, my_leader, ALLTOALL_RTAG, &req);
|
||||
MPMY_Wait(req, 0);
|
||||
if (MPMY_Procnum() == my_leader + proc) {
|
||||
Msgf(("Alltoall relay recv from %d (source=%d, incnt=%d)\n",
|
||||
my_leader, dest_leader, PROCS_PER_NODE * recvbytes));
|
||||
MPMY_Irecv(recvbuf + dest_leader * recvbytes, PROCS_PER_NODE * recvbytes,
|
||||
my_leader, ALLTOALL_TAG, &req);
|
||||
MPMY_Wait(req, &stat);
|
||||
ret = MPMY_Count(&stat);
|
||||
if (ret != PROCS_PER_NODE * recvbytes) {
|
||||
Error("Irecv failed, expected %d got %d\n", PROCS_PER_NODE * recvbytes, ret);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
memcpy(tmpbuf_s, sendbuf + dest * sendbytes, sendbytes);
|
||||
for (i = 1; i < PROCS_PER_NODE; i++) {
|
||||
if (my_leader + i >= MPMY_Nproc()) break;
|
||||
MPMY_Irecv(tmpbuf_s + i * recvbytes, recvbytes, my_leader+i, ALLTOALL_RTAG, &req);
|
||||
MPMY_Wait(req, &stat);
|
||||
ret = MPMY_Count(&stat);
|
||||
if (ret != recvbytes) {
|
||||
Error("Irecv failed, expected %d got %d\n", recvbytes, ret);
|
||||
}
|
||||
}
|
||||
Msgf(("Alltoall relay for %d MPMY_Shift(dest=%d, incnt=%d, outcnt=%d)\n",
|
||||
dest, dest_leader, PROCS_PER_NODE * recvbytes, PROCS_PER_NODE * sendbytes));
|
||||
MPMY_Shift(dest_leader, tmpbuf_r, PROCS_PER_NODE * recvbytes,
|
||||
tmpbuf_s, PROCS_PER_NODE * sendbytes, &stat);
|
||||
ret = MPMY_Count(&stat);
|
||||
if (ret != PROCS_PER_NODE * recvbytes)
|
||||
Error("Shift failed, expected %d got %d\n", PROCS_PER_NODE * recvbytes, ret);
|
||||
if (proc == 0) {
|
||||
Msgf(("Alltoall local copy (source=%d, incnt=%d)\n",
|
||||
dest_leader, PROCS_PER_NODE * recvbytes));
|
||||
memcpy(recvbuf + dest_leader * recvbytes, tmpbuf_r, PROCS_PER_NODE * recvbytes);
|
||||
} else {
|
||||
Msgf(("Alltoall relay send to %d (source=%d, incnt=%d)\n",
|
||||
my_leader+proc, dest_leader, PROCS_PER_NODE * recvbytes));
|
||||
MPMY_Isend(tmpbuf_r, PROCS_PER_NODE * recvbytes, my_leader+proc, ALLTOALL_TAG, &req);
|
||||
MPMY_Wait(req, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (MPMY_Procnum() == my_leader) {
|
||||
Free(tmpbuf_r);
|
||||
Free(tmpbuf_s);
|
||||
}
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
MPMY_Alltoallv(void *sendbuf, int *scount, int *soff, MPMY_Datatype sendtype,
|
||||
void *recvbuf, int *rcount, int *roff, MPMY_Datatype recvtype)
|
||||
{
|
||||
MPMY_Status stat;
|
||||
int i;
|
||||
int ret;
|
||||
int doc_procs, doc_nodes, relative, dest, proc;
|
||||
int ssize = MPMY_Datasize[sendtype];
|
||||
int rsize = MPMY_Datasize[recvtype];
|
||||
int my_node = MPMY_Procnum() / PROCS_PER_NODE;
|
||||
int my_leader = my_node * PROCS_PER_NODE;
|
||||
int local_rank = MPMY_Procnum() % PROCS_PER_NODE;
|
||||
int dest_leader;
|
||||
char *tmpbuf_s = NULL;
|
||||
char *tmpbuf_r = NULL;
|
||||
int *stcnt = NULL;
|
||||
int *stoff = NULL;
|
||||
MPMY_Comm_request req;
|
||||
int sendbytes, recvbytes;
|
||||
|
||||
doc_nodes = ilog2(MPMY_Nproc()/PROCS_PER_NODE-1) + 1;
|
||||
doc_procs = ilog2(PROCS_PER_NODE-1) + 1;
|
||||
if (MPMY_Procnum() == my_leader) {
|
||||
stcnt = Calloc(PROCS_PER_NODE, sizeof(int));
|
||||
stoff = Calloc(PROCS_PER_NODE, sizeof(int));
|
||||
}
|
||||
Msgf(("Alltoallv my_leader %d, local_rank %d, doc_nodes %d, doc_procs %d\n",
|
||||
my_leader, local_rank, doc_nodes, doc_procs));
|
||||
/* Within a node */
|
||||
for (relative = 0; relative < 1 << doc_procs; relative++) {
|
||||
dest = my_leader + (relative ^ local_rank);
|
||||
if ((dest >= MPMY_Nproc()) || (dest >= my_leader + PROCS_PER_NODE))
|
||||
continue;
|
||||
if ((rcount[dest] == 0) && (scount[dest] == 0))
|
||||
continue;
|
||||
Msgf(("local Alltoallv MPMY_Shift(dest=%d, instart=%p, incnt=%d, outstart=%p, outcnt=%d)\n",
|
||||
dest, recvbuf + roff[dest] * rsize, rcount[dest] * rsize,
|
||||
sendbuf + soff[dest] * ssize, scount[dest] * ssize));
|
||||
MPMY_Shift(dest, recvbuf + roff[dest] * rsize, rcount[dest] * rsize,
|
||||
sendbuf + soff[dest] * ssize, scount[dest] * ssize, &stat);
|
||||
ret = MPMY_Count(&stat);
|
||||
if (ret != rcount[dest] * rsize)
|
||||
Error("Shift failed, expected %d got %d\n", rcount[dest] * rsize, ret);
|
||||
}
|
||||
/* Across nodes */
|
||||
for (relative = 1; relative < 1 << doc_nodes; relative++) {
|
||||
for (proc = 0; proc < PROCS_PER_NODE; proc++) {
|
||||
dest_leader = (relative ^ my_node) * PROCS_PER_NODE;
|
||||
dest = dest_leader + proc;
|
||||
if (dest >= MPMY_Nproc())
|
||||
continue;
|
||||
if (MPMY_Procnum() != my_leader) {
|
||||
MPMY_Isend(&scount[dest], sizeof(int), my_leader, ALLTOALL_NTAG, &req);
|
||||
MPMY_Wait(req, 0);
|
||||
if (MPMY_Procnum() == my_leader + proc) {
|
||||
for (recvbytes = 0, i = dest_leader; i < dest_leader + PROCS_PER_NODE; i++) {
|
||||
if (i >= MPMY_Nproc()) break;
|
||||
recvbytes += rcount[i] * rsize;
|
||||
}
|
||||
MPMY_Isend(&recvbytes, sizeof(int), my_leader, ALLTOALL_NTAG, &req);
|
||||
MPMY_Wait(req, 0);
|
||||
}
|
||||
if (scount[dest]) {
|
||||
MPMY_Isend(sendbuf + soff[dest] * ssize, scount[dest] * ssize, my_leader,
|
||||
ALLTOALL_RTAG, &req);
|
||||
MPMY_Wait(req, 0);
|
||||
}
|
||||
if ((MPMY_Procnum() == my_leader + proc) && recvbytes) {
|
||||
Msgf(("Alltoallv relay recv from %d (source=%d, incnt=%d)\n",
|
||||
my_leader, dest_leader, recvbytes));
|
||||
MPMY_Irecv(recvbuf + roff[dest_leader] * rsize, recvbytes,
|
||||
my_leader, ALLTOALL_TAG, &req);
|
||||
MPMY_Wait(req, &stat);
|
||||
ret = MPMY_Count(&stat);
|
||||
if (ret != recvbytes) {
|
||||
Error("Irecv failed, expected %d got %d\n", recvbytes, ret);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
stcnt[0] = scount[dest];
|
||||
stoff[0] = 0;
|
||||
sendbytes = stcnt[0] * ssize;
|
||||
for (i = 1; i < PROCS_PER_NODE; i++) {
|
||||
if (my_leader + i >= MPMY_Nproc()) break;
|
||||
MPMY_Irecv(stcnt+i, sizeof(int), my_leader+i, ALLTOALL_NTAG, &req);
|
||||
MPMY_Wait(req, &stat);
|
||||
ret = MPMY_Count(&stat);
|
||||
if (ret != sizeof(int)) {
|
||||
Error("Irecv failed, expected %ld got %d\n", sizeof(int), ret);
|
||||
}
|
||||
stoff[i] = stoff[i-1] + stcnt[i-1];
|
||||
sendbytes += stcnt[i] * ssize;
|
||||
}
|
||||
if (proc == 0) {
|
||||
for (recvbytes = 0, i = dest_leader; i < dest_leader + PROCS_PER_NODE; i++) {
|
||||
if (i >= MPMY_Nproc()) break;
|
||||
recvbytes += rcount[i] * rsize;
|
||||
}
|
||||
} else if (my_leader+proc < MPMY_Nproc()) {
|
||||
MPMY_Irecv(&recvbytes, sizeof(int), my_leader+proc, ALLTOALL_NTAG, &req);
|
||||
MPMY_Wait(req, &stat);
|
||||
ret = MPMY_Count(&stat);
|
||||
if (ret != sizeof(int)) {
|
||||
Error("Irecv failed, expected %ld got %d\n", sizeof(int), ret);
|
||||
}
|
||||
}
|
||||
if (sendbytes || recvbytes) {
|
||||
Msgf(("allocating %d bytes for send\n", sendbytes));
|
||||
tmpbuf_s = Malloc(sendbytes);
|
||||
memcpy(tmpbuf_s, sendbuf + soff[dest] * ssize, scount[dest] * ssize);
|
||||
for (i = 1; i < PROCS_PER_NODE; i++) {
|
||||
if (my_leader + i >= MPMY_Nproc()) break;
|
||||
if (stcnt[i]) {
|
||||
MPMY_Irecv(tmpbuf_s + stoff[i] * ssize, stcnt[i] * ssize,
|
||||
my_leader+i, ALLTOALL_RTAG, &req);
|
||||
MPMY_Wait(req, &stat);
|
||||
ret = MPMY_Count(&stat);
|
||||
if (ret != stcnt[i] * ssize) {
|
||||
Error("Irecv failed, expected %d got %d\n", stcnt[i] * ssize, ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
Msgf(("allocating %d bytes for recv\n", recvbytes));
|
||||
Msgf(("Alltoallv relay for %d MPMY_Shift(dest=%d, incnt=%d, outcnt=%d)\n",
|
||||
dest, dest_leader, recvbytes, sendbytes));
|
||||
tmpbuf_r = Malloc(recvbytes);
|
||||
if (sendbytes || recvbytes) {
|
||||
MPMY_Shift(dest_leader, tmpbuf_r, recvbytes, tmpbuf_s, sendbytes, &stat);
|
||||
ret = MPMY_Count(&stat);
|
||||
if (ret != recvbytes)
|
||||
Error("Shift failed, expected %d got %d\n", recvbytes, ret);
|
||||
}
|
||||
Free(tmpbuf_s);
|
||||
if (recvbytes) {
|
||||
if (proc == 0) {
|
||||
Msgf(("Alltoallv local copy (source=%d, incnt=%d)\n",
|
||||
dest_leader, recvbytes));
|
||||
memcpy(recvbuf + roff[dest_leader] * rsize, tmpbuf_r, recvbytes);
|
||||
} else if (my_leader+proc < MPMY_Nproc()) {
|
||||
Msgf(("Alltoallv relay send to %d (source=%d, incnt=%d)\n",
|
||||
my_leader+proc, dest_leader, recvbytes));
|
||||
MPMY_Isend(tmpbuf_r, recvbytes, my_leader+proc, ALLTOALL_TAG, &req);
|
||||
MPMY_Wait(req, 0);
|
||||
}
|
||||
}
|
||||
Free(tmpbuf_r);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (MPMY_Procnum() == my_leader) {
|
||||
Free(stcnt);
|
||||
Free(stoff);
|
||||
}
|
||||
return MPMY_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
MPMY_Alltoallv_simple(void *sendbuf, int *scount, int *soff, MPMY_Datatype sendtype,
|
||||
void *recvbuf, int *rcount, int *roff, MPMY_Datatype recvtype)
|
||||
{
|
||||
MPMY_Status stat;
|
||||
int ret;
|
||||
int doc, relative, i;
|
||||
int ssize = MPMY_Datasize[sendtype];
|
||||
int rsize = MPMY_Datasize[recvtype];
|
||||
|
||||
doc = ilog2(MPMY_Nproc()-1) + 1;
|
||||
i = MPMY_Procnum();
|
||||
if (scount[i]) {
|
||||
memcpy(recvbuf + roff[i] * rsize, sendbuf + soff[i] * ssize, scount[i] * ssize);
|
||||
}
|
||||
for (relative = 1; relative < 1<<doc; relative++) {
|
||||
i = relative ^ MPMY_Procnum();
|
||||
if (i >= MPMY_Nproc())
|
||||
continue;
|
||||
if ((scount[i] == 0) && (rcount[i] == 0))
|
||||
continue;
|
||||
Msgf(("Alltoallv MPMY_Shift(dest=%d, instart=%p, incnt=%d, outstart=%p, outcnt=%d)\n",
|
||||
i, recvbuf + roff[i] * rsize, rcount[i] * rsize,
|
||||
sendbuf + soff[i] * ssize, scount[i] * ssize));
|
||||
MPMY_Shift(i, recvbuf + roff[i] * rsize, rcount[i] * rsize,
|
||||
sendbuf + soff[i] * ssize, scount[i] * ssize, &stat);
|
||||
ret = MPMY_Count(&stat);
|
||||
if (ret != rcount[i] * rsize)
|
||||
Error("Shift failed, expected %d got %d\n", rcount[i] * rsize, ret);
|
||||
}
|
||||
return MPMY_SUCCESS;
|
||||
}
|
83
external/libsdf/libsw/msgdirinit.c
vendored
Normal file
83
external/libsdf/libsw/msgdirinit.c
vendored
Normal file
|
@ -0,0 +1,83 @@
|
|||
#define NO_MSGS
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include "Malloc.h"
|
||||
#include "mpmy_abnormal.h"
|
||||
#include "protos.h"
|
||||
#include "error.h"
|
||||
#include "Msgs.h"
|
||||
#include "mpmy.h"
|
||||
#include "files.h"
|
||||
#include "mpmy_io.h"
|
||||
|
||||
#ifdef __DELTA__
|
||||
void ivfprintf(FILE *stream, const char *fmt, va_list args);
|
||||
void ifflush(FILE *stream);
|
||||
#endif
|
||||
|
||||
void MsgdirInit(const char *name)
|
||||
{
|
||||
char *junk;
|
||||
void *dbgfp;
|
||||
char *lastslash;
|
||||
char *dirname;
|
||||
|
||||
#ifdef __PARAGON__
|
||||
#define PARAGON_MAX_OPEN 128
|
||||
if (MPMY_Nproc() > PARAGON_MAX_OPEN) {
|
||||
SinglWarning("Can't open more than %d files on paragon because of NORMA-IPC\n",
|
||||
PARAGON_MAX_OPEN);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef sun
|
||||
if (MPMY_Nproc() > 32) {
|
||||
SinglWarning("Can't open %d files on cm5 because of fd limit\n",
|
||||
MPMY_Nproc());
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
junk = Malloc(strlen(name)+1); /* enough? */
|
||||
lastslash = strrchr(name, '/');
|
||||
if( lastslash == NULL || lastslash == &name[0] ){
|
||||
/* Either it's in "." or in "/" */
|
||||
/* In either case we don't need to do a mkdir */
|
||||
dirname = NULL;
|
||||
}else{
|
||||
strncpy(junk, name, lastslash-name);
|
||||
junk[lastslash-name] = '\0';
|
||||
dirname = junk;
|
||||
}
|
||||
|
||||
/* We only try to create the lowest level of the name. No
|
||||
recursion here... Nosiree. */
|
||||
if( dirname && !fexists(dirname) ){
|
||||
if( MPMY_Mkdir(dirname, 0777) ){
|
||||
SinglWarning("Mkdir(%s) failed\n", dirname);
|
||||
goto outahere;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now the directory is sure to exist. */
|
||||
dbgfp = fopen(name, "w");
|
||||
if( dbgfp == NULL ){
|
||||
Error("Could not fopen %s, errno=%d\n", name, errno);
|
||||
}
|
||||
|
||||
#ifdef __DELTA__
|
||||
Msg_addfile(dbgfp, (Msgvfprintf_t)ivfprintf, (Msgfflush_t)ifflush);
|
||||
#else
|
||||
Msg_addfile(dbgfp, (Msgvfprintf_t)vfprintf, (Msgfflush_t)fflush);
|
||||
#endif
|
||||
outahere:
|
||||
Free(junk);
|
||||
}
|
||||
|
441
external/libsdf/libsw/obstack.c
vendored
Normal file
441
external/libsdf/libsw/obstack.c
vendored
Normal file
|
@ -0,0 +1,441 @@
|
|||
/* obstack.c - subroutines used implicitly by object stack macros
|
||||
Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998,
|
||||
1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef _LIBC
|
||||
# include <obstack.h>
|
||||
# include <shlib-compat.h>
|
||||
#else
|
||||
# include "obstack.h"
|
||||
#endif
|
||||
|
||||
/* NOTE BEFORE MODIFYING THIS FILE: This version number must be
|
||||
incremented whenever callers compiled using an old obstack.h can no
|
||||
longer properly call the functions in this obstack.c. */
|
||||
#define OBSTACK_INTERFACE_VERSION 1
|
||||
|
||||
/* Comment out all this code if we are using the GNU C Library, and are not
|
||||
actually compiling the library itself, and the installed library
|
||||
supports the same library interface we do. This code is part of the GNU
|
||||
C Library, but also included in many other GNU distributions. Compiling
|
||||
and linking in this code is a waste when using the GNU C library
|
||||
(especially if it is a shared library). Rather than having every GNU
|
||||
program understand `configure --with-gnu-libc' and omit the object
|
||||
files, it is simpler to just do this in the source for each such file. */
|
||||
|
||||
#include <stdio.h> /* Random thing to get __GNU_LIBRARY__. */
|
||||
#if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1
|
||||
# include <gnu-versions.h>
|
||||
# if _GNU_OBSTACK_INTERFACE_VERSION == OBSTACK_INTERFACE_VERSION
|
||||
# define ELIDE_CODE
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#ifndef ELIDE_CODE
|
||||
|
||||
|
||||
# if HAVE_INTTYPES_H
|
||||
# include <inttypes.h>
|
||||
# endif
|
||||
# if HAVE_STDINT_H || defined _LIBC
|
||||
# include <stdint.h>
|
||||
# endif
|
||||
|
||||
/* Determine default alignment. */
|
||||
union fooround
|
||||
{
|
||||
uintmax_t i;
|
||||
long double d;
|
||||
void *p;
|
||||
};
|
||||
struct fooalign
|
||||
{
|
||||
char c;
|
||||
union fooround u;
|
||||
};
|
||||
/* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT.
|
||||
But in fact it might be less smart and round addresses to as much as
|
||||
DEFAULT_ROUNDING. So we prepare for it to do that. */
|
||||
enum
|
||||
{
|
||||
DEFAULT_ALIGNMENT = offsetof (struct fooalign, u),
|
||||
DEFAULT_ROUNDING = sizeof (union fooround)
|
||||
};
|
||||
|
||||
/* When we copy a long block of data, this is the unit to do it with.
|
||||
On some machines, copying successive ints does not work;
|
||||
in such a case, redefine COPYING_UNIT to `long' (if that works)
|
||||
or `char' as a last resort. */
|
||||
# ifndef COPYING_UNIT
|
||||
# define COPYING_UNIT int
|
||||
# endif
|
||||
|
||||
|
||||
/* The functions allocating more room by calling `obstack_chunk_alloc'
|
||||
jump to the handler pointed to by `obstack_alloc_failed_handler'.
|
||||
This can be set to a user defined function which should either
|
||||
abort gracefully or use longjump - but shouldn't return. This
|
||||
variable by default points to the internal function
|
||||
`print_and_abort'. */
|
||||
static void print_and_abort (void);
|
||||
void (*obstack_alloc_failed_handler) (void) = print_and_abort;
|
||||
|
||||
/* Exit value used when `print_and_abort' is used. */
|
||||
# include <stdlib.h>
|
||||
# ifdef _LIBC
|
||||
int obstack_exit_failure = EXIT_FAILURE;
|
||||
# else
|
||||
# include "exitfail.h"
|
||||
# define obstack_exit_failure exit_failure
|
||||
# endif
|
||||
|
||||
# ifdef _LIBC
|
||||
# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4)
|
||||
/* A looong time ago (before 1994, anyway; we're not sure) this global variable
|
||||
was used by non-GNU-C macros to avoid multiple evaluation. The GNU C
|
||||
library still exports it because somebody might use it. */
|
||||
struct obstack *_obstack_compat;
|
||||
compat_symbol (libc, _obstack_compat, _obstack, GLIBC_2_0);
|
||||
# endif
|
||||
# endif
|
||||
|
||||
/* Define a macro that either calls functions with the traditional malloc/free
|
||||
calling interface, or calls functions with the mmalloc/mfree interface
|
||||
(that adds an extra first argument), based on the state of use_extra_arg.
|
||||
For free, do not use ?:, since some compilers, like the MIPS compilers,
|
||||
do not allow (expr) ? void : void. */
|
||||
|
||||
# define CALL_CHUNKFUN(h, size) \
|
||||
(((h) -> use_extra_arg) \
|
||||
? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
|
||||
: (*(struct _obstack_chunk *(*) (long)) (h)->chunkfun) ((size)))
|
||||
|
||||
# define CALL_FREEFUN(h, old_chunk) \
|
||||
do { \
|
||||
if ((h) -> use_extra_arg) \
|
||||
(*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
|
||||
else \
|
||||
(*(void (*) (void *)) (h)->freefun) ((old_chunk)); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* Initialize an obstack H for use. Specify chunk size SIZE (0 means default).
|
||||
Objects start on multiples of ALIGNMENT (0 means use default).
|
||||
CHUNKFUN is the function to use to allocate chunks,
|
||||
and FREEFUN the function to free them.
|
||||
|
||||
Return nonzero if successful, calls obstack_alloc_failed_handler if
|
||||
allocation fails. */
|
||||
|
||||
int
|
||||
_obstack_begin (struct obstack *h,
|
||||
int size, int alignment,
|
||||
void *(*chunkfun) (long),
|
||||
void (*freefun) (void *))
|
||||
{
|
||||
register struct _obstack_chunk *chunk; /* points to new chunk */
|
||||
|
||||
if (alignment == 0)
|
||||
alignment = DEFAULT_ALIGNMENT;
|
||||
if (size == 0)
|
||||
/* Default size is what GNU malloc can fit in a 4096-byte block. */
|
||||
{
|
||||
/* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
|
||||
Use the values for range checking, because if range checking is off,
|
||||
the extra bytes won't be missed terribly, but if range checking is on
|
||||
and we used a larger request, a whole extra 4096 bytes would be
|
||||
allocated.
|
||||
|
||||
These number are irrelevant to the new GNU malloc. I suspect it is
|
||||
less sensitive to the size of the request. */
|
||||
int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
|
||||
+ 4 + DEFAULT_ROUNDING - 1)
|
||||
& ~(DEFAULT_ROUNDING - 1));
|
||||
size = 4096 - extra;
|
||||
}
|
||||
|
||||
h->chunkfun = (struct _obstack_chunk * (*)(void *, long)) chunkfun;
|
||||
h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
|
||||
h->chunk_size = size;
|
||||
h->alignment_mask = alignment - 1;
|
||||
h->use_extra_arg = 0;
|
||||
|
||||
chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
|
||||
if (!chunk)
|
||||
(*obstack_alloc_failed_handler) ();
|
||||
h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents,
|
||||
alignment - 1);
|
||||
h->chunk_limit = chunk->limit
|
||||
= (char *) chunk + h->chunk_size;
|
||||
chunk->prev = 0;
|
||||
/* The initial chunk now contains no empty object. */
|
||||
h->maybe_empty_object = 0;
|
||||
h->alloc_failed = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
_obstack_begin_1 (struct obstack *h, int size, int alignment,
|
||||
void *(*chunkfun) (void *, long),
|
||||
void (*freefun) (void *, void *),
|
||||
void *arg)
|
||||
{
|
||||
register struct _obstack_chunk *chunk; /* points to new chunk */
|
||||
|
||||
if (alignment == 0)
|
||||
alignment = DEFAULT_ALIGNMENT;
|
||||
if (size == 0)
|
||||
/* Default size is what GNU malloc can fit in a 4096-byte block. */
|
||||
{
|
||||
/* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
|
||||
Use the values for range checking, because if range checking is off,
|
||||
the extra bytes won't be missed terribly, but if range checking is on
|
||||
and we used a larger request, a whole extra 4096 bytes would be
|
||||
allocated.
|
||||
|
||||
These number are irrelevant to the new GNU malloc. I suspect it is
|
||||
less sensitive to the size of the request. */
|
||||
int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
|
||||
+ 4 + DEFAULT_ROUNDING - 1)
|
||||
& ~(DEFAULT_ROUNDING - 1));
|
||||
size = 4096 - extra;
|
||||
}
|
||||
|
||||
h->chunkfun = (struct _obstack_chunk * (*)(void *,long)) chunkfun;
|
||||
h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
|
||||
h->chunk_size = size;
|
||||
h->alignment_mask = alignment - 1;
|
||||
h->extra_arg = arg;
|
||||
h->use_extra_arg = 1;
|
||||
|
||||
chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
|
||||
if (!chunk)
|
||||
(*obstack_alloc_failed_handler) ();
|
||||
h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents,
|
||||
alignment - 1);
|
||||
h->chunk_limit = chunk->limit
|
||||
= (char *) chunk + h->chunk_size;
|
||||
chunk->prev = 0;
|
||||
/* The initial chunk now contains no empty object. */
|
||||
h->maybe_empty_object = 0;
|
||||
h->alloc_failed = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Allocate a new current chunk for the obstack *H
|
||||
on the assumption that LENGTH bytes need to be added
|
||||
to the current object, or a new object of length LENGTH allocated.
|
||||
Copies any partial object from the end of the old chunk
|
||||
to the beginning of the new one. */
|
||||
|
||||
void
|
||||
_obstack_newchunk (struct obstack *h, int length)
|
||||
{
|
||||
register struct _obstack_chunk *old_chunk = h->chunk;
|
||||
register struct _obstack_chunk *new_chunk;
|
||||
register long new_size;
|
||||
register long obj_size = h->next_free - h->object_base;
|
||||
register long i;
|
||||
long already;
|
||||
char *object_base;
|
||||
|
||||
/* Compute size for new chunk. */
|
||||
new_size = (obj_size + length) + (obj_size >> 3) + h->alignment_mask + 100;
|
||||
if (new_size < h->chunk_size)
|
||||
new_size = h->chunk_size;
|
||||
|
||||
/* Allocate and initialize the new chunk. */
|
||||
new_chunk = CALL_CHUNKFUN (h, new_size);
|
||||
if (!new_chunk)
|
||||
(*obstack_alloc_failed_handler) ();
|
||||
h->chunk = new_chunk;
|
||||
new_chunk->prev = old_chunk;
|
||||
new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;
|
||||
|
||||
/* Compute an aligned object_base in the new chunk */
|
||||
object_base =
|
||||
__PTR_ALIGN ((char *) new_chunk, new_chunk->contents, h->alignment_mask);
|
||||
|
||||
/* Move the existing object to the new chunk.
|
||||
Word at a time is fast and is safe if the object
|
||||
is sufficiently aligned. */
|
||||
if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT)
|
||||
{
|
||||
for (i = obj_size / sizeof (COPYING_UNIT) - 1;
|
||||
i >= 0; i--)
|
||||
((COPYING_UNIT *)object_base)[i]
|
||||
= ((COPYING_UNIT *)h->object_base)[i];
|
||||
/* We used to copy the odd few remaining bytes as one extra COPYING_UNIT,
|
||||
but that can cross a page boundary on a machine
|
||||
which does not do strict alignment for COPYING_UNITS. */
|
||||
already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT);
|
||||
}
|
||||
else
|
||||
already = 0;
|
||||
/* Copy remaining bytes one by one. */
|
||||
for (i = already; i < obj_size; i++)
|
||||
object_base[i] = h->object_base[i];
|
||||
|
||||
/* If the object just copied was the only data in OLD_CHUNK,
|
||||
free that chunk and remove it from the chain.
|
||||
But not if that chunk might contain an empty object. */
|
||||
if (! h->maybe_empty_object
|
||||
&& (h->object_base
|
||||
== __PTR_ALIGN ((char *) old_chunk, old_chunk->contents,
|
||||
h->alignment_mask)))
|
||||
{
|
||||
new_chunk->prev = old_chunk->prev;
|
||||
CALL_FREEFUN (h, old_chunk);
|
||||
}
|
||||
|
||||
h->object_base = object_base;
|
||||
h->next_free = h->object_base + obj_size;
|
||||
/* The new chunk certainly contains no empty object yet. */
|
||||
h->maybe_empty_object = 0;
|
||||
}
|
||||
# ifdef _LIBC
|
||||
libc_hidden_def (_obstack_newchunk)
|
||||
# endif
|
||||
|
||||
/* Return nonzero if object OBJ has been allocated from obstack H.
|
||||
This is here for debugging.
|
||||
If you use it in a program, you are probably losing. */
|
||||
|
||||
/* Suppress -Wmissing-prototypes warning. We don't want to declare this in
|
||||
obstack.h because it is just for debugging. */
|
||||
int _obstack_allocated_p (struct obstack *h, void *obj);
|
||||
|
||||
int
|
||||
_obstack_allocated_p (struct obstack *h, void *obj)
|
||||
{
|
||||
register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
|
||||
register struct _obstack_chunk *plp; /* point to previous chunk if any */
|
||||
|
||||
lp = (h)->chunk;
|
||||
/* We use >= rather than > since the object cannot be exactly at
|
||||
the beginning of the chunk but might be an empty object exactly
|
||||
at the end of an adjacent chunk. */
|
||||
while (lp != 0 && ((void *) lp >= obj || (void *) (lp)->limit < obj))
|
||||
{
|
||||
plp = lp->prev;
|
||||
lp = plp;
|
||||
}
|
||||
return lp != 0;
|
||||
}
|
||||
|
||||
/* Free objects in obstack H, including OBJ and everything allocate
|
||||
more recently than OBJ. If OBJ is zero, free everything in H. */
|
||||
|
||||
# undef obstack_free
|
||||
|
||||
void
|
||||
obstack_free (struct obstack *h, void *obj)
|
||||
{
|
||||
register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
|
||||
register struct _obstack_chunk *plp; /* point to previous chunk if any */
|
||||
|
||||
lp = h->chunk;
|
||||
/* We use >= because there cannot be an object at the beginning of a chunk.
|
||||
But there can be an empty object at that address
|
||||
at the end of another chunk. */
|
||||
while (lp != 0 && ((void *) lp >= obj || (void *) (lp)->limit < obj))
|
||||
{
|
||||
plp = lp->prev;
|
||||
CALL_FREEFUN (h, lp);
|
||||
lp = plp;
|
||||
/* If we switch chunks, we can't tell whether the new current
|
||||
chunk contains an empty object, so assume that it may. */
|
||||
h->maybe_empty_object = 1;
|
||||
}
|
||||
if (lp)
|
||||
{
|
||||
h->object_base = h->next_free = (char *) (obj);
|
||||
h->chunk_limit = lp->limit;
|
||||
h->chunk = lp;
|
||||
}
|
||||
else if (obj != 0)
|
||||
/* obj is not in any of the chunks! */
|
||||
abort ();
|
||||
}
|
||||
|
||||
# ifdef _LIBC
|
||||
/* Older versions of libc used a function _obstack_free intended to be
|
||||
called by non-GCC compilers. */
|
||||
strong_alias (obstack_free, _obstack_free)
|
||||
# endif
|
||||
|
||||
int
|
||||
_obstack_memory_used (struct obstack *h)
|
||||
{
|
||||
register struct _obstack_chunk* lp;
|
||||
register int nbytes = 0;
|
||||
|
||||
for (lp = h->chunk; lp != 0; lp = lp->prev)
|
||||
{
|
||||
nbytes += lp->limit - (char *) lp;
|
||||
}
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
/* Define the error handler. */
|
||||
# ifdef _LIBC
|
||||
# include <libintl.h>
|
||||
# else
|
||||
# include "gettext.h"
|
||||
# endif
|
||||
# ifndef _
|
||||
# define _(msgid) gettext (msgid)
|
||||
# endif
|
||||
|
||||
# ifdef _LIBC
|
||||
# include <libio/iolibio.h>
|
||||
# endif
|
||||
|
||||
# ifndef __attribute__
|
||||
/* This feature is available in gcc versions 2.5 and later. */
|
||||
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)
|
||||
# define __attribute__(Spec) /* empty */
|
||||
# endif
|
||||
# endif
|
||||
|
||||
static void
|
||||
__attribute__ ((noreturn))
|
||||
print_and_abort (void)
|
||||
{
|
||||
/* Don't change any of these strings. Yes, it would be possible to add
|
||||
the newline to the string and use fputs or so. But this must not
|
||||
happen because the "memory exhausted" message appears in other places
|
||||
like this and the translation should be reused instead of creating
|
||||
a very similar string which requires a separate translation. */
|
||||
# ifdef _LIBC
|
||||
(void) __fxprintf (NULL, "%s\n", _("memory exhausted"));
|
||||
# else
|
||||
fprintf (stderr, "%s\n", _("memory exhausted"));
|
||||
# endif
|
||||
exit (obstack_exit_failure);
|
||||
}
|
||||
|
||||
#endif /* !ELIDE_CODE */
|
34
external/libsdf/libsw/op_template.c
vendored
Normal file
34
external/libsdf/libsw/op_template.c
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
|
||||
/* This is a template that is included multiple times in mpmy_combine.c */
|
||||
|
||||
switch(manifest->u.op) {
|
||||
case MPMY_SUM:
|
||||
Do_Op(outbuf, +=, inbuf, Type, count);
|
||||
break;
|
||||
case MPMY_PROD:
|
||||
Do_Op(outbuf, *=, inbuf, Type, count);
|
||||
break;
|
||||
case MPMY_MAX:
|
||||
Do_Op(outbuf,
|
||||
= (*(Type *)outbuf > *(Type *)inbuf) ? *(Type *)outbuf :,
|
||||
inbuf, Type, count);
|
||||
break;
|
||||
case MPMY_MIN:
|
||||
Do_Op(outbuf,
|
||||
= (*(Type *)outbuf < *(Type *)inbuf) ? *(Type *)outbuf :,
|
||||
inbuf, Type, count);
|
||||
break;
|
||||
#ifdef BIT_OPS
|
||||
case MPMY_BAND:
|
||||
Do_Op(outbuf, &=, inbuf, Type, count);
|
||||
break;
|
||||
case MPMY_BOR:
|
||||
Do_Op(outbuf, |=, inbuf, Type, count);
|
||||
break;
|
||||
case MPMY_BXOR:
|
||||
Do_Op(outbuf, ^=, inbuf, Type, count);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
Error("Unknown op in mpmy_combine\n");
|
||||
}
|
363
external/libsdf/libsw/peano.c
vendored
Normal file
363
external/libsdf/libsw/peano.c
vendored
Normal file
|
@ -0,0 +1,363 @@
|
|||
#ifndef NDIM
|
||||
#define NDIM 3
|
||||
#endif
|
||||
|
||||
#include "Msgs.h"
|
||||
#include "Assert.h"
|
||||
#include "key.h"
|
||||
#include "vop.h"
|
||||
|
||||
|
||||
/* The long-awaited peano-hilbert key. */
|
||||
/* "When the going gets wierd, the wierd turn pro." */
|
||||
/* Interestingly, it isn't particularly more complicated by virtue */
|
||||
/* of the arbitrary NDIM support. The NDIM=3 only code was essentially */
|
||||
/* the same except for some loop indices */
|
||||
|
||||
#if NDIM==3
|
||||
/* The possible places to start. */
|
||||
/* They can only have an even number of bits turned on. */
|
||||
#define S000 0
|
||||
#define S011 1
|
||||
#define S101 2
|
||||
#define S110 3
|
||||
/* one for each of the possible startindices */
|
||||
static int sindex_to_mask[1<<(NDIM-1)] = {0, 3, 5, 6};
|
||||
static int smask_to_index[1<<NDIM] = {S000, -1, -1, S011, -1, S101, S110, -1};
|
||||
|
||||
/* The possible "path-types" (there are NDIM of them) */
|
||||
#define Px 0
|
||||
#define Py 1
|
||||
#define Pz 2
|
||||
|
||||
static int pindex_to_mask[NDIM] = {4, 2, 1};
|
||||
|
||||
/* What are the large transitions in each of the three basic paths? */
|
||||
static int bigtrans[NDIM][1<<NDIM] = {
|
||||
{Py, Pz, Py, Px, Py, Pz, Py, Px}, /* Px */
|
||||
{Px, Pz, Px, Py, Px, Pz, Px, Py}, /* Py */
|
||||
{Px, Py, Px, Pz, Px, Py, Px, Pz} /* Pz */
|
||||
};
|
||||
|
||||
/* What are the small transitions on each of the NDIM basic paths? */
|
||||
static int ltltrans[NDIM][1<<NDIM] = {
|
||||
{Py, Pz, Pz, Px, Px, Pz, Pz, Py}, /* Px */
|
||||
{Px, Pz, Pz, Py, Py, Pz, Pz, Px}, /* Py */
|
||||
{Px, Py, Py, Pz, Pz, Py, Py, Px} /* Pz */
|
||||
};
|
||||
|
||||
#endif /* NDIM==3 */
|
||||
|
||||
#if NDIM==2
|
||||
/* The possible places to start. */
|
||||
/* They can only have an even number of bits turned on. */
|
||||
#define S00 0
|
||||
#define S11 1
|
||||
|
||||
/* one for each of the possible startindices */
|
||||
static int sindex_to_mask[1<<(NDIM-1)] = {0, 3};
|
||||
static int smask_to_index[1<<NDIM] = {S00, -1, -1, S11};
|
||||
|
||||
/* The possible "path-types" (there are NDIM of them) */
|
||||
#define Px 0
|
||||
#define Py 1
|
||||
|
||||
static int pindex_to_mask[NDIM] = {2, 1};
|
||||
|
||||
/* What are the large transitions in each of the NDIM basic paths? */
|
||||
static int bigtrans[NDIM][1<<NDIM] = {
|
||||
{Py, Px, Py, Px}, /* Px */
|
||||
{Px, Py, Px, Py} /* Py */
|
||||
};
|
||||
|
||||
/* What are the small transitions on each of the three basic paths? */
|
||||
static int ltltrans[NDIM][1<<NDIM] = {
|
||||
{Py, Px, Px, Py}, /* Px */
|
||||
{Px, Py, Py, Px} /* Py */
|
||||
};
|
||||
|
||||
#endif /* NDIM==2 */
|
||||
|
||||
static int bitmap[1<<(NDIM-1)][NDIM][1<<NDIM]; /* range 1<<NDIM */
|
||||
static int revbitmap[1<<(NDIM-1)][NDIM][1<<NDIM]; /* range 1<<NDIM */
|
||||
static int startmap[1<<(NDIM-1)][NDIM][1<<NDIM]; /* range 1<<(NDIM-1) */
|
||||
static int typmap[1<<(NDIM-1)][NDIM][1<<NDIM]; /* range NDIM */
|
||||
static int setup_done;
|
||||
|
||||
static void setup(void){
|
||||
unsigned int start, typ, j;
|
||||
unsigned int smap[1<<NDIM], bmap[1<<NDIM], lmap[1<<NDIM];
|
||||
unsigned int bt, lt, bm, st;
|
||||
|
||||
for(typ=0; typ<NDIM; typ++){
|
||||
for(start=0; start<(1<<(NDIM-1)); start++){
|
||||
bm = st = sindex_to_mask[start];
|
||||
for(j=0; j<(1<<NDIM); j++){
|
||||
smap[j] = smask_to_index[st];
|
||||
lmap[j] = ltltrans[typ][j];
|
||||
bmap[j] = bm;
|
||||
bt = pindex_to_mask[ bigtrans[typ][j] ];
|
||||
lt = pindex_to_mask[ ltltrans[typ][j] ];
|
||||
bm = bm^bt;
|
||||
st = st^(bt^lt);
|
||||
}
|
||||
/* This little wierdness arranges that map works in the */
|
||||
/* right direction...really */
|
||||
for(j=0; j<(1<<NDIM); j++){
|
||||
bm = bmap[j];
|
||||
startmap[start][typ][bm] = smap[j];
|
||||
bitmap[start][typ][bm] = j;
|
||||
revbitmap[start][typ][j] = bm; /* a shot in the dark */
|
||||
typmap[start][typ][bm] = lmap[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
setup_done = 1;
|
||||
}
|
||||
|
||||
static Key_t _PHKeyFromInts(unsigned int ikey[NDIM], unsigned int depth, int start, int type){
|
||||
Key_t ret;
|
||||
unsigned int bits;
|
||||
unsigned int rshift;
|
||||
unsigned int otype;
|
||||
Vxd(unsigned int ikey);
|
||||
ret = KeyInt(1);
|
||||
|
||||
if( !setup_done )
|
||||
setup();
|
||||
|
||||
VxV(ikey, = ikey);
|
||||
for(rshift=depth; rshift; ){
|
||||
rshift--;
|
||||
bits = (ikey0>>rshift)&1;
|
||||
#if NDIM > 1
|
||||
bits |= ((ikey1>>rshift)&1) << 1;
|
||||
#if NDIM > 2
|
||||
bits |= ((ikey2>>rshift)&1) << 2;
|
||||
#endif
|
||||
#endif
|
||||
ret = KeyOrInt(KeyLshift(ret, NDIM), bitmap[start][type][bits]);
|
||||
otype = type;
|
||||
type = typmap[start][otype][bits];
|
||||
start = startmap[start][otype][bits];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
Key_t PHKeyFromInts(unsigned int ikey[NDIM], int ndim, unsigned int depth){
|
||||
assert(ndim == NDIM);
|
||||
return _PHKeyFromInts(ikey, depth, 0, 0);
|
||||
}
|
||||
|
||||
/* Convert from a PH key to a NDIM-tuple of ints. */
|
||||
/* Return the "depth" of the key */
|
||||
|
||||
static unsigned int
|
||||
_IntsFromPHKey(Key_t key, unsigned int ikey[NDIM],
|
||||
int depth, int start, int type){
|
||||
unsigned int lobits, unscrambled;
|
||||
unsigned int otype;
|
||||
unsigned int rshift, ret;
|
||||
Vxd(unsigned int out);
|
||||
Key_t keymax;
|
||||
Key_t key0;
|
||||
|
||||
if( !setup_done )
|
||||
setup();
|
||||
keymax = KeyLshift(KeyInt(1), NDIM*depth);
|
||||
key0 = KeyInt(0);
|
||||
|
||||
VxS(out, = 0);
|
||||
/* We need to start at the left, so we need to figure out where the */
|
||||
/* left of key is! */
|
||||
while( KeyEQ(KeyAnd(keymax, key), key0) ){
|
||||
keymax = KeyRshift(keymax, NDIM);
|
||||
depth--;
|
||||
}
|
||||
ret = depth;
|
||||
|
||||
rshift = depth*NDIM;
|
||||
Msgf(("IntsFromPHKey(%s)\n", PrintKey(key)));
|
||||
while( rshift > 0 ){
|
||||
Key_t kr;
|
||||
rshift -= NDIM;
|
||||
depth--;
|
||||
kr = KeyRshift(key, rshift);
|
||||
lobits = KeyAndInt(kr, (1<<NDIM)-1);
|
||||
Msgf(("rshift=%d, kr=%s, lobits: %d\n", rshift, PrintKey(kr), lobits));
|
||||
unscrambled = revbitmap[start][type][lobits];
|
||||
|
||||
out0 |= (unscrambled&1)<<depth;
|
||||
#if NDIM > 1
|
||||
out1 |= ((unscrambled>>1)&1)<<depth;
|
||||
#if NDIM > 2
|
||||
out2 |= ((unscrambled>>2)&1)<<depth;
|
||||
#endif
|
||||
#endif
|
||||
otype = type;
|
||||
type = typmap[start][otype][unscrambled];
|
||||
start = startmap[start][otype][unscrambled];
|
||||
}
|
||||
VVx(ikey, = out);
|
||||
return ret;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
IntsFromPHKey(Key_t key, unsigned int ikey[NDIM], int ndim){
|
||||
assert(ndim == NDIM);
|
||||
return _IntsFromPHKey(key, ikey, TreeLevel(key, NDIM), 0, 0);
|
||||
}
|
||||
|
||||
#ifdef STANDALONE
|
||||
#define MAXDEPTH (15/NDIM)
|
||||
|
||||
/* The loops here are just too hard to deal with for generic NDIM. */
|
||||
/* And in two-d, we can make Postscript output! */
|
||||
#if NDIM == 3
|
||||
main(int argc, char **argv){
|
||||
int depth;
|
||||
unsigned int i, ikey;
|
||||
unsigned int ik[NDIM];
|
||||
int type, start;
|
||||
unsigned int revk[NDIM], revd;
|
||||
Key_t key, base;
|
||||
|
||||
depth = atoi(argv[1]);
|
||||
start = atoi(argv[2]);
|
||||
type = atoi(argv[3]);
|
||||
if( depth < 0 )
|
||||
Error("bad depth\n");
|
||||
if( type < 0 || type >= NDIM )
|
||||
Error("bad type\n");
|
||||
if( start < 0 || start >= 1<<(NDIM-1) )
|
||||
Error("bad start");
|
||||
|
||||
/* Test each ikey in a 3-d grid. Make sure that
|
||||
_IntsFromKey(KeyFromInts(ik)) == ik */
|
||||
for(ik[0]=0; ik[0]<(1<<depth); ik[0]++){
|
||||
for(ik[1]=0; ik[1]<(1<<depth); ik[1]++){
|
||||
for(ik[2]=0; ik[2]<(1<<depth); ik[2]++){
|
||||
key = _PHKeyFromInts(ik, depth, start, type);
|
||||
revd = _IntsFromPHKey(key, revk, depth, start, type);
|
||||
assert(revd == depth );
|
||||
if( revk[0]!=ik[0] || revk[1]!=ik[1] || revk[2]!=ik[2] )
|
||||
Warning("ik=(%x %x %x) -> %s -> revk=(%x %x %x)\n",
|
||||
ik[0], ik[1], ik[2],
|
||||
PrintKey(key),
|
||||
revk[0], revk[1], revk[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Test each key starting at 0. Make sure that
|
||||
KeyFromInts(IntsFromKey(k))==k */
|
||||
base = KeyLshift(KeyInt(1), depth*NDIM);
|
||||
for(ikey=0; ikey < (1<<(NDIM*depth)); ikey++){
|
||||
Key_t revkey;
|
||||
unsigned int di[NDIM];
|
||||
unsigned int iklast[NDIM];
|
||||
int d2;
|
||||
|
||||
revd = _IntsFromPHKey(base, ik, depth, start, type);
|
||||
assert(revd == depth);
|
||||
revkey = _PHKeyFromInts(ik, depth, start, type);
|
||||
if( KeyNEQ(revkey, base)){
|
||||
char s[64];
|
||||
strcpy(s, PrintKey(revkey));
|
||||
Warning("key %s -> %x %x %x -> %s\n",
|
||||
PrintKey(base), ik[0], ik[1], ik[2], s);
|
||||
}
|
||||
VVV(di, = ik, - iklast);
|
||||
d2 = Dot(di, di);
|
||||
if( d2 != 1 && ikey ){
|
||||
Warning("Move by more than 1 at ikey=%#0o\n", ikey);
|
||||
}
|
||||
|
||||
VV(iklast, = ik);
|
||||
base = KeyAddInt(base, 1);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if NDIM==2
|
||||
|
||||
#define SZ 6. /* inches */
|
||||
main(int argc, char **argv){
|
||||
int depth;
|
||||
unsigned int i, ikey;
|
||||
unsigned int ik[NDIM];
|
||||
int type, start;
|
||||
unsigned int revk[NDIM], revd;
|
||||
Key_t key, base;
|
||||
|
||||
depth = atoi(argv[1]);
|
||||
start = atoi(argv[2]);
|
||||
type = atoi(argv[3]);
|
||||
if( depth < 0 )
|
||||
Error("bad depth\n");
|
||||
if( type < 0 || type >= NDIM )
|
||||
Error("bad type\n");
|
||||
if( start < 0 || start >= 1<<(NDIM-1) )
|
||||
Error("bad start");
|
||||
|
||||
Warning("This is test of the emergency warning system\n");
|
||||
/* Test each ikey in a 3-d grid. Make sure that
|
||||
_IntsFromKey(KeyFromInts(ik)) == ik */
|
||||
for(ik[0]=0; ik[0]<(1<<depth); ik[0]++){
|
||||
for(ik[1]=0; ik[1]<(1<<depth); ik[1]++){
|
||||
key = _PHKeyFromInts(ik, depth, start, type);
|
||||
revd = _IntsFromPHKey(key, revk, depth, start, type);
|
||||
assert(revd == depth );
|
||||
if( revk[0]!=ik[0] || revk[1]!=ik[1])
|
||||
Warning("ik=(%x %x) -> %s -> revk=(%x %x)\n",
|
||||
ik[0], ik[1],
|
||||
PrintKey(key),
|
||||
revk[0], revk[1]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Test each key starting at 0. Make sure that
|
||||
KeyFromInts(IntsFromKey(k))==k */
|
||||
printf("%%!\n");
|
||||
printf("/L {2 copy lineto stroke moveto pop} def\n");
|
||||
printf("72 72 translate\n");
|
||||
printf("%%scale to 6 inches width, hgt\n");
|
||||
printf("%g %g scale\n", 72.*SZ/(1<<depth), 72.*SZ/(1<<depth));
|
||||
printf("%% line width of 1pt\n");
|
||||
printf("%g setlinewidth\n", (1<<depth)/(SZ*72));
|
||||
printf("0 0 moveto\n");
|
||||
|
||||
base = KeyLshift(KeyInt(1), depth*NDIM);
|
||||
for(ikey=0; ikey < (1<<(NDIM*depth)); ikey++){
|
||||
Key_t revkey;
|
||||
unsigned int di[NDIM];
|
||||
unsigned int iklast[NDIM];
|
||||
int d2;
|
||||
|
||||
revd = _IntsFromPHKey(base, ik, depth, start, type);
|
||||
assert(revd == depth);
|
||||
revkey = _PHKeyFromInts(ik, depth, start, type);
|
||||
if( KeyNEQ(revkey, base)){
|
||||
char s[64];
|
||||
strcpy(s, PrintKey(revkey));
|
||||
Warning("key %s -> %x %x -> %s\n",
|
||||
PrintKey(base), ik[0], ik[1], s);
|
||||
}
|
||||
printf("%d %d %d L\n", i, ik[0], ik[1]);
|
||||
VVV(di, = ik, - iklast);
|
||||
d2 = Dot(di, di);
|
||||
if( d2 != 1 && ikey ){
|
||||
Warning("Move by more than 1 at ikey=%#0o\n", ikey);
|
||||
}
|
||||
|
||||
VV(iklast, = ik);
|
||||
base = KeyAddInt(base, 1);
|
||||
}
|
||||
printf("showpage\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
#endif /* NDIM==2 */
|
||||
#endif /* STANDALONE */
|
225
external/libsdf/libsw/poll.1.c
vendored
Normal file
225
external/libsdf/libsw/poll.1.c
vendored
Normal file
|
@ -0,0 +1,225 @@
|
|||
#include <string.h>
|
||||
#include "mpmy.h"
|
||||
#include "Msgs.h"
|
||||
#include "assert.h"
|
||||
#include "gc.h"
|
||||
#include "timers.h"
|
||||
#include "error.h"
|
||||
#include "Malloc.h"
|
||||
#include "dll.h"
|
||||
#include "chn.h"
|
||||
#include "poll.h"
|
||||
|
||||
#define INBUFSZ (16384*sizeof(int))
|
||||
#define MAXRELAY 4096
|
||||
#define MAXLOCAL 64
|
||||
#define MAXREMOTE 2048
|
||||
Timer_t PollWaitTm;
|
||||
|
||||
static void (*func)();
|
||||
static int size;
|
||||
static int polldone;
|
||||
static int localdone;
|
||||
static int remotedone;
|
||||
static int localid;
|
||||
static int nremote;
|
||||
static int nrelay_active;
|
||||
static int nrelay_highwater;
|
||||
static MPMY_Comm_request inreq;
|
||||
static char localpoll[MAXLOCAL];
|
||||
static char remotepoll[MAXREMOTE];
|
||||
static int *relaybuf[MAXRELAY];
|
||||
static int inbuf[INBUFSZ/sizeof(int)]; /* avoid using malloc */
|
||||
|
||||
static void
|
||||
process(int count, int tag)
|
||||
{
|
||||
int dest = inbuf[0];
|
||||
|
||||
if (dest < 0 || dest >= MPMY_Nproc()) {
|
||||
Error("Bad dest in Poll()\n");
|
||||
}
|
||||
if (dest != MPMY_Procnum()) { /* relay */
|
||||
MPMY_Comm_request req;
|
||||
|
||||
Msgf(("PollRelay: %d to %d using buffer %d\n", count, dest, nrelay_active));
|
||||
if (nrelay_active > MAXRELAY) Error("Out of relay buffers\n");
|
||||
memcpy(relaybuf[nrelay_active], inbuf, count);
|
||||
MPMY_Isend(relaybuf[nrelay_active++], count, dest, tag, &req);
|
||||
if (nrelay_active > nrelay_highwater) nrelay_highwater = nrelay_active;
|
||||
MPMY_Irecv(&inbuf, size, MPMY_SOURCE_ANY, tag, &inreq);
|
||||
/* This should be something more like a select() to free intermediate buffers */
|
||||
PollWait(req, tag);
|
||||
if (--nrelay_active < 0) Error("Bad value for nrelay_active\n");
|
||||
} else if (count == 2*sizeof(int)) {
|
||||
int src = inbuf[1];
|
||||
if (src < 0 || src >= MAXLOCAL+MAXREMOTE) {
|
||||
Error("Bad src in Poll()\n");
|
||||
}
|
||||
Msgf(("PollDone msg from %d\n", src));
|
||||
if (localid) polldone = 1;
|
||||
else if (src < MAXLOCAL) {
|
||||
/* local done message */
|
||||
if (src >= MPMY_ProcsPerNode()) Error("Bad src in Poll()\n");
|
||||
if (localpoll[src])
|
||||
Error("localpoll[%d] already set!\n", src);
|
||||
if (localdone >= MPMY_ProcsPerNode()) Error("localdone already acheived\n");
|
||||
localpoll[src] = 1;
|
||||
localdone++;
|
||||
Msgf(("Poll: localdone is %d\n", localdone));
|
||||
} else {
|
||||
/* remote done message */
|
||||
src -= MAXLOCAL;
|
||||
if (src >= nremote) Error("Bad src in Poll()\n");
|
||||
if (remotepoll[src])
|
||||
Error("remotepoll[%d] already set!\n", src);
|
||||
if (remotedone >= nremote) Error("remotedone already acheived\n");
|
||||
remotepoll[src] = 1;
|
||||
if (++remotedone >= nremote) polldone = 1;
|
||||
Msgf(("Poll: remotedone is %d\n", remotedone));
|
||||
}
|
||||
MPMY_Irecv(&inbuf, size, MPMY_SOURCE_ANY, tag, &inreq);
|
||||
} else {
|
||||
Msgf(("PollProcess: %d\n", count));
|
||||
func(inbuf+1, count-sizeof(int));
|
||||
MPMY_Irecv(&inbuf, size, MPMY_SOURCE_ANY, tag, &inreq);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PollSetup(void put(void *buf, int size), int max_size, int tag)
|
||||
{
|
||||
int i;
|
||||
int procs_per_node = MPMY_ProcsPerNode();
|
||||
|
||||
Msgf(("PollSetup\n"));
|
||||
func = put;
|
||||
if (max_size > INBUFSZ) SinglError("INBUFSZ too small\n");
|
||||
if (procs_per_node > MAXLOCAL) SinglError("MAXLOCAL too small\n");
|
||||
if ((MPMY_Nproc()-1)/procs_per_node >= MAXREMOTE) SinglError("MAXREMOTE too small\n");
|
||||
nrelay_active = nrelay_highwater = polldone = localdone = remotedone = 0;
|
||||
localid = MPMY_Procnum() % procs_per_node;
|
||||
nremote = (MPMY_Nproc() + procs_per_node - 1) / procs_per_node;
|
||||
for (i = 0; i < procs_per_node; i++) localpoll[i] = 0;
|
||||
for (i = 0; i < nremote; i++) remotepoll[i] = 0;
|
||||
if (MPMY_Nproc() % procs_per_node) {
|
||||
if (MPMY_Procnum() == MPMY_Nproc() - 1) {
|
||||
for (i = MPMY_Nproc() % procs_per_node; i < procs_per_node; i++) {
|
||||
localpoll[i] = 1;
|
||||
++localdone;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (localid == 0) {
|
||||
for (i = 0; i < MAXRELAY; i++) {
|
||||
relaybuf[i] = Malloc(INBUFSZ);
|
||||
}
|
||||
}
|
||||
|
||||
/* In fact, this test is insufficient if somebody decides to send
|
||||
a short message anyway we'll still be confused! */
|
||||
if (max_size == sizeof(int) || max_size == 2*sizeof(int))
|
||||
SinglError("Poll uses size for message sorting. You can't use size=%ld or %ld without some new coding\n", (long)sizeof(int), (long)2*sizeof(int));
|
||||
|
||||
size = max_size;
|
||||
MPMY_Irecv(&inbuf, size, MPMY_SOURCE_ANY, tag, &inreq);
|
||||
}
|
||||
|
||||
void
|
||||
Poll(int tag)
|
||||
{
|
||||
int flag;
|
||||
MPMY_Status stat;
|
||||
|
||||
Msgf(("P(tag=%d)\n", tag));
|
||||
MPMY_Flick();
|
||||
while (MPMY_Test(inreq, &flag, &stat), flag) {
|
||||
process(stat.count, tag);
|
||||
}
|
||||
}
|
||||
|
||||
/* If we use a plain MPMY_Wait() during a poll session, deadlock may */
|
||||
/* result from isends blocking */
|
||||
void
|
||||
PollWait(MPMY_Comm_request req, int tag)
|
||||
{
|
||||
int flag;
|
||||
MPMY_Status stat;
|
||||
|
||||
Msgf(("PW(tag=%d)\n", tag));
|
||||
while (1) {
|
||||
if (MPMY_Test(req, &flag, 0), flag) return;
|
||||
if (MPMY_Test(inreq, &flag, &stat), flag) process(stat.count, tag);
|
||||
MPMY_Flick();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PollUntilDone(int tag)
|
||||
{
|
||||
MPMY_Comm_request req;
|
||||
MPMY_Status stat;
|
||||
int buf[2];
|
||||
int i;
|
||||
int procnum = MPMY_Procnum();
|
||||
int procs_per_node = MPMY_ProcsPerNode();
|
||||
|
||||
Msg("polldone", ("PUD(tag=%d)\n", tag));
|
||||
StartTimer(&PollWaitTm);
|
||||
if (localid == 0) {
|
||||
/* I'm a group master */
|
||||
if (localpoll[0]) Error("localpoll[0] already set!\n");
|
||||
localpoll[0] = 1;
|
||||
++localdone;
|
||||
while (localdone != procs_per_node) { /* not right if Nproc() % procs_per_node */
|
||||
MPMY_Wait(inreq, &stat);
|
||||
process(stat.count, tag);
|
||||
}
|
||||
Msg("polldone", ("PollDone local group finished\n"));
|
||||
/* Tell masters our group is done */
|
||||
for (i = 0; i < nremote; i++) {
|
||||
buf[0] = i*procs_per_node;
|
||||
buf[1] = MAXLOCAL + MPMY_Procnum() / procs_per_node;
|
||||
Msg("polldone", ("PollDone sent to remote master %d\n", i*procs_per_node));
|
||||
MPMY_Isend(buf, 2*sizeof(int), i*procs_per_node, tag, &req);
|
||||
PollWait(req, tag);
|
||||
}
|
||||
while (!polldone) {
|
||||
MPMY_Wait(inreq, &stat);
|
||||
process(stat.count, tag);
|
||||
}
|
||||
/* Tell local group we are done */
|
||||
for (i = MPMY_Procnum()+1; i < MPMY_Procnum()+procs_per_node && i < MPMY_Nproc(); i++) {
|
||||
buf[0] = i;
|
||||
buf[1] = 0;
|
||||
Msg("polldone", ("PollDone sent to %d\n", i));
|
||||
MPMY_Isend(buf, 2*sizeof(int), i, tag, &req);
|
||||
PollWait(req, tag);
|
||||
}
|
||||
} else {
|
||||
/* I'm a slave in the local group */
|
||||
int dest = (procnum / procs_per_node) * procs_per_node;
|
||||
buf[0] = dest;
|
||||
buf[1] = localid;
|
||||
/* Tell local master we're done */
|
||||
Msg("polldone", ("PollDone sent to local master %d\n", dest));
|
||||
MPMY_Isend(buf, 2*sizeof(int), dest, tag, &req);
|
||||
PollWait(req, tag);
|
||||
while (!polldone) {
|
||||
MPMY_Wait(inreq, &stat);
|
||||
process(stat.count, tag);
|
||||
}
|
||||
}
|
||||
/* self send to clean up inreq */
|
||||
MPMY_Isend(buf, sizeof(int), MPMY_Procnum(), tag, &req);
|
||||
MPMY_Wait(req, 0);
|
||||
MPMY_Wait(inreq, 0);
|
||||
StopTimer(&PollWaitTm);
|
||||
if (localid == 0) {
|
||||
for (i = 0; i < MAXRELAY; i++) {
|
||||
Free(relaybuf[i]);
|
||||
}
|
||||
}
|
||||
Msgf(("PollDone, nrelay_highwater = %d\n", nrelay_highwater));
|
||||
}
|
244
external/libsdf/libsw/poll.c
vendored
Normal file
244
external/libsdf/libsw/poll.c
vendored
Normal file
|
@ -0,0 +1,244 @@
|
|||
#include <string.h>
|
||||
#include "mpmy.h"
|
||||
#include "Msgs.h"
|
||||
#include "assert.h"
|
||||
#include "gc.h"
|
||||
#include "timers.h"
|
||||
#include "error.h"
|
||||
#include "dll.h"
|
||||
#include "chn.h"
|
||||
#include "poll.h"
|
||||
|
||||
#define INBUFSZ (16384*sizeof(int))
|
||||
#define MAXRELAY 512
|
||||
#define MAXLOCAL 64
|
||||
#define MAXREMOTE 2048
|
||||
Timer_t PollWaitTm;
|
||||
|
||||
static void (*func)();
|
||||
static int size;
|
||||
static int polldone;
|
||||
static int localdone;
|
||||
static int remotedone;
|
||||
static int localid;
|
||||
static int nremote;
|
||||
static MPMY_Comm_request inreq;
|
||||
static char localpoll[MAXLOCAL];
|
||||
static char remotepoll[MAXREMOTE];
|
||||
static int bufused[MAXRELAY];
|
||||
MPMY_Comm_request Rreq[MAXRELAY];
|
||||
static int relaybuf[MAXRELAY][INBUFSZ/sizeof(int)];
|
||||
static int inbuf[INBUFSZ/sizeof(int)]; /* avoid using malloc */
|
||||
|
||||
static int
|
||||
allocbuf(void)
|
||||
{
|
||||
int i;
|
||||
int flag;
|
||||
int inuse;
|
||||
|
||||
inuse = 0;
|
||||
for (i = 0; i < MAXRELAY; i++) {
|
||||
if (bufused[i] == 1) {
|
||||
if (MPMY_Test(Rreq[i], &flag, 0), flag) {
|
||||
bufused[i] = 0;
|
||||
} else inuse++;
|
||||
}
|
||||
}
|
||||
Msgf(("%d relay inuse\n", ++inuse));
|
||||
for (i = 0; i < MAXRELAY; i++) {
|
||||
if (bufused[i] == 0) {
|
||||
bufused[i] = 1;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
Error("Out of relay buffers\n");
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
process(int count, int tag)
|
||||
{
|
||||
int dest = inbuf[0];
|
||||
|
||||
if (dest < 0 || dest >= MPMY_Nproc()) {
|
||||
Error("Bad dest in Poll()\n");
|
||||
}
|
||||
if (dest != MPMY_Procnum()) { /* relay */
|
||||
int i;
|
||||
i = allocbuf();
|
||||
Msgf(("PollRelay: %d to %d using buffer %d\n", count, dest, i));
|
||||
memcpy(relaybuf[i], inbuf, count);
|
||||
MPMY_Isend(relaybuf[i], count, dest, tag, Rreq+i);
|
||||
MPMY_Irecv(&inbuf, size, MPMY_SOURCE_ANY, tag, &inreq);
|
||||
} else if (count == 2*sizeof(int)) {
|
||||
int src = inbuf[1];
|
||||
if (src < 0 || src >= MAXLOCAL+MAXREMOTE) {
|
||||
Error("Bad src in Poll()\n");
|
||||
}
|
||||
Msgf(("PollDone msg from %d\n", src));
|
||||
if (localid) polldone = 1;
|
||||
else if (src < MAXLOCAL) {
|
||||
/* local done message */
|
||||
if (src >= MPMY_ProcsPerNode()) Error("Bad src in Poll()\n");
|
||||
if (localpoll[src])
|
||||
Error("localpoll[%d] already set!\n", src);
|
||||
if (localdone >= MPMY_ProcsPerNode()) Error("localdone already acheived\n");
|
||||
localpoll[src] = 1;
|
||||
localdone++;
|
||||
Msgf(("Poll: localdone is %d\n", localdone));
|
||||
} else {
|
||||
/* remote done message */
|
||||
src -= MAXLOCAL;
|
||||
if (src >= nremote) Error("Bad src in Poll()\n");
|
||||
if (remotepoll[src])
|
||||
Error("remotepoll[%d] already set!\n", src);
|
||||
if (remotedone >= nremote) Error("remotedone already acheived\n");
|
||||
remotepoll[src] = 1;
|
||||
if (++remotedone >= nremote) polldone = 1;
|
||||
Msgf(("Poll: remotedone is %d\n", remotedone));
|
||||
}
|
||||
MPMY_Irecv(&inbuf, size, MPMY_SOURCE_ANY, tag, &inreq);
|
||||
} else {
|
||||
Msgf(("PollProcess: %d\n", count));
|
||||
func(inbuf+1, count-sizeof(int));
|
||||
MPMY_Irecv(&inbuf, size, MPMY_SOURCE_ANY, tag, &inreq);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PollSetup(void put(void *buf, int size), int max_size, int tag)
|
||||
{
|
||||
int i;
|
||||
int procs_per_node = MPMY_ProcsPerNode();
|
||||
|
||||
Msgf(("PollSetup\n"));
|
||||
func = put;
|
||||
if (max_size > INBUFSZ) SinglError("INBUFSZ too small\n");
|
||||
if (procs_per_node > MAXLOCAL) SinglError("MAXLOCAL too small\n");
|
||||
if ((MPMY_Nproc()-1)/procs_per_node >= MAXREMOTE) SinglError("MAXREMOTE too small\n");
|
||||
polldone = localdone = remotedone = 0;
|
||||
localid = MPMY_Procnum() % procs_per_node;
|
||||
nremote = (MPMY_Nproc() + procs_per_node - 1) / procs_per_node;
|
||||
for (i = 0; i < procs_per_node; i++) localpoll[i] = 0;
|
||||
for (i = 0; i < nremote; i++) remotepoll[i] = 0;
|
||||
for (i = 0; i < MAXRELAY; i++) bufused[i] = 0;
|
||||
if (MPMY_Nproc() % procs_per_node) {
|
||||
if (MPMY_Procnum() == MPMY_Nproc() - 1) {
|
||||
for (i = MPMY_Nproc() % procs_per_node; i < procs_per_node; i++) {
|
||||
localpoll[i] = 1;
|
||||
++localdone;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* In fact, this test is insufficient if somebody decides to send
|
||||
a short message anyway we'll still be confused! */
|
||||
if (max_size == sizeof(int) || max_size == 2*sizeof(int))
|
||||
SinglError("Poll uses size for message sorting. You can't use size=%ld or %ld without some new coding\n", (long)sizeof(int), (long)2*sizeof(int));
|
||||
|
||||
size = max_size;
|
||||
MPMY_Irecv(&inbuf, size, MPMY_SOURCE_ANY, tag, &inreq);
|
||||
}
|
||||
|
||||
void
|
||||
Poll(int tag)
|
||||
{
|
||||
int flag;
|
||||
MPMY_Status stat;
|
||||
|
||||
Msgf(("P(tag=%d)\n", tag));
|
||||
while (MPMY_Test(inreq, &flag, &stat), flag) {
|
||||
process(stat.count, tag);
|
||||
MPMY_Flick();
|
||||
}
|
||||
}
|
||||
|
||||
/* If we use a plain MPMY_Wait() during a poll session, deadlock may */
|
||||
/* result from isends blocking */
|
||||
void
|
||||
PollWait(MPMY_Comm_request req, int tag)
|
||||
{
|
||||
int flag;
|
||||
MPMY_Status stat;
|
||||
|
||||
Msgf(("PW(tag=%d)\n", tag));
|
||||
while (1) {
|
||||
if (MPMY_Test(req, &flag, 0), flag) return;
|
||||
if (MPMY_Test(inreq, &flag, &stat), flag) process(stat.count, tag);
|
||||
MPMY_Flick();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PollUntilDone(int tag)
|
||||
{
|
||||
MPMY_Comm_request req;
|
||||
MPMY_Status stat;
|
||||
int buf[2];
|
||||
int i;
|
||||
int procnum = MPMY_Procnum();
|
||||
int procs_per_node = MPMY_ProcsPerNode();
|
||||
|
||||
Msg("polldone", ("PUD(tag=%d)\n", tag));
|
||||
StartTimer(&PollWaitTm);
|
||||
if (localid == 0) {
|
||||
/* I'm a group master */
|
||||
if (localpoll[0]) Error("localpoll[0] already set!\n");
|
||||
localpoll[0] = 1;
|
||||
++localdone;
|
||||
while (localdone != procs_per_node) { /* not right if Nproc() % procs_per_node */
|
||||
MPMY_Wait(inreq, &stat);
|
||||
process(stat.count, tag);
|
||||
}
|
||||
Msg("polldone", ("PollDone local group finished\n"));
|
||||
/* Tell masters our group is done */
|
||||
for (i = 0; i < nremote; i++) {
|
||||
buf[0] = i*procs_per_node;
|
||||
buf[1] = MAXLOCAL + MPMY_Procnum() / procs_per_node;
|
||||
Msg("polldone", ("PollDone sent to remote master %d\n", i*procs_per_node));
|
||||
MPMY_Isend(buf, 2*sizeof(int), i*procs_per_node, tag, &req);
|
||||
PollWait(req, tag);
|
||||
}
|
||||
while (!polldone) {
|
||||
MPMY_Wait(inreq, &stat);
|
||||
process(stat.count, tag);
|
||||
for (i = 0; i < MAXRELAY; i++) {
|
||||
int flag;
|
||||
if (bufused[i] == 1) {
|
||||
if (MPMY_Test(Rreq[i], &flag, 0), flag) {
|
||||
bufused[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Tell local group we are done */
|
||||
for (i = MPMY_Procnum()+1; i < MPMY_Procnum()+procs_per_node && i < MPMY_Nproc(); i++) {
|
||||
buf[0] = i;
|
||||
buf[1] = 0;
|
||||
Msg("polldone", ("PollDone sent to %d\n", i));
|
||||
MPMY_Isend(buf, 2*sizeof(int), i, tag, &req);
|
||||
PollWait(req, tag);
|
||||
}
|
||||
} else {
|
||||
/* I'm a slave in the local group */
|
||||
int dest = (procnum / procs_per_node) * procs_per_node;
|
||||
buf[0] = dest;
|
||||
buf[1] = localid;
|
||||
/* Tell local master we're done */
|
||||
Msg("polldone", ("PollDone sent to local master %d\n", dest));
|
||||
MPMY_Isend(buf, 2*sizeof(int), dest, tag, &req);
|
||||
PollWait(req, tag);
|
||||
while (!polldone) {
|
||||
MPMY_Wait(inreq, &stat);
|
||||
process(stat.count, tag);
|
||||
}
|
||||
}
|
||||
/* self send to clean up inreq */
|
||||
MPMY_Isend(buf, sizeof(int), MPMY_Procnum(), tag, &req);
|
||||
MPMY_Wait(req, 0);
|
||||
MPMY_Wait(inreq, 0);
|
||||
StopTimer(&PollWaitTm);
|
||||
Msgf(("PollDone\n"));
|
||||
}
|
111
external/libsdf/libsw/qromo.c
vendored
Normal file
111
external/libsdf/libsw/qromo.c
vendored
Normal file
|
@ -0,0 +1,111 @@
|
|||
#include <math.h>
|
||||
#include "Malloc.h"
|
||||
#include "error.h"
|
||||
#include "qromo.h"
|
||||
|
||||
#define NR_END 1
|
||||
|
||||
static float *vector(long nl, long nh)
|
||||
/* allocate a float vector with subscript range v[nl..nh] */
|
||||
{
|
||||
float *v;
|
||||
|
||||
v = Malloc((nh-nl+1+NR_END)*sizeof(float));
|
||||
return v-nl+NR_END;
|
||||
}
|
||||
|
||||
static void free_vector(v,nl,nh)
|
||||
float *v;
|
||||
long nh,nl;
|
||||
/* free a float vector allocated with vector() */
|
||||
{
|
||||
Free(v+nl-NR_END);
|
||||
}
|
||||
|
||||
void polint(float xa[], float ya[], int n, float x, float *y, float *dy)
|
||||
{
|
||||
int i,m,ns=1;
|
||||
float den,dif,dift,ho,hp,w;
|
||||
float *c,*d;
|
||||
|
||||
dif=fabs(x-xa[1]);
|
||||
c=vector(1,n);
|
||||
d=vector(1,n);
|
||||
for (i=1;i<=n;i++) {
|
||||
if ( (dift=fabs(x-xa[i])) < dif) {
|
||||
ns=i;
|
||||
dif=dift;
|
||||
}
|
||||
c[i]=ya[i];
|
||||
d[i]=ya[i];
|
||||
}
|
||||
*y=ya[ns--];
|
||||
for (m=1;m<n;m++) {
|
||||
for (i=1;i<=n-m;i++) {
|
||||
ho=xa[i]-x;
|
||||
hp=xa[i+m]-x;
|
||||
w=c[i+1]-d[i];
|
||||
if ( (den=ho-hp) == 0.0) Error("Error in routine polint");
|
||||
den=w/den;
|
||||
d[i]=hp*den;
|
||||
c[i]=ho*den;
|
||||
}
|
||||
*y += (*dy=(2*ns < (n-m) ? c[ns+1] : d[ns--]));
|
||||
}
|
||||
free_vector(d,1,n);
|
||||
free_vector(c,1,n);
|
||||
}
|
||||
|
||||
#define FUNC(x) ((*func)(x))
|
||||
|
||||
float midpnt(float (*func)(float), float a, float b, int n)
|
||||
{
|
||||
float x,tnm,sum,del,ddel;
|
||||
static float s;
|
||||
int it,j;
|
||||
|
||||
if (n == 1) {
|
||||
return (s=(b-a)*FUNC(0.5*(a+b)));
|
||||
} else {
|
||||
for(it=1,j=1;j<n-1;j++) it *= 3;
|
||||
tnm=it;
|
||||
del=(b-a)/(3.0*tnm);
|
||||
ddel=del+del;
|
||||
x=a+0.5*del;
|
||||
sum=0.0;
|
||||
for (j=1;j<=it;j++) {
|
||||
sum += FUNC(x);
|
||||
x += ddel;
|
||||
sum += FUNC(x);
|
||||
x += del;
|
||||
}
|
||||
s=(s+(b-a)*sum/tnm)/3.0;
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
#define EPS 1.0e-6
|
||||
#define JMAX 14
|
||||
#define JMAXP (JMAX+1)
|
||||
#define K 5
|
||||
|
||||
float qromo(float (*func)(float), float a, float b,
|
||||
float (*choose)(float(*)(float), float, float, int))
|
||||
{
|
||||
|
||||
int j;
|
||||
float ss,dss,h[JMAXP+1],s[JMAXP+1];
|
||||
|
||||
h[1]=1.0;
|
||||
for (j=1;j<=JMAX;j++) {
|
||||
s[j]=(*choose)(func,a,b,j);
|
||||
if (j >= K) {
|
||||
polint(&h[j-K],&s[j-K],K,0.0,&ss,&dss);
|
||||
if (fabs(dss) < EPS*fabs(ss)) return ss;
|
||||
}
|
||||
s[j+1]=s[j];
|
||||
h[j+1]=h[j]/9.0;
|
||||
}
|
||||
Error("Too many steps in routing qromo");
|
||||
return 0.0;
|
||||
}
|
111
external/libsdf/libsw/qromod.c
vendored
Normal file
111
external/libsdf/libsw/qromod.c
vendored
Normal file
|
@ -0,0 +1,111 @@
|
|||
#include <math.h>
|
||||
#include "Malloc.h"
|
||||
#include "error.h"
|
||||
#include "qromo.h"
|
||||
|
||||
#define NR_END 1
|
||||
|
||||
static double *vector(long nl, long nh)
|
||||
/* allocate a double vector with subscript range v[nl..nh] */
|
||||
{
|
||||
double *v;
|
||||
|
||||
v = Malloc((nh-nl+1+NR_END)*sizeof(double));
|
||||
return v-nl+NR_END;
|
||||
}
|
||||
|
||||
static void free_vector(v,nl,nh)
|
||||
double *v;
|
||||
long nh,nl;
|
||||
/* free a double vector allocated with vector() */
|
||||
{
|
||||
Free(v+nl-NR_END);
|
||||
}
|
||||
|
||||
void polintd(double xa[], double ya[], int n, double x, double *y, double *dy)
|
||||
{
|
||||
int i,m,ns=1;
|
||||
double den,dif,dift,ho,hp,w;
|
||||
double *c,*d;
|
||||
|
||||
dif=fabs(x-xa[1]);
|
||||
c=vector(1,n);
|
||||
d=vector(1,n);
|
||||
for (i=1;i<=n;i++) {
|
||||
if ( (dift=fabs(x-xa[i])) < dif) {
|
||||
ns=i;
|
||||
dif=dift;
|
||||
}
|
||||
c[i]=ya[i];
|
||||
d[i]=ya[i];
|
||||
}
|
||||
*y=ya[ns--];
|
||||
for (m=1;m<n;m++) {
|
||||
for (i=1;i<=n-m;i++) {
|
||||
ho=xa[i]-x;
|
||||
hp=xa[i+m]-x;
|
||||
w=c[i+1]-d[i];
|
||||
if ( (den=ho-hp) == 0.0) Error("Error in routine polint");
|
||||
den=w/den;
|
||||
d[i]=hp*den;
|
||||
c[i]=ho*den;
|
||||
}
|
||||
*y += (*dy=(2*ns < (n-m) ? c[ns+1] : d[ns--]));
|
||||
}
|
||||
free_vector(d,1,n);
|
||||
free_vector(c,1,n);
|
||||
}
|
||||
|
||||
#define FUNC(x) ((*func)(x))
|
||||
|
||||
double midpntd(double (*func)(double), double a, double b, int n)
|
||||
{
|
||||
double x,tnm,sum,del,ddel;
|
||||
static double s;
|
||||
int it,j;
|
||||
|
||||
if (n == 1) {
|
||||
return (s=(b-a)*FUNC(0.5*(a+b)));
|
||||
} else {
|
||||
for(it=1,j=1;j<n-1;j++) it *= 3;
|
||||
tnm=it;
|
||||
del=(b-a)/(3.0*tnm);
|
||||
ddel=del+del;
|
||||
x=a+0.5*del;
|
||||
sum=0.0;
|
||||
for (j=1;j<=it;j++) {
|
||||
sum += FUNC(x);
|
||||
x += ddel;
|
||||
sum += FUNC(x);
|
||||
x += del;
|
||||
}
|
||||
s=(s+(b-a)*sum/tnm)/3.0;
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
#define EPS 1.0e-12
|
||||
#define JMAX 20
|
||||
#define JMAXP (JMAX+1)
|
||||
#define K 5
|
||||
|
||||
double qromod(double (*func)(double), double a, double b,
|
||||
double (*choose)(double(*)(double), double, double, int))
|
||||
{
|
||||
|
||||
int j;
|
||||
double ss,dss,h[JMAXP+1],s[JMAXP+1];
|
||||
|
||||
h[1]=1.0;
|
||||
for (j=1;j<=JMAX;j++) {
|
||||
s[j]=(*choose)(func,a,b,j);
|
||||
if (j >= K) {
|
||||
polintd(&h[j-K],&s[j-K],K,0.0,&ss,&dss);
|
||||
if (fabs(dss) < EPS*fabs(ss)) return ss;
|
||||
}
|
||||
s[j+1]=s[j];
|
||||
h[j+1]=h[j]/9.0;
|
||||
}
|
||||
Error("Too many steps in routine qromod\n");
|
||||
return 0.0;
|
||||
}
|
6
external/libsdf/libsw/raise.c
vendored
Normal file
6
external/libsdf/libsw/raise.c
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
|
||||
int raise(int sig){
|
||||
return kill(getpid(), sig);
|
||||
}
|
126
external/libsdf/libsw/randoms.c
vendored
Normal file
126
external/libsdf/libsw/randoms.c
vendored
Normal file
|
@ -0,0 +1,126 @@
|
|||
#include "error.h"
|
||||
#include "randoms.h"
|
||||
|
||||
/* ran2 from Numerical Recipes 2nd ed. modified to conform to our interface */
|
||||
/* You win $1000 from Press et al. if it fails non-trivially */
|
||||
|
||||
#define IM1 2147483563
|
||||
#define IM2 2147483399
|
||||
#define AM (1.0/IM1)
|
||||
#define IMM1 (IM1-1)
|
||||
#define IA1 40014
|
||||
#define IA2 40692
|
||||
#define IQ1 53668
|
||||
#define IQ2 52774
|
||||
#define IR1 12211
|
||||
#define IR2 3791
|
||||
#define NDIV (1+IMM1/NTAB)
|
||||
#define EPS 1.2e-7
|
||||
#define RNMX (1.0-EPS)
|
||||
|
||||
void
|
||||
ran_init(int seed, ran_state *s)
|
||||
{
|
||||
int j;
|
||||
long k;
|
||||
|
||||
if (seed < 1)
|
||||
Error("Bad seed in ran_init2 (%d)\n", seed);
|
||||
s->idum = s->idum2 = seed;
|
||||
s->next_norml_ok = 0;
|
||||
for (j=NTAB+7;j>=0;j--) {
|
||||
k=(s->idum)/IQ1;
|
||||
s->idum=IA1*(s->idum-k*IQ1)-k*IR1;
|
||||
if (s->idum < 0) s->idum += IM1;
|
||||
if (j < NTAB) s->iv[j] = s->idum;
|
||||
}
|
||||
s->iy=s->iv[0];
|
||||
s->did_init = IQ1;
|
||||
}
|
||||
|
||||
float
|
||||
uniform_rand(ran_state *s)
|
||||
{
|
||||
int j;
|
||||
long k;
|
||||
float temp;
|
||||
|
||||
if (s->did_init != IQ1)
|
||||
Error("You forgot to call ran_init2\n");
|
||||
k=(s->idum)/IQ1;
|
||||
s->idum=IA1*(s->idum-k*IQ1)-k*IR1;
|
||||
if (s->idum < 0) s->idum += IM1;
|
||||
k=s->idum2/IQ2;
|
||||
s->idum2=IA2*(s->idum2-k*IQ2)-k*IR2;
|
||||
if (s->idum2 < 0) s->idum2 += IM2;
|
||||
j=s->iy/NDIV;
|
||||
s->iy=s->iv[j]-s->idum2;
|
||||
s->iv[j] = s->idum;
|
||||
if (s->iy < 1) s->iy += IMM1;
|
||||
if ((temp=AM*s->iy) > RNMX) return RNMX;
|
||||
else return temp;
|
||||
}
|
||||
|
||||
float normal_rand(ran_state *st)
|
||||
/*
|
||||
This is the Polar method for normal distributions, as described on or near
|
||||
page 104 of Knuth, Semi-numerical Algorithms. To quote Knuth, "The polar
|
||||
method is quite slow, but it has essentially perfect accuracy, and it is very
|
||||
easy to write a program for the polar method..." 'nuf said. Algorithm due
|
||||
to Box, Muller and Marsaglia.
|
||||
*/
|
||||
{
|
||||
float v1, v2; /* uniformly distributed on [-1, 1) */
|
||||
float s; /* radius of a point pulled from a uniform circle */
|
||||
float foo; /* A useful intermediate value. */
|
||||
double log(double), sqrt(double);
|
||||
|
||||
if(st->next_norml_ok){
|
||||
st->next_norml_ok = 0;
|
||||
return st->next_norml;
|
||||
}
|
||||
|
||||
do{
|
||||
v1 = 2.0F * uniform_rand(st) - 1.0F;
|
||||
v2 = 2.0F * uniform_rand(st) - 1.0F;
|
||||
s = v1*v1 + v2*v2;
|
||||
} while(s >= 1.0F);
|
||||
foo = sqrt( -2.0F * log(s)/s);
|
||||
st->next_norml_ok = 1;
|
||||
st->next_norml = v1*foo;
|
||||
return v2*foo;
|
||||
}
|
||||
|
||||
/* Return a uniform point in a ndim-sphere by rejection. */
|
||||
/* If ndim is large (bigger than 4 or so), this becomes very inefficient */
|
||||
/* Return the radius-squard of the result. */
|
||||
float sphere_rand(ran_state *st, int ndim, float *x)
|
||||
{
|
||||
int k;
|
||||
float rsqx;
|
||||
|
||||
do {
|
||||
rsqx = (float)0.0;
|
||||
for (k = 0; k < ndim; k++) {
|
||||
x[k] = uniform_rand(st)*2.0F - 1.0F; /* a pt in (-1,1) */
|
||||
rsqx += x[k] * x[k];
|
||||
}
|
||||
} while (rsqx > (float)1.0);
|
||||
return rsqx;
|
||||
}
|
||||
|
||||
/* Return a uniform point in a ndim-cube */
|
||||
/* Return the radius-squard of the result. */
|
||||
float cube_rand(ran_state *st, int ndim, float *x)
|
||||
{
|
||||
int k;
|
||||
float rsqx;
|
||||
|
||||
rsqx = (float)0.0;
|
||||
for (k = 0; k < ndim; k++) {
|
||||
x[k] = uniform_rand(st)*2.0F - 1.0F; /* a pt in (-1,1) */
|
||||
rsqx += x[k] * x[k];
|
||||
}
|
||||
return rsqx;
|
||||
}
|
||||
|
153
external/libsdf/libsw/ring.c
vendored
Normal file
153
external/libsdf/libsw/ring.c
vendored
Normal file
|
@ -0,0 +1,153 @@
|
|||
#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);
|
||||
}
|
93
external/libsdf/libsw/rsort.c
vendored
Normal file
93
external/libsdf/libsw/rsort.c
vendored
Normal file
|
@ -0,0 +1,93 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "Malloc.h"
|
||||
#include "key.h"
|
||||
|
||||
#define pswap(a, b, sz) do { \
|
||||
char _c[sz]; \
|
||||
memcpy((void *)&_c, (void *)a, sz); \
|
||||
memcpy((void *)a, (void *)b, sz); \
|
||||
memcpy((void *)b, (void *)&_c, sz); \
|
||||
} while (0)
|
||||
|
||||
#define STACKSIZE 16384
|
||||
|
||||
/* Only need to continue if there is more than 1 element */
|
||||
#define push(_shift, _offset, _n) \
|
||||
if (_n > 1LL && _shift >= 0) { \
|
||||
sp->shift = _shift; \
|
||||
sp->offset = _offset; \
|
||||
(sp++)->n = _n; \
|
||||
if (sp >= stack+STACKSIZE) Error("Stack overflow\n"); \
|
||||
}
|
||||
|
||||
#define pop(_shift, _offset, _n) do { \
|
||||
_shift = (--sp)->shift; \
|
||||
_offset = sp->offset; \
|
||||
_n = sp->n; \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* insertion sort for small lists */
|
||||
static void
|
||||
isort(void *k, int n, int sz, Key_t (*getkey)(const void *))
|
||||
{
|
||||
void *p, *q;
|
||||
|
||||
for (p = k+sz; --n >= 1; p += sz) {
|
||||
for (q = p; q > k; q -= sz) {
|
||||
if (KeyGT(getkey(q), getkey(q-sz)))
|
||||
break;
|
||||
pswap(q, q-sz, sz);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* American Flag radix sort using aux storage of O(1) and stack of O(logN) */
|
||||
void
|
||||
rsort(void *tag, int64_t n, int sz, int radixBits, int sortBits, Key_t (*getkey)(const void *))
|
||||
{
|
||||
int i, shift, c;
|
||||
int64_t offset, *keyden, *pile;
|
||||
void *ak;
|
||||
unsigned int radix = 1 << radixBits;
|
||||
unsigned int mask = radix - 1;
|
||||
struct {
|
||||
int shift;
|
||||
int64_t offset;
|
||||
int64_t n;
|
||||
} stack[STACKSIZE], *sp = stack;
|
||||
|
||||
keyden = Malloc(radix * sizeof(int64_t));
|
||||
pile = Malloc(radix * sizeof(int64_t));
|
||||
|
||||
/* start so last mask cycle uses all radixBits */
|
||||
push((sortBits-1)/radixBits*radixBits, 0, n);
|
||||
|
||||
while (sp > stack) {
|
||||
pop(shift, offset, n);
|
||||
if (n < 64) {
|
||||
isort(tag+offset*sz, n, sz, getkey);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (i = 0; i < radix; i++)
|
||||
keyden[i] = 0;
|
||||
for (ak = tag+offset*sz; ak < tag+(offset+n)*sz; ak += sz)
|
||||
++keyden[KeyAndInt(KeyRshift(getkey(ak), shift), mask)];
|
||||
for (pile[0] = keyden[0], i = 1; i < radix; i++)
|
||||
pile[i] = pile[i-1]+keyden[i];
|
||||
push(shift-radixBits, offset, keyden[0]);
|
||||
for (i = 1; i < radix; i++)
|
||||
push(shift-radixBits, offset+pile[i-1], keyden[i]);
|
||||
for (ak = tag+offset*sz; ak < tag+(offset+n-keyden[mask])*sz; ak += keyden[c]*sz) {
|
||||
char tag_aux[sz];
|
||||
memcpy(tag_aux, ak, sz); /* in-place permutation */
|
||||
while (--pile[c = KeyAndInt(KeyRshift(getkey(tag_aux), shift), mask)] > (ak-tag)/sz-offset)
|
||||
pswap(tag_aux, tag+(pile[c]+offset)*sz, sz);
|
||||
memcpy(ak, tag_aux, sz);
|
||||
}
|
||||
}
|
||||
Free(pile);
|
||||
Free(keyden);
|
||||
}
|
113
external/libsdf/libsw/sigio_dump.c
vendored
Normal file
113
external/libsdf/libsw/sigio_dump.c
vendored
Normal file
|
@ -0,0 +1,113 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/socket.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include "error.h"
|
||||
#include "singlio.h"
|
||||
#include "Msgs.h"
|
||||
#include "protos.h"
|
||||
#include "mpmy.h"
|
||||
#include "byteswap.h"
|
||||
#include "memfile.h"
|
||||
|
||||
static void sock_init(char *hostname, int *port,
|
||||
struct sockaddr_in *acc, int bind_flag);
|
||||
|
||||
static void setup_handler(void);
|
||||
static void io_ready(int);
|
||||
|
||||
static int sock; /* file descriptor for my UDP socket */
|
||||
|
||||
void
|
||||
sigio_setup(void)
|
||||
{
|
||||
int port = 4000;
|
||||
struct sockaddr_in my_addr;
|
||||
|
||||
setup_handler();
|
||||
sock_init(NULL, &port, &my_addr, 1); /* get my sockaddr */
|
||||
|
||||
if (fcntl(sock, F_SETOWN, getpid()) < 0)
|
||||
Error("F_SETOWN error\n");
|
||||
|
||||
#ifdef FASYNC
|
||||
if (fcntl(sock, F_SETFL, FASYNC) < 0)
|
||||
Error("F_SETFL FASYNC error\n");
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
setup_handler(void)
|
||||
{
|
||||
signal(SIGIO, io_ready);
|
||||
}
|
||||
|
||||
static void
|
||||
io_ready(int sig)
|
||||
{
|
||||
int node;
|
||||
|
||||
PrintMemfile();
|
||||
signal(SIGIO, io_ready);
|
||||
return;
|
||||
}
|
||||
|
||||
/* This is virtually identical to the lsv code */
|
||||
|
||||
static void
|
||||
sock_init(char *hostname, int *port, struct sockaddr_in *acc, int bind_flag)
|
||||
{
|
||||
struct hostent *hp;
|
||||
char host_name[256];
|
||||
unsigned long inaddr;
|
||||
int tries = 0;
|
||||
|
||||
if (hostname == NULL) {
|
||||
if( (hostname = getenv("LSV_HOSTNAME")) == NULL ){
|
||||
if (gethostname(host_name, 256))
|
||||
Error("sock_create: gethostname failed\n");
|
||||
hostname = host_name;
|
||||
}
|
||||
}
|
||||
memset(acc, 0, sizeof(struct sockaddr_in));
|
||||
acc->sin_family = htons(AF_INET);
|
||||
|
||||
if ((inaddr = inet_addr(hostname)) != -1) /* it is numeric */
|
||||
acc->sin_addr.s_addr = inaddr;
|
||||
else if ((hp = gethostbyname(hostname)) != (struct hostent *)0)
|
||||
memcpy(&(acc->sin_addr), hp->h_addr, hp->h_length);
|
||||
else
|
||||
Error("gethostbyname failed\n");
|
||||
|
||||
if (bind_flag) {
|
||||
sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
}
|
||||
try_again:
|
||||
acc->sin_port = htons(*port);
|
||||
if (bind_flag) {
|
||||
int ret;
|
||||
ret = bind(sock,(struct sockaddr *)acc,sizeof(struct sockaddr_in));
|
||||
if (ret < 0 ) {
|
||||
if (tries < 100) {
|
||||
/* printf("bind returns %d\n", ret); */
|
||||
(*port)++;
|
||||
tries++;
|
||||
goto try_again;
|
||||
} else {
|
||||
Error("Can't bind socket. Tried %d, up to port %d\n",
|
||||
tries, *port);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
Msg_do("sigio_dump at %s port %d\n", hostname, *port);
|
||||
errno = 0; /* clear errors */
|
||||
}
|
||||
}
|
35
external/libsdf/libsw/singlio.c
vendored
Normal file
35
external/libsdf/libsw/singlio.c
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include "protos.h"
|
||||
#include "mpmy.h"
|
||||
#include "Msgs.h"
|
||||
#include "singlio.h"
|
||||
|
||||
static int singl_auto_flush = 1;
|
||||
|
||||
int singlAutoflush(int new){
|
||||
int ret = singl_auto_flush;
|
||||
singl_auto_flush = new;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int singlPrintf(const char *fmt, ...){
|
||||
va_list ap;
|
||||
int ret;
|
||||
|
||||
if(MPMY_Procnum() != 0 )
|
||||
return 0;
|
||||
va_start(ap, fmt);
|
||||
ret = vfprintf(stdout, fmt, ap);
|
||||
va_end(ap);
|
||||
if( singl_auto_flush )
|
||||
fflush(stdout);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void singlFflush(void)
|
||||
{
|
||||
if( MPMY_Procnum() != 0 )
|
||||
return;
|
||||
fflush(stdout);
|
||||
}
|
67
external/libsdf/libsw/stk.c
vendored
Normal file
67
external/libsdf/libsw/stk.c
vendored
Normal file
|
@ -0,0 +1,67 @@
|
|||
#define STKdotC
|
||||
#include "Assert.h"
|
||||
#include "stk.h"
|
||||
#include "error.h"
|
||||
/* Everything else is inlined in stk.h */
|
||||
|
||||
/* Any non-inlined definitions can go here. */
|
||||
|
||||
void StkInit(struct stk *s, size_t initial_sz,
|
||||
void *(*realloc_like)(void *, size_t), unsigned int alignment){
|
||||
s->growby = initial_sz;
|
||||
s->realloc_like = realloc_like;
|
||||
s->ptr = s->bottom = realloc_like(NULL, initial_sz);
|
||||
s->top = s->bottom + initial_sz;
|
||||
if( alignment == 0 )
|
||||
alignment = _STK_DEFAULT_ALIGNMENT;
|
||||
assert( (alignment & (alignment-1)) == 0 );
|
||||
s->align_mask = alignment - 1;
|
||||
}
|
||||
|
||||
void StkInitWithData(struct stk *s, size_t initial_sz,
|
||||
void *(*realloc_like)(void *, size_t), void *data,
|
||||
unsigned int alignment){
|
||||
s->growby = initial_sz;
|
||||
s->realloc_like = realloc_like;
|
||||
s->bottom = data;
|
||||
s->top = s->ptr = s->bottom + initial_sz;
|
||||
if( alignment == 0 )
|
||||
alignment = _STK_DEFAULT_ALIGNMENT;
|
||||
assert( (alignment & (alignment-1)) == 0 );
|
||||
s->align_mask = alignment - 1;
|
||||
}
|
||||
|
||||
void StkCopy(struct stk *to, const struct stk *from){
|
||||
size_t initial_sz;
|
||||
|
||||
to->growby = from->growby;
|
||||
to->realloc_like = from->realloc_like;
|
||||
initial_sz = StkSz(from);
|
||||
to->bottom = to->realloc_like(NULL, initial_sz);
|
||||
to->top = to->ptr = to->bottom + initial_sz;
|
||||
memcpy(to->bottom, from->bottom, initial_sz);
|
||||
}
|
||||
|
||||
void StkTerminate(struct stk *s){
|
||||
(*s->realloc_like)(s->bottom, 0); /* free */
|
||||
s->ptr = s->bottom = s->top = NULL;
|
||||
}
|
||||
|
||||
void StkGrow(Stk *s, int nbytes){
|
||||
size_t newsz = (s->ptr - s->bottom) + nbytes + s->growby;
|
||||
char *newbottom = (*s->realloc_like)(s->bottom, newsz);
|
||||
if( newbottom == NULL ){
|
||||
Error("Can't realloc to sz=%ld in StkGrow\n", newsz);
|
||||
}
|
||||
s->ptr = (s->ptr - s->bottom) + newbottom;
|
||||
s->top = newbottom + newsz;
|
||||
s->bottom = newbottom;
|
||||
}
|
||||
|
||||
void *StkCrunch(struct stk *s){
|
||||
size_t newsz = s->ptr - s->bottom;
|
||||
char *newbottom = (*s->realloc_like)(s->bottom, newsz);
|
||||
s->ptr = s->top = newsz + newbottom;
|
||||
s->bottom = newbottom;
|
||||
return newbottom;
|
||||
}
|
1428
external/libsdf/libsw/swampi.c
vendored
Normal file
1428
external/libsdf/libsw/swampi.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
140
external/libsdf/libsw/swampif.c
vendored
Normal file
140
external/libsdf/libsw/swampif.c
vendored
Normal file
|
@ -0,0 +1,140 @@
|
|||
void _F77(mpi_init)(int *ierr)
|
||||
{
|
||||
*ierr = MPI_Init(0, 0);
|
||||
}
|
||||
|
||||
void _F77(mpi_finalize)(int *ierr)
|
||||
{
|
||||
*ierr = MPI_Finalize();
|
||||
}
|
||||
|
||||
void _F77(mpi_abort)(int *comm, int *err, int *ierr)
|
||||
{
|
||||
*ierr = MPI_Abort(*comm, *err);
|
||||
}
|
||||
|
||||
void _F77(mpi_comm_rank)(int *comm, int *rank, int *ierr)
|
||||
{
|
||||
*ierr = MPI_Comm_rank(*comm, rank);
|
||||
}
|
||||
|
||||
void _F77(mpi_comm_size)(int *comm, int *size, int *ierr)
|
||||
{
|
||||
*ierr = MPI_Comm_size(*comm, size);
|
||||
}
|
||||
|
||||
void _F77(mpi_get_count)(MPI_Status *status, int *type, int *cnt, int *ierr)
|
||||
{
|
||||
*ierr = MPI_Get_count(status, *type, cnt);
|
||||
}
|
||||
|
||||
void _F77(mpi_isend)(void *buf, int *cnt, int *type, int *dest, int *tag,
|
||||
int *comm, MPI_Request req, int *ierr)
|
||||
{
|
||||
*ierr = MPI_Isend(buf, *cnt, *type, *dest, *tag, *comm, req);
|
||||
}
|
||||
|
||||
void _F77(mpi_irecv)(void *buf, int *cnt, int *type, int *src, int *tag,
|
||||
int *comm, MPI_Request req, int *ierr)
|
||||
{
|
||||
*ierr = MPI_Irecv(buf, *cnt, *type, *src, *tag, *comm, req);
|
||||
}
|
||||
|
||||
void _F77(mpi_test)(MPI_Request req, int *flag, MPI_Status *stat, int *ierr)
|
||||
{
|
||||
*ierr = MPI_Test(req, flag, stat);
|
||||
}
|
||||
|
||||
void _F77(mpi_wait)(MPI_Request req, MPI_Status *status, int *ierr)
|
||||
{
|
||||
*ierr = MPI_Wait(req, status);
|
||||
}
|
||||
|
||||
void _F77(mpi_waitall)(int *count, MPI_Request *reqv,
|
||||
MPI_Status *statusv, int *ierr)
|
||||
{
|
||||
*ierr = MPI_Waitall(*count, reqv, statusv);
|
||||
}
|
||||
|
||||
void _F77(mpi_send)(void *buf, int *cnt, int *type, int *dest, int *tag,
|
||||
int *comm, int *ierr)
|
||||
{
|
||||
*ierr = MPI_Send(buf, *cnt, *type, *dest, *tag, *comm);
|
||||
}
|
||||
|
||||
void _F77(mpi_recv)(void *buf, int *cnt, int *type, int *src, int *tag,
|
||||
int *comm, MPI_Status *status, int *ierr)
|
||||
{
|
||||
*ierr = MPI_Recv(buf, *cnt, *type, *src, *tag, *comm, status);
|
||||
}
|
||||
|
||||
void _F77(mpi_sendrecv)(void *sendbuf, int *sendcnt, int *sendtype,
|
||||
int *dest, int *sendtag, void *recvbuf, int *recvcnt,
|
||||
int *recvtype, int *source, int *recvtag,
|
||||
int *comm, MPI_Status *status, int *ierr)
|
||||
{
|
||||
*ierr = MPI_Sendrecv(sendbuf, *sendcnt, *sendtype, *dest, *sendtag,
|
||||
recvbuf, *recvcnt, *recvtype, *source, *recvtag,
|
||||
*comm, status);
|
||||
}
|
||||
|
||||
void _F77(mpi_bcast)(void *buf, int *cnt, int *type, int *src, int *comm,
|
||||
int *ierr)
|
||||
{
|
||||
*ierr = MPI_Bcast(buf, *cnt, *type, *src, *comm);
|
||||
}
|
||||
|
||||
void _F77(mpi_reduce)(void *sendbuf, void *recvbuf, int *count, int *datatype,
|
||||
int *op, int *root, int *comm, int *ierr)
|
||||
{
|
||||
*ierr = MPI_Reduce(sendbuf, recvbuf, *count, *datatype, *op, *root, *comm);
|
||||
}
|
||||
|
||||
void _F77(mpi_allreduce)(void *sendbuf, void *recvbuf, int *count,
|
||||
int *datatype, int *op, int *comm, int *ierr)
|
||||
{
|
||||
*ierr = MPI_Allreduce(sendbuf, recvbuf, *count, *datatype, *op, *comm);
|
||||
}
|
||||
|
||||
void _F77(mpi_barrier)(int *comm, int *ierr)
|
||||
{
|
||||
*ierr = MPI_Barrier(*comm);
|
||||
}
|
||||
|
||||
void _F77(mpi_alltoallv)(void *sbuf, int *sendcnts, int *sdispls, int *stype,
|
||||
void *rbuf, int *recvcnts, int *rdispls, int *rtype,
|
||||
int *comm, int *ierr)
|
||||
{
|
||||
*ierr = MPI_Alltoallv(sbuf, sendcnts, sdispls, *stype,
|
||||
rbuf, recvcnts, rdispls, *rtype, *comm);
|
||||
}
|
||||
|
||||
void _F77(mpi_alltoall)(void *sendbuf, int *sendcount, int *sendtype,
|
||||
void *recvbuf, int *recvcount, int *recvtype,
|
||||
int *comm, int *ierr)
|
||||
{
|
||||
*ierr = MPI_Alltoall(sendbuf, *sendcount, *sendtype,
|
||||
recvbuf, *recvcount, *recvtype, *comm);
|
||||
}
|
||||
|
||||
void _F77(mpi_comm_dup)(MPI_Comm *comm, MPI_Comm *newcomm, int *ierr)
|
||||
{
|
||||
*ierr = MPI_Comm_dup(*comm, newcomm);
|
||||
}
|
||||
|
||||
void _F77(mpi_comm_split)(MPI_Comm *comm, int *color, int *key,
|
||||
MPI_Comm *newcomm, int *ierr)
|
||||
{
|
||||
*ierr = MPI_Comm_split(*comm, *color, *key, newcomm);
|
||||
}
|
||||
|
||||
|
||||
double _F77(mpi_wtime)(void)
|
||||
{
|
||||
return MPI_Wtime();
|
||||
}
|
||||
|
||||
double _F77(mpi_wtick)(void)
|
||||
{
|
||||
return MPI_Wtick();
|
||||
}
|
159
external/libsdf/libsw/timers.c
vendored
Normal file
159
external/libsdf/libsw/timers.c
vendored
Normal file
|
@ -0,0 +1,159 @@
|
|||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include "Malloc.h"
|
||||
#include "timers.h"
|
||||
#include "mpmy.h"
|
||||
#include "mpmy_time.h"
|
||||
#include "Assert.h"
|
||||
|
||||
/* Make sure any #defines in timers.h don't interfere... */
|
||||
#undef StartTimer
|
||||
#undef StopTimer
|
||||
#undef StartWCTimer
|
||||
#undef StopWCTimer
|
||||
|
||||
#define MAXENABLED 100
|
||||
|
||||
static Timer_t *enabled_timers[MAXENABLED];
|
||||
static int nenabled_timers;
|
||||
|
||||
void ClearTimer(Timer_t *t)
|
||||
{
|
||||
MPMY_ClearTimer(t->mpmy_tm);
|
||||
return;
|
||||
}
|
||||
|
||||
double ReadTimer(Timer_t *t)
|
||||
{
|
||||
return MPMY_ReadTimer(t->mpmy_tm);
|
||||
}
|
||||
|
||||
void StartTimer(Timer_t *t)
|
||||
{
|
||||
if (t->enabled)
|
||||
MPMY_StartTimer(t->mpmy_tm);
|
||||
return;
|
||||
}
|
||||
|
||||
void CopyTimer(Timer_t *src, Timer_t *dest)
|
||||
{
|
||||
MPMY_CopyTimer(src->mpmy_tm, dest->mpmy_tm);
|
||||
}
|
||||
|
||||
void StopTimer(Timer_t *t)
|
||||
{
|
||||
if (t->enabled)
|
||||
MPMY_StopTimer(t->mpmy_tm);
|
||||
return;
|
||||
}
|
||||
|
||||
void ClearEnabledTimers(void){
|
||||
int i;
|
||||
for(i=0; i<nenabled_timers; i++){
|
||||
ClearTimer(enabled_timers[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void EnableWCTimer(Timer_t *t, char *name){
|
||||
assert(nenabled_timers < MAXENABLED);
|
||||
enabled_timers[nenabled_timers++] = t;
|
||||
t->name = Malloc(strlen(name)+1);
|
||||
strcpy(t->name, name);
|
||||
t->enabled = 1;
|
||||
t->mpmy_tm = MPMY_CreateTimer(MPMY_WC_TIME);
|
||||
ClearTimer(t);
|
||||
}
|
||||
|
||||
void EnableCPUTimer(Timer_t *t, char *name){
|
||||
assert(nenabled_timers < MAXENABLED);
|
||||
enabled_timers[nenabled_timers++] = t;
|
||||
t->name = Malloc(strlen(name)+1);
|
||||
strcpy(t->name, name);
|
||||
t->enabled = 1;
|
||||
t->mpmy_tm = MPMY_CreateTimer(MPMY_CPU_TIME);
|
||||
ClearTimer(t);
|
||||
}
|
||||
|
||||
void DisableTimer(Timer_t *t){
|
||||
int i;
|
||||
|
||||
for(i=0; i<nenabled_timers; i++){
|
||||
if( enabled_timers[i] == t )
|
||||
break;
|
||||
}
|
||||
assert(i < nenabled_timers);
|
||||
t->enabled = 0;
|
||||
Free(t->name);
|
||||
t->name = NULL;
|
||||
enabled_timers[i] = enabled_timers[--nenabled_timers];
|
||||
MPMY_DestroyTimer(t->mpmy_tm);
|
||||
}
|
||||
|
||||
void SumTimers(void){
|
||||
double nprocinv;
|
||||
Timer_t *t;
|
||||
int i;
|
||||
MPMY_Comm_request req;
|
||||
|
||||
MPMY_ICombine_Init(&req);
|
||||
for(i=0; i<nenabled_timers; i++){
|
||||
t = enabled_timers[i];
|
||||
t->mean = t->min = t->max = MPMY_ReadTimer(t->mpmy_tm);
|
||||
MPMY_ICombine(&t->min, &t->min, 1, MPMY_DOUBLE, MPMY_MIN, req);
|
||||
MPMY_ICombine(&t->max, &t->max, 1, MPMY_DOUBLE, MPMY_MAX, req);
|
||||
MPMY_ICombine(&t->mean, &t->mean, 1, MPMY_DOUBLE, MPMY_SUM, req);
|
||||
}
|
||||
MPMY_ICombine_Wait(req);
|
||||
|
||||
/* Now loop a second time and divide the mean by Nproc */
|
||||
nprocinv = 1./MPMY_Nproc();
|
||||
for(i=0; i<nenabled_timers; i++){
|
||||
t = enabled_timers[i];
|
||||
t->mean *= nprocinv;
|
||||
}
|
||||
}
|
||||
|
||||
void OutputTimers(int (*Printf_Like)(const char *, ...)){
|
||||
int i;
|
||||
Timer_t *t;
|
||||
|
||||
SumTimers();
|
||||
Printf_Like("%12s %10s %10s %10s\n", "Timers", "Min", "Max", "Mean");
|
||||
for (i = 0; i < nenabled_timers; i++) {
|
||||
t = enabled_timers[i];
|
||||
if( t->enabled && t->name )
|
||||
Printf_Like("%12s %10.2f %10.2f %10.2f\n", t->name,
|
||||
t->min, t->max, t->mean);
|
||||
}
|
||||
}
|
||||
|
||||
void OutputTimer(Timer_t *t, int (*Printf_Like)(const char *, ...)){
|
||||
MPMY_Comm_request req;
|
||||
|
||||
if( t->enabled && t->name ) {
|
||||
MPMY_ICombine_Init(&req);
|
||||
t->mean = t->min = t->max = MPMY_ReadTimer(t->mpmy_tm);
|
||||
MPMY_ICombine(&t->min, &t->min, 1, MPMY_DOUBLE, MPMY_MIN, req);
|
||||
MPMY_ICombine(&t->max, &t->max, 1, MPMY_DOUBLE, MPMY_MAX, req);
|
||||
MPMY_ICombine(&t->mean, &t->mean, 1, MPMY_DOUBLE, MPMY_SUM, req);
|
||||
MPMY_ICombine_Wait(req);
|
||||
t->mean /= MPMY_Nproc();
|
||||
Printf_Like("%12s %10.2f %10.2f %10.2f\n", t->name,
|
||||
t->min, t->max, t->mean);
|
||||
}
|
||||
}
|
||||
|
||||
void OutputIndividualTimers(int (*Printf_Like)(const char *, ...)){
|
||||
int i;
|
||||
Timer_t *t;
|
||||
|
||||
Printf_Like("%12s %10s\n", "Timers", "(sec)");
|
||||
for (i = 0; i < nenabled_timers; i++) {
|
||||
t = enabled_timers[i];
|
||||
if( t->enabled && t->name ){
|
||||
Printf_Like("%12s %10.2f\n", t->name, MPMY_ReadTimer(t->mpmy_tm));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue