/* ti_array_bulkio.c this file is not meant to be compiled directly - it is included from ti_array.c in several places to provide a shared implementation of the primitives this file makes the same assumptions as ti_array.c about predefinition of T, N, PTR_TO_T */ #include "ti_config.h" #include "bulkio.h" #include "array-byteswap.h" #include "layout!PTAjbyte.h" #include "layout!LTAjbyte.h" #include "layout!TAjbyte.h" #include "layout!Pjbyte.h" #include "layout!Ljbyte.h" #include "native-utils.h" #define CHECK_NULL_TI_ARRAY(x) \ if (ti_isnull(x)) CHECK_NULL_LOCAL(NULL) #define ELEMSIZE (sizeof(T)) #if !defined(WORDS_BIGENDIAN) #define BYTESWAP (PORTABLE_ONDISK_REPRESENTATION && (ELEMSIZE == 2 || ELEMSIZE == 4 || ELEMSIZE == 8)) #else #define BYTESWAP 0 #endif /* ------------------------------------------------------------------------------------ */ #ifdef TIARRAY_BULKIO_READFUNC_HEADER #define STRINGIFY(x) #x #define WHERE STRINGIFY(TIARRAY_BULKIO_READFUNC_HEADER) TIARRAY_BULKIO_READFUNC_HEADER { CHECK_NULL_GLOBAL(fileobj); /* eliminate the silly cases */ CHECK_NULL_TI_ARRAY(x); if (RECTDOMAIN_ISNULL(x.domain)) return; /* maybe should be an exn? */ { int iscontiguous = (int)ISCONTIGUOUS_METHOD(x); /* ti array props */ #if GLOBAL_ARRAY int islocal = (int)isDirectlyAddressable(x.A); #else int islocal = 1; #endif int numelems = RECTDOMAIN_SIZE(x.domain); int numbytes = numelems * ELEMSIZE; Pjbyte global_tiarray_data; LTAjbyte bytearray; /* our local temp array, and other useful handles to it */ PTAjbyte global_bytearray; Pjbyte global_bytearray_data; if (numelems == 0) return; { PTR_TO_T tiarray_firstelem = ti_get_array_data_ptr(x); #if GLOBAL_ARRAY global_tiarray_data = *(Pjbyte *)&tiarray_firstelem; #else globalize(global_tiarray_data, *(Ljbyte *)&tiarray_firstelem); #endif } DEBUGMSG3("islocal=%i iscontiguous=%i BYTESWAP=%i", islocal, iscontiguous, BYTESWAP); DEBUGMSG3("numbytes=%i numelems=%i ELEMSIZE=%i", numbytes, numelems, ELEMSIZE); DEBUGMSG2("global_tiarray_data=(%i)0x%08x", (int)TO_PROC(global_tiarray_data), (int)TO_LOCAL(global_tiarray_data)); #if GLOBAL_ARRAY DEBUGMSG2("x.A=(%i)0x%08x", (int)TO_PROC(x.A), (int)TO_LOCAL(x.A)); #else DEBUGMSG2("x.A=(%i)0x%08x", MYPROC, (int)x.A); #endif JAVA_ARRAY_ALLOC(bytearray, 0, numbytes, jbyte, 1, 1); globalize(global_bytearray, bytearray); FIELD_ADDR_GLOBAL( global_bytearray_data, global_bytearray, data[0] ); /* get ptr to data */ DEBUGMSG("Calling fileobj.read()"); TIARRAY_BULKIO_READFUNC_CALLIO(fileobj, global_bytearray, 0, numbytes); DEBUGMSG("Returned from fileobj.read()"); if (islocal) { if (iscontiguous) { /* local, contiguous */ if (BYTESWAP) ARRAY_COPY_BYTE_SWAP_GLOBAL(global_tiarray_data, global_bytearray_data, ELEMSIZE, numelems); else memcpy(TO_LOCAL(global_tiarray_data), TO_LOCAL(global_bytearray_data), numbytes); /* this memcpy could be removed for RAF fileobjects by violating the interface (making system call directly) */ /* or for all file objects if we had a level of indirection between java array descriptors and their data */ } else { /* local, non-contiguous */ copy_desc_t cd; if (BYTESWAP) ARRAY_BYTE_SWAP_GLOBAL(global_bytearray_data, ELEMSIZE, numelems); cd.x = x; cd.R = x.domain; UNPACK_METHOD(&cd, (void *)TO_LOCAL(global_bytearray_data)); /* scatter */ } } else { if (iscontiguous) { /* global, contiguous */ if (BYTESWAP) ARRAY_BYTE_SWAP_GLOBAL(global_bytearray_data, ELEMSIZE, numelems); local_to_global_copy( TO_LOCAL(global_bytearray_data), global_tiarray_data, numbytes ); } else { /* global, non-contiguous */ if (BYTESWAP) ARRAY_BYTE_SWAP_GLOBAL(global_bytearray_data, ELEMSIZE, numelems); #if GLOBAL_ARRAY && defined(COMM_AM2) { copy_desc_t cd; cd.x = x; cd.R = x.domain; /* transfer & scatter */ put_array((void*)UNPACK_METHOD, &cd, sizeof(cd), (void *)TO_LOCAL(global_bytearray_data), numbytes, TO_BOX(x.A)); } #else { /* TODO: this is very inefficient - may be faster to copy entire block and unpack locally */ int i, lo[N], hi[N], stride[N]; ti_POINT p, q, s; T *buf = (T *)TO_LOCAL(global_bytearray_data); /* Do an el-by-el copy. */ p = RECTDOMAIN_MIN(x.domain); q = RECTDOMAIN_MAX(x.domain); s = RECTDOMAIN_STRIDE(x.domain); for (i = 0; i < N; i++) { lo[i] = POINT_INDEX(p, i + 1); hi[i] = POINT_INDEX(q, i + 1); if ((stride[i] = POINT_INDEX(s, i + 1)) == 0) stride[i] = 1; } forall(e, x, lo, hi, stride, weak_assign(e, *(buf++)), WEAK_ASSIGN_LOCAL(e, *(buf++))); ti_sync(); } #endif } } JAVA_ARRAY_FREE(bytearray); return; /* could return numbytes here... */ } } #undef WHERE #undef STRINGIFY #endif /* ------------------------------------------------------------------------------------ */ #ifdef TIARRAY_BULKIO_WRITEFUNC_HEADER #define STRINGIFY(x) #x #define WHERE STRINGIFY(TIARRAY_BULKIO_WRITEFUNC_HEADER) TIARRAY_BULKIO_WRITEFUNC_HEADER { CHECK_NULL_GLOBAL(fileobj); /* eliminate the silly cases */ CHECK_NULL_TI_ARRAY(x); if (RECTDOMAIN_ISNULL(x.domain)) return; /* maybe should be an exn? */ { int iscontiguous = (int)ISCONTIGUOUS_METHOD(x); /* ti array props */ #if GLOBAL_ARRAY int islocal = (int)isDirectlyAddressable(x.A); #else int islocal = 1; #endif int numelems = RECTDOMAIN_SIZE(x.domain); int numbytes = numelems * ELEMSIZE; PTR_TO_T tiarray_firstelem; Pjbyte global_tiarray_data; LTAjbyte bytearray; /* our local temp array, and other useful handles to it */ PTAjbyte global_bytearray; Pjbyte global_bytearray_data; if (numelems == 0) return; { PTR_TO_T tiarray_firstelem = ti_get_array_data_ptr(x); #if GLOBAL_ARRAY global_tiarray_data = *(Pjbyte *)&tiarray_firstelem; #else globalize(global_tiarray_data, *(Ljbyte *)&tiarray_firstelem); #endif } DEBUGMSG3("islocal=%i iscontiguous=%i BYTESWAP=%i", islocal, iscontiguous, BYTESWAP); DEBUGMSG3("numbytes=%i numelems=%i ELEMSIZE=%i", numbytes, numelems, ELEMSIZE); DEBUGMSG2("global_tiarray_data=(%i)0x%08x", (int)TO_PROC(global_tiarray_data), (int)TO_LOCAL(global_tiarray_data)); #if GLOBAL_ARRAY DEBUGMSG2("x.A=(%i)0x%08x", (int)TO_PROC(x.A), (int)TO_LOCAL(x.A)); #else DEBUGMSG2("x.A=(%i)0x%08x", MYPROC, (int)x.A); #endif JAVA_ARRAY_ALLOC(bytearray, 0, numbytes, jbyte, 1, 1); globalize(global_bytearray, bytearray); FIELD_ADDR_GLOBAL( global_bytearray_data, global_bytearray, data[0] ); /* get ptr to data */ if (islocal) { if (iscontiguous) { /* local, contiguous */ if (BYTESWAP) ARRAY_COPY_BYTE_SWAP_GLOBAL(global_bytearray_data, global_tiarray_data, ELEMSIZE, numelems); else memcpy(TO_LOCAL(global_bytearray_data), TO_LOCAL(global_tiarray_data), numbytes); /* this memcpy could be removed for RAF fileobjects by violating the interface (making system call directly) */ /* or for all file objects if we had a level of indirection between java array descriptors and their data */ } else { /* local, non-contiguous */ int bytes_gathered; copy_desc_t cd; cd.x = x; cd.R = x.domain; PACK_METHOD(&cd, &bytes_gathered, (void *)TO_LOCAL(global_bytearray_data)); /* gather */ assert(bytes_gathered == numbytes); if (BYTESWAP) ARRAY_BYTE_SWAP_GLOBAL(global_bytearray_data, ELEMSIZE, numelems); } } else { if (iscontiguous) { /* global, contiguous */ global_to_local_copy( global_tiarray_data, TO_LOCAL(global_bytearray_data), numbytes ); if (BYTESWAP) ARRAY_BYTE_SWAP_GLOBAL(global_bytearray_data, ELEMSIZE, numelems); } else { /* global, non-contiguous */ #if GLOBAL_ARRAY && defined(COMM_AM2) { copy_desc_t cd; cd.x = x; cd.R = x.domain; /* gather & transfer */ get_array((void *)PACK_METHOD, &cd, sizeof(cd), TO_BOX(x.A), (void *)TO_LOCAL(global_bytearray_data), ELEMENTS_ARE_ATOMIC); } #else { /* TODO: this is very inefficient - may be faster to copy entire block and unpack locally */ int i, lo[N], hi[N], stride[N]; ti_POINT p, q, s; T *buf = (T *)TO_LOCAL(global_bytearray_data); /* Do an el-by-el copy. */ p = RECTDOMAIN_MIN(x.domain); q = RECTDOMAIN_MAX(x.domain); s = RECTDOMAIN_STRIDE(x.domain); for (i = 0; i < N; i++) { lo[i] = POINT_INDEX(p, i + 1); hi[i] = POINT_INDEX(q, i + 1); if ((stride[i] = POINT_INDEX(s, i + 1)) == 0) stride[i] = 1; } forall(e, x, lo, hi, stride, deref(*(buf++), e), DEREF_LOCAL(*(buf++), e)); ti_sync(); } #endif if (BYTESWAP) ARRAY_BYTE_SWAP_GLOBAL(global_bytearray_data, ELEMSIZE, numelems); } } DEBUGMSG("Calling fileobj.write()"); TIARRAY_BULKIO_WRITEFUNC_CALLIO(fileobj, global_bytearray, 0, numbytes); DEBUGMSG("Returned from fileobj.write()"); JAVA_ARRAY_FREE(bytearray); return; /* could return numbytes here... */ } } #undef WHERE #undef STRINGIFY #endif /* ------------------------------------------------------------------------------------ */ #undef BYTESWAP /* ------------------------------------------------------------------------------------ */