/* $Source: runtime/gasnet/shmem-conduit/gasnet_extended_help_extra.h $ * $Date: Sat, 13 Aug 2005 21:06:53 -0700 $ * $Revision: 1.3 $ * Description: GASNet Extended Shmem-specific Header * Copyright 2005, Christian Bell * Terms of use are as specified in license.txt */ #ifndef _IN_GASNET_H #error This file is not meant to be included directly- clients should include gasnet.h #endif #if defined(CRAY_SHMEM) || defined(SGI_SHMEM) #include #else #include #endif #include /* memcpy */ #ifndef _GASNET_EXTENDED_HELP_EXTRA_H #define _GASNET_EXTENDED_HELP_EXTRA_H /* * Defining GASNETE_NBISYNC_ALWAYS_QUIET causes a quiet to be generated at * every nbi sync operation instead of only NBIs that contain puts. This * allows puts to be be completed as 1-store instead of 2-stores. * * This is more important on X1 since we really want the nbi loop to * generate a vector load/store. */ #if defined(CRAYX1) #define GASNETE_NBISYNC_ALWAYS_QUIET 1 #else #define GASNETE_NBISYNC_ALWAYS_QUIET 0 #endif #define GASNETE_OK 0 /* Always 0, same as GASNET_OK */ #ifndef _GASNET_ERRORS #define _GASNET_ERRORS #define _GASNET_ERR_BASE 10000 #define GASNET_ERR_NOT_INIT (_GASNET_ERR_BASE+1) #define GASNET_ERR_RESOURCE (_GASNET_ERR_BASE+2) #define GASNET_ERR_BAD_ARG (_GASNET_ERR_BASE+3) #define GASNET_ERR_NOT_READY (_GASNET_ERR_BASE+4) #define GASNET_ERR_BARRIER_MISMATCH (_GASNET_ERR_BASE+5) #endif #if defined(CRAY_SHMEM) #include #include #define GASNETE_PRAGMA_IVDEP _Pragma("_CRI ivdep") extern uintptr_t gasnete_pe_bits_shift; extern uintptr_t gasnete_addr_bits_mask; /* Translation on X1 -- works in every GASNet configuration, but we can * ignore the translation on clients that already understand global pointers */ #define GASNETE_TRANSLATE_X1(addr,pe) \ (void *) ( (((uintptr_t) (addr)) & gasnete_addr_bits_mask) | \ (((uintptr_t) (pe)) << gasnete_pe_bits_shift)) #define GASNETE_TRANSLATE_PTR GASNETE_TRANSLATE_X1 #elif defined(SGI_SHMEM) #define GASNETE_PRAGMA_IVDEP /* no ivdep is useful here */ #define GASNETE_TRANSLATE_PTR(addr,pe) shmem_ptr(addr,pe) #endif /* The translation is free when using segment-large or segment-fast. For * segment-everything, the translation is only free if the client can manage * global addresses itself (and asserts that it can). */ #if defined(GASNETE_GLOBAL_ADDRESS_CLIENT) || \ defined(GASNET_SEGMENT_FAST) || defined(GASNET_SEGMENT_LARGE) #define GASNETE_SHMPTR(addr,pe) (addr) #else #define GASNETE_SHMPTR(addr,pe) GASNETE_TRANSLATE_PTR(addr,pe) #endif #define GASNETE_SHMPTR_AM(addr,pe) GASNETE_TRANSLATE_PTR(addr,pe) #ifdef CRAYX1 #define _GASNETE_CRAYX1_ONLY(x) x #else #define _GASNETE_CRAYX1_ONLY(x) #endif #define _GASNETE_INLINE_VLOOP(dest,src,nbytes) \ do { \ unsigned long i, sz; \ sz = ((unsigned long)(nbytes))>>3; \ for (i=0; i sizeof(gasnet_register_value_t)) gasneti_fatalerror( "VIOLATION: Unsupported size %d in valget", nbytes); #endif shmem_getmem((void *) &tempA, src, nbytes, node); return (gasnet_valget_handle_t) tempA; } } } #endif #define gasnete_get_val (gasnet_register_value_t) gasnete_get_nb_val /* * Since shmem only has blocking valgets, we use the value as the handle and * the resulting value. */ #define gasnete_wait_syncnb_valget(handle) ((gasnet_register_value_t)handle) /* ------------------------------------------------------------------------------------ */ /* Non-Blocking and Blocking Value Put ==================================== */ #ifdef GASNETE_GLOBAL_ADDRESS GASNET_INLINE_MODIFIER(gasnete_put_val_inner) void gasnete_put_val_inner(gasnet_node_t node, void *dest, gasnet_register_value_t value, size_t nbytes) { switch (nbytes) { case 8: *((uint64_t *)GASNETE_SHMPTR(dest,node)) = (uint64_t)value; return; case 4: *((uint32_t *)GASNETE_SHMPTR(dest,node)) = (uint32_t)value; return; case 2: *((uint16_t *)GASNETE_SHMPTR(dest,node)) = (uint16_t)value; return; case 1: *((uint8_t *)GASNETE_SHMPTR(dest,node)) = (uint8_t)value; return; default: #if 0 gasneti_fatalerror( "VIOLATION: Unsupported size %d in valput", nbytes); #endif break; } return; } #else GASNET_INLINE_MODIFIER(gasnete_put_val_inner) void gasnete_put_val_inner(gasnet_node_t node, void *dest, gasnet_register_value_t value, size_t nbytes) { static char val_put[8]; switch (nbytes) { #ifdef GASNET_SHMEM_PUT_8 case 8: GASNET_SHMEM_PUT_8(dest, value, node); return; #endif #ifdef GASNET_SHMEM_PUT_4 case 4: GASNET_SHMEM_PUT_4(dest, value, node); return; #endif #ifdef GASNET_SHMEM_PUT_2 case 2: GASNET_SHMEM_PUT_2(dest, value, node); return; #endif case 0: return; default: #if 0 && defined(GASNET_DEBUG) if (nbytes > sizeof(gasnet_register_value_t)) gasneti_fatalerror( "VIOLATION: Unsupported size %d in valput", nbytes); #endif memcpy(val_put, &value, nbytes); shmem_putmem(dest, val_put, nbytes, node); return; } } #endif GASNET_INLINE_MODIFIER(_gasnete_put_val) void _gasnete_put_val(gasnet_node_t node, void *dest, gasnet_register_value_t value, size_t nbytes) { gasnete_put_val_inner(node, dest, value, nbytes); /* No choice here -- we need remote completion, so big quiet hammer */ shmem_quiet(); } #define gasnete_put_val _gasnete_put_val GASNET_INLINE_MODIFIER(_gasnete_put_nb_val) gasnet_handle_t _gasnete_put_nb_val(gasnet_node_t node, void *dest, gasnet_register_value_t value, size_t nbytes) { gasnete_put_val_inner(node, dest, value, nbytes); return GASNETE_SYNC_QUIET; } #define gasnete_put_nb_val _gasnete_put_nb_val GASNET_INLINE_MODIFIER(_gasnete_put_nbi_val) void _gasnete_put_nbi_val(gasnet_node_t node, void *dest, gasnet_register_value_t value, size_t nbytes) { gasnete_put_val_inner(node, dest, value, nbytes); gasnete_nbisync_cur = GASNETE_SYNC_QUIET; return; } #define gasnete_put_nbi_val _gasnete_put_nbi_val #endif