#ifndef LMP_MEMORY_H #define LMP_MEMORY_H #define __STDC_LIMIT_MACROS #define __STDC_FORMAT_MACROS #include "stdio.h" #include "stdlib.h" #include "limits.h" #include "stdint.h" #include "inttypes.h" typedef int64_t bigint; #define BIGINT_FORMAT "%" PRId64 #define ATOBIGINT atoll class Memory { public: Memory(){}; void *smalloc(bigint n, const char *); void *srealloc(void *, bigint n, const char *); void sfree(void *); void fail(const char *); /* ---------------------------------------------------------------------- create a 1d array ------------------------------------------------------------------------- */ template TYPE *create(TYPE *&array, int n, const char *name) { bigint nbytes = sizeof(TYPE) * n; array = (TYPE *) smalloc(nbytes,name); return array; }; template TYPE **create(TYPE **&array, int n, const char *name) {fail(name);} /* ---------------------------------------------------------------------- grow or shrink 1d array ------------------------------------------------------------------------- */ template TYPE *grow(TYPE *&array, int n, const char *name) { if (array == NULL) return create(array,n,name); bigint nbytes = sizeof(TYPE) * n; array = (TYPE *) srealloc(array,nbytes,name); return array; }; template TYPE **grow(TYPE **&array, int n, const char *name) {fail(name);} /* ---------------------------------------------------------------------- destroy a 1d array ------------------------------------------------------------------------- */ template void destroy(TYPE *array) { sfree(array); }; /* ---------------------------------------------------------------------- create a 1d array with index from nlo to nhi inclusive cannot grow it ------------------------------------------------------------------------- */ template TYPE *create1d_offset(TYPE *&array, int nlo, int nhi, const char *name) { bigint nbytes = sizeof(TYPE) * (nhi-nlo+1); array = (TYPE *) smalloc(nbytes,name); array -= nlo; return array; } template TYPE **create1d_offset(TYPE **&array, int nlo, int nhi, const char *name) {fail(name);} /* ---------------------------------------------------------------------- destroy a 1d array with index offset ------------------------------------------------------------------------- */ template void destroy1d_offset(TYPE *array, int offset) { if (array) sfree(&array[offset]); } /* ---------------------------------------------------------------------- create a 2d array ------------------------------------------------------------------------- */ template TYPE **create(TYPE **&array, int n1, int n2, const char *name) { bigint nbytes = sizeof(TYPE) * n1*n2; TYPE *data = (TYPE *) smalloc(nbytes,name); nbytes = sizeof(TYPE *) * n1; array = (TYPE **) smalloc(nbytes,name); int n = 0; for (int i = 0; i < n1; i++) { array[i] = &data[n]; n += n2; } return array; } template TYPE ***create(TYPE ***&array, int n1, int n2, const char *name) {fail(name);} /* ---------------------------------------------------------------------- grow or shrink 1st dim of a 2d array last dim must stay the same ------------------------------------------------------------------------- */ template TYPE **grow(TYPE **&array, int n1, int n2, const char *name) { if (array == NULL) return create(array,n1,n2,name); bigint nbytes = sizeof(TYPE) * n1*n2; TYPE *data = (TYPE *) srealloc(array[0],nbytes,name); nbytes = sizeof(TYPE *) * n1; array = (TYPE **) srealloc(array,nbytes,name); int n = 0; for (int i = 0; i < n1; i++) { array[i] = &data[n]; n += n2; } return array; } template TYPE ***grow(TYPE ***&array, int n1, int n2, const char *name) {fail(name);} /* ---------------------------------------------------------------------- destroy a 2d array ------------------------------------------------------------------------- */ template void destroy(TYPE **array) { if (array == NULL) return; sfree(array[0]); sfree(array); } /* ---------------------------------------------------------------------- create a 2d array with 2nd index from n2lo to n2hi inclusive cannot grow it ------------------------------------------------------------------------- */ template TYPE **create2d_offset(TYPE **&array, int n1, int n2lo, int n2hi, const char *name) { int n2 = n2hi - n2lo + 1; create(array,n1,n2,name); for (int i = 0; i < n1; i++) array[i] -= n2lo; return array; } template TYPE ***create2d_offset(TYPE ***&array, int n1, int n2lo, int n2hi, const char *name) {fail(name);} /* ---------------------------------------------------------------------- destroy a 2d array with 2nd index offset ------------------------------------------------------------------------- */ template void destroy2d_offset(TYPE **array, int offset) { if (array == NULL) return; sfree(&array[0][offset]); sfree(array); } /* ---------------------------------------------------------------------- create a 3d array ------------------------------------------------------------------------- */ template TYPE ***create(TYPE ***&array, int n1, int n2, int n3, const char *name) { bigint nbytes = sizeof(TYPE) * n1*n2*n3; TYPE *data = (TYPE *) smalloc(nbytes,name); nbytes = sizeof(TYPE *) * n1*n2; TYPE **plane = (TYPE **) smalloc(nbytes,name); nbytes = sizeof(TYPE **) * n1; array = (TYPE ***) smalloc(nbytes,name); int i,j; int n = 0; for (i = 0; i < n1; i++) { array[i] = &plane[i*n2]; for (j = 0; j < n2; j++) { plane[i*n2+j] = &data[n]; n += n3; } } return array; } template TYPE ****create(TYPE ****&array, int n1, int n2, int n3, const char *name) {fail(name);} /* ---------------------------------------------------------------------- grow or shrink 1st dim of a 3d array last 2 dims must stay the same ------------------------------------------------------------------------- */ template TYPE ***grow(TYPE ***&array, int n1, int n2, int n3, const char *name) { if (array == NULL) return create(array,n1,n2,n3,name); bigint nbytes = sizeof(TYPE) * n1*n2*n3; TYPE *data = (TYPE *) srealloc(array[0][0],nbytes,name); nbytes = sizeof(TYPE *) * n1*n2; TYPE **plane = (TYPE **) srealloc(array[0],nbytes,name); nbytes = sizeof(TYPE **) * n1; array = (TYPE ***) srealloc(array,nbytes,name); int i,j; int n = 0; for (i = 0; i < n1; i++) { array[i] = &plane[i*n2]; for (j = 0; j < n2; j++) { plane[i*n2+j] = &data[n]; n += n3; } } return array; } template TYPE ****grow(TYPE ****&array, int n1, int n2, int n3, const char *name) {fail(name);} /* ---------------------------------------------------------------------- destroy a 3d array ------------------------------------------------------------------------- */ template void destroy(TYPE ***array) { if (array == NULL) return; sfree(array[0][0]); sfree(array[0]); sfree(array); } /* ---------------------------------------------------------------------- create a 3d array with 1st index from n1lo to n1hi inclusive cannot grow it ------------------------------------------------------------------------- */ template TYPE ***create3d_offset(TYPE ***&array, int n1lo, int n1hi, int n2, int n3, const char *name) { int n1 = n1hi - n1lo + 1; create(array,n1,n2,n3,name); array -= n1lo; return array; } template TYPE ****create3d_offset(TYPE ****&array, int n1lo, int n1hi, int n2, int n3, const char *name) {fail(name);} /* ---------------------------------------------------------------------- free a 3d array with 1st index offset ------------------------------------------------------------------------- */ template void destroy3d_offset(TYPE ***array, int offset) { if (array) destroy(&array[offset]); } /* ---------------------------------------------------------------------- create a 3d array with 1st index from n1lo to n1hi inclusive, 2nd index from n2lo to n2hi inclusive, 3rd index from n3lo to n3hi inclusive cannot grow it ------------------------------------------------------------------------- */ template TYPE ***create3d_offset(TYPE ***&array, int n1lo, int n1hi, int n2lo, int n2hi, int n3lo, int n3hi, const char *name) { int n1 = n1hi - n1lo + 1; int n2 = n2hi - n2lo + 1; int n3 = n3hi - n3lo + 1; create(array,n1,n2,n3,name); for (int i = 0; i < n1*n2; i++) array[0][i] -= n3lo; for (int i = 0; i < n1; i++) array[i] -= n2lo; array -= n1lo; return array; } template TYPE ****create3d_offset(TYPE ****&array, int n1lo, int n1hi, int n2lo, int n2hi, int n3lo, int n3hi, const char *name) {fail(name);} /* ---------------------------------------------------------------------- free a 3d array with all 3 indices offset ------------------------------------------------------------------------- */ template void destroy3d_offset(TYPE ***array, int n1_offset, int n2_offset, int n3_offset) { if (array == NULL) return; sfree(&array[n1_offset][n2_offset][n3_offset]); sfree(&array[n1_offset][n2_offset]); sfree(&array[n1_offset]); } /* ---------------------------------------------------------------------- create a 4d array ------------------------------------------------------------------------- */ template TYPE ****create(TYPE ****&array, int n1, int n2, int n3, int n4, const char *name) { bigint nbytes = sizeof(TYPE) * n1*n2*n3*n4; TYPE *data = (double *) smalloc(nbytes,name); nbytes = sizeof(TYPE *) * n1*n2*n3; TYPE **cube = (double **) smalloc(nbytes,name); nbytes = sizeof(TYPE **) * n1*n2; TYPE ***plane = (double ***) smalloc(nbytes,name); nbytes = sizeof(TYPE ***) * n1; array = (double ****) smalloc(nbytes,name); int i,j,k; int n = 0; for (i = 0; i < n1; i++) { array[i] = &plane[i*n2]; for (j = 0; j < n2; j++) { plane[i*n2+j] = &cube[i*n2*n3+j*n3]; for (k = 0; k < n3; k++) { cube[i*n2*n3+j*n3+k] = &data[n]; n += n4; } } } return array; } template TYPE *****create(TYPE *****&array, int n1, int n2, int n3, int n4, const char *name) {fail(name);} /* ---------------------------------------------------------------------- destroy a 4d array ------------------------------------------------------------------------- */ template void destroy(TYPE ****array) { if (array == NULL) return; sfree(array[0][0][0]); sfree(array[0][0]); sfree(array[0]); sfree(array); } /* ---------------------------------------------------------------------- memory usage of arrays, including pointers ------------------------------------------------------------------------- */ template bigint usage(TYPE *array, int n) { bigint bytes = sizeof(TYPE) * n; return bytes; } template bigint usage(TYPE **array, int n1, int n2) { bigint bytes = sizeof(TYPE) * n1*n2; bytes += sizeof(TYPE *) * n1; return bytes; } template bigint usage(TYPE ***array, int n1, int n2, int n3) { bigint bytes = sizeof(TYPE) * n1*n2*n3; bytes += sizeof(TYPE *) * n1*n2; bytes += sizeof(TYPE **) * n1; return bytes; } template bigint usage(TYPE ****array, int n1, int n2, int n3, int n4) { bigint bytes = sizeof(TYPE) * n1*n2*n3*n4; bytes += sizeof(TYPE *) * n1*n2*n3; bytes += sizeof(TYPE **) * n1*n2; bytes += sizeof(TYPE ***) * n1; return bytes; } }; #endif