diff --git a/buffers/Makefile.in b/buffers/Makefile.in new file mode 100644 index 000000000..0498fce5d --- /dev/null +++ b/buffers/Makefile.in @@ -0,0 +1,98 @@ +# $Id: Makefile.in 1793 2011-10-12 21:55:13Z reker $ + +srcdir = @srcdir@ +top_builddir = @top_builddir@ +abs_top_builddir = @abs_top_builddir@ +top_srcdir = @top_srcdir@ +abs_top_srcdir = @abs_top_srcdir@ +subdir = buffers +builddir = @builddir@ + +CFLAGS = @CFLAGS@ +DEPFLAGS = @DEPFLAGS@ +LDFLAGS = @LDFLAGS@ +DEFS = @DEFS@ +OPTARGS = @OPTARGS@ + +AR = ar +RANLIB = @RANLIB@ +CC = @CC@ +CCDEP = @CCDEP@ +CCLD = $(CC) +LINK = $(CCLD) $(CFLAGS) $(LDFLAGS) ${OPTARGS} -o $@ +LEX = @LEX@ +AUTOCONF = @AUTOCONF@ +DEFS = @DEFS@ + +INCLUDES = @INCLUDES@ +LDADD = +COMPILE = ${CC} ${DEFS} ${INCLUDES} ${CFLAGS} ${OPTARGS} + +LIBRARIES = libbuffers + +libbuffers_TARGETS = gauge \ + gauge_finalize_gauge_buffers \ + gauge_get_gauge_field \ + gauge_get_gauge_field_array \ + gauge_initialize_gauge_buffers \ + gauge_return_gauge_field \ + gauge_return_gauge_field_array + +libbuffers_OBJECTS = $(addsuffix .o, ${libbuffers_TARGETS}) + +# default rule + +all: Makefile dep libbuffers.a + +# rules for debugging +debug all-debug: CFLAGS := $(CFLAGS) @DEBUG_FLAG@ +debug all-debug: all + +# rules for profiling information +profile all-profile: CFLAGS := $(filter-out -fomit-frame-pointer,${CFLAGS}) @PROFILE_FLAG@ +profile all-profile: all + + +#include dep rules + + +-include $(addsuffix .d,${libbuffers_TARGETS}) + +include ${top_srcdir}/Makefile.global + +# rule to compile objects + +%.o: ${srcdir}/%.c %.d Makefile ${abs_top_builddir}/config.h + $(COMPILE) -c $< + + +# rule to make libbuffers +libbuffers.a: ${libbuffers_OBJECTS} Makefile + @rm -f libbuffers.a + @${AR} cru libbuffers.a $(libbuffers_OBJECTS) + @$(RANLIB) libbuffers.a + @cp libbuffers.a ${top_builddir}/lib/libbuffers.a + +# rule to generate .d files + +$(addsuffix .d,$(libbuffers_TARGETS)): %.d: ${srcdir}/%.c Makefile + @$(CCDEP) ${DEPFLAGS} ${INCLUDES} $< > $@ + +# rule to make dependencies + +dep: ${addsuffix .d, ${libbuffers_TARGETS}} + +# rules to clean + +compile-clean: Makefile + rm -f ${$(addsuffix _OBJECTS, ${LIBRARIES})} *.d + +clean: compile-clean + rm -f $(addsuffix .a, ${LIBRARIES}) + rm -f ../lib/libbuffers.a + +distclean: clean + rm -f Makefile + + +.PHONY: all dep clean compile-clean distclean debug all-debug profile all-profile diff --git a/buffers/gauge.c b/buffers/gauge.c new file mode 100644 index 000000000..f7d2e24fc --- /dev/null +++ b/buffers/gauge.c @@ -0,0 +1,3 @@ +#include "gauge.ih" + +gauge_buffers_t g_gauge_buffers; diff --git a/buffers/gauge.h b/buffers/gauge.h new file mode 100644 index 000000000..36dd876aa --- /dev/null +++ b/buffers/gauge.h @@ -0,0 +1,36 @@ +#pragma once + +#include "su3.h" + +typedef su3 su3_tuple[4]; + +typedef struct +{ + su3_tuple **reserve; + unsigned int max; + unsigned int allocated; + int stack; +} gauge_buffers_t; + +typedef struct +{ + su3_tuple *field; +} gauge_field_t; + +typedef struct +{ + su3_tuple **field_array; + unsigned int length; +} gauge_field_array_t; + +extern gauge_buffers_t g_gauge_buffers; + +void initialize_gauge_buffers(unsigned int max); + +gauge_field_t get_gauge_field(); +void return_gauge_field(gauge_field_t *gauge_field); + +gauge_field_array_t get_gauge_field_array(unsigned int length); +void return_gauge_field_array(gauge_field_array_t *gauge_field_array); + +void finalize_gauge_buffers(); diff --git a/buffers/gauge.ih b/buffers/gauge.ih new file mode 100644 index 000000000..683f41cd8 --- /dev/null +++ b/buffers/gauge.ih @@ -0,0 +1,6 @@ +#include +#include + +#include +#include + diff --git a/buffers/gauge_finalize_gauge_buffers.c b/buffers/gauge_finalize_gauge_buffers.c new file mode 100644 index 000000000..78cb7082f --- /dev/null +++ b/buffers/gauge_finalize_gauge_buffers.c @@ -0,0 +1,14 @@ +#include "gauge.ih" + +void finalize_gauge_buffers() +{ + if (g_gauge_buffers.stack != g_gauge_buffers.allocated - 1) + fprintf(stderr, "WARNING: g_gauge_buffers finalized with unreturned fields!"); /* Make error? */ + for (unsigned int ctr = 0; ctr < (g_gauge_buffers.stack); ++ctr) + { + /* We need to retrieve the unaligned pointers, stored _before_ the actual fields. */ + void* ptr = ((void**)g_gauge_buffers.reserve[ctr])[-1]; + free(ptr); + } + free(g_gauge_buffers.reserve); +} diff --git a/buffers/gauge_get_gauge_field.c b/buffers/gauge_get_gauge_field.c new file mode 100644 index 000000000..3e855dd40 --- /dev/null +++ b/buffers/gauge_get_gauge_field.c @@ -0,0 +1,38 @@ +#include "gauge.ih" + +/* This routine not only malloc's a field, but immediately aligns it. + To keep track of the original address to free the field eventually, + we store that address _before_ the actual buffer. + The end user should never have to see the alignment after this. */ + +gauge_field_t get_gauge_field() +{ + void *raw = NULL; + size_t p = 0; + gauge_field_t gauge_field; + + if (g_gauge_buffers.stack < 0) /* Need to allocate a new buffer */ + { + if (g_gauge_buffers.allocated == g_gauge_buffers.max) + { +#ifdef MPI + MPI_Finalize(); /* Hard to handle gracefully here, can improve later... */ +#endif + exit(1); + } + ++g_gauge_buffers.stack; + raw = malloc(sizeof(void*) + ALIGN_BASE + sizeof(su3_tuple) * VOLUMEPLUSRAND + 1); + p = (size_t)raw + sizeof(void*); + p = ((p + ALIGN_BASE) & ~ALIGN_BASE); + ((void**)p)[-1] = raw; + g_gauge_buffers.reserve[g_gauge_buffers.stack] = (su3_tuple*)p; + ++g_gauge_buffers.allocated; + } + + gauge_field.field = g_gauge_buffers.reserve[g_gauge_buffers.stack]; + g_gauge_buffers.reserve[g_gauge_buffers.stack] = NULL; + --g_gauge_buffers.stack; + + return gauge_field; +} + diff --git a/buffers/gauge_get_gauge_field_array.c b/buffers/gauge_get_gauge_field_array.c new file mode 100644 index 000000000..8c1752e98 --- /dev/null +++ b/buffers/gauge_get_gauge_field_array.c @@ -0,0 +1,34 @@ +#include "gauge.ih" + +gauge_field_array_t get_gauge_field_array(unsigned int length) +{ + gauge_field_array_t gauge_field_array; + gauge_field_array.length = length; + gauge_field_array.field_array = (su3_tuple**)calloc(length, sizeof(su3_tuple*)); + + if (g_gauge_buffers.stack < (length - 1)) /* Need to allocate more buffers */ + { + if (g_gauge_buffers.allocated >= (g_gauge_buffers.max - length)) + { +#ifdef MPI + MPI_Finalize(); +#endif + exit(1); /* Hard to handle gracefully here, can improve later... */ + } + for (unsigned int ctr = 0; ctr < length; ++ctr) + { + ++g_gauge_buffers.stack; + g_gauge_buffers.reserve[g_gauge_buffers.stack] = (su3_tuple*)malloc(sizeof(su3_tuple) * VOLUMEPLUSRAND + 1); + } + g_gauge_buffers.allocated += length; + } + + for (unsigned int ctr = 0; ctr < length; ++ctr) + { + gauge_field_array.field_array[ctr] = g_gauge_buffers.reserve[g_gauge_buffers.stack]; + g_gauge_buffers.reserve[g_gauge_buffers.stack] = NULL; + --g_gauge_buffers.stack; + } + return gauge_field_array; +} + diff --git a/buffers/gauge_initialize_gauge_buffers.c b/buffers/gauge_initialize_gauge_buffers.c new file mode 100644 index 000000000..f242b15de --- /dev/null +++ b/buffers/gauge_initialize_gauge_buffers.c @@ -0,0 +1,10 @@ +#include "gauge.ih" + +void initialize_gauge_buffers(unsigned int max) +{ + g_gauge_buffers.max = max; + g_gauge_buffers.allocated = 0; + g_gauge_buffers.stack = -1; + g_gauge_buffers.reserve = (su3_tuple**)calloc(max, sizeof(su3_tuple*)); +} + diff --git a/buffers/gauge_return_gauge_field.c b/buffers/gauge_return_gauge_field.c new file mode 100644 index 000000000..ce7825aaf --- /dev/null +++ b/buffers/gauge_return_gauge_field.c @@ -0,0 +1,9 @@ +#include "gauge.ih" + +void return_gauge_field(gauge_field_t *gauge_field) +{ + ++g_gauge_buffers.stack; + g_gauge_buffers.reserve[g_gauge_buffers.stack] = gauge_field->field; + gauge_field->field = NULL; +} + diff --git a/buffers/gauge_return_gauge_field_array.c b/buffers/gauge_return_gauge_field_array.c new file mode 100644 index 000000000..e7b9e17fc --- /dev/null +++ b/buffers/gauge_return_gauge_field_array.c @@ -0,0 +1,11 @@ +#include "gauge.ih" + +void return_gauge_field_array(gauge_field_array_t *gauge_field_array) +{ + for (unsigned int ctr = 0; ctr < gauge_field_array->length; ++ctr) + { + ++g_gauge_buffers.stack; + g_gauge_buffers.reserve[g_gauge_buffers.stack] = gauge_field_array->field_array[ctr]; + gauge_field_array->field_array[ctr] = NULL; + } +}