First implementation of the checksum in the datatype engine. I'm using adler 32
the same algorithm as in the zlib library, as it is supposed to be the fastest one and still give good error detection. For those who want to activate the checksum, there is a define at the bottom of the datatype_internal.h file. This commit was SVN r8509.
Этот коммит содержится в:
родитель
2a94f693f6
Коммит
e008196f50
@ -92,7 +92,7 @@ inline int32_t ompi_convertor_pack( ompi_convertor_t* pConv,
|
||||
struct iovec* iov, uint32_t* out_size,
|
||||
size_t* max_data, int32_t* freeAfter )
|
||||
{
|
||||
pConv->checksum = 0;
|
||||
pConv->checksum = 1;
|
||||
/* protect against over packing data */
|
||||
if( pConv->bConverted == (pConv->pDesc->size * pConv->count) ) {
|
||||
iov[0].iov_len = 0;
|
||||
@ -101,6 +101,7 @@ inline int32_t ompi_convertor_pack( ompi_convertor_t* pConv,
|
||||
return 1; /* nothing to do */
|
||||
}
|
||||
assert( pConv->bConverted < (pConv->pDesc->size * pConv->count) );
|
||||
|
||||
/* We dont allocate any memory. The packing function should allocate it
|
||||
* if it need. If it's possible to find iovec in the derived datatype
|
||||
* description then we dont have to allocate any memory.
|
||||
@ -114,7 +115,7 @@ inline int32_t ompi_convertor_unpack( ompi_convertor_t* pConv,
|
||||
{
|
||||
const ompi_datatype_t *pData = pConv->pDesc;
|
||||
|
||||
pConv->checksum = 0;
|
||||
pConv->checksum = 1;
|
||||
/* protect against over unpacking data */
|
||||
if( pConv->bConverted == (pData->size * pConv->count) ) {
|
||||
iov[0].iov_len = 0;
|
||||
|
@ -318,6 +318,50 @@ static inline int GET_FIRST_NON_LOOP( const dt_elem_desc_t* _pElem )
|
||||
return index;
|
||||
}
|
||||
|
||||
/* Please set it to one if you want data checksum. The current implementation
|
||||
* use ADLER32 algorithm.
|
||||
*/
|
||||
#define OMPI_REQUIRE_DATA_VALIDATION 1
|
||||
|
||||
/* ADLER_NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
|
||||
#define ADLER_NMAX 5551
|
||||
#define MOD_ADLER 65521
|
||||
|
||||
#if OMPI_REQUIRE_DATA_VALIDATION
|
||||
|
||||
#define DO1(buf,i) {_a += buf[i]; _b += _a;}
|
||||
#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
|
||||
#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
|
||||
#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
|
||||
#define DO16(buf) DO8(buf,0); DO8(buf,8);
|
||||
|
||||
#define COMPUTE_SPECIFIC_CHECKSUM( DATA, LENGTH, ADLER32) \
|
||||
do { \
|
||||
uint8_t *_data = (DATA); /* Pointer to the data to be summed */ \
|
||||
size_t _len = (LENGTH); /* Length in bytes */ \
|
||||
uint32_t _a = (ADLER32) & 0xffff, \
|
||||
_b = ((ADLER32) >> 16) & 0xffff; \
|
||||
\
|
||||
while( _len > 0 ) { \
|
||||
unsigned _tlen = _len > ADLER_NMAX ? ADLER_NMAX : _len; \
|
||||
_len -= _tlen; \
|
||||
while( _tlen >= 16 ) { \
|
||||
DO16(_data); \
|
||||
_data += 16; \
|
||||
_tlen -= 16; \
|
||||
} \
|
||||
if( 0 != _tlen ) do { \
|
||||
_a += *_data++; _b += _a; \
|
||||
} while( --_tlen > 0 ); \
|
||||
_a = _a % MOD_ADLER; \
|
||||
_b = _b % MOD_ADLER; \
|
||||
} \
|
||||
(ADLER32) = _b << 16 | _a; \
|
||||
} while(0)
|
||||
#else
|
||||
#define COMPUTE_SPECIFIC_CHECKSUM( DATA, LENGTH, ADLER32 )
|
||||
#endif /* OMPI_REQUIRE_DATA_VALIDATION */
|
||||
|
||||
#if defined(c_plusplus) || defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
@ -619,6 +619,12 @@ ompi_convertor_pack_no_conv_contig( ompi_convertor_t* pConv,
|
||||
length -= iov[iov_count].iov_len;
|
||||
pConv->bConverted += iov[iov_count].iov_len;
|
||||
pStack[0].disp += iov[iov_count].iov_len;
|
||||
/* We compute the checksum if we have to. But we will store the temporary
|
||||
* values in the a and b variables, and only at the end take in account the
|
||||
* value of the convertor checksum.
|
||||
*/
|
||||
COMPUTE_SPECIFIC_CHECKSUM( iov[iov_count].iov_base, iov[iov_count].iov_len,
|
||||
pConv->checksum );
|
||||
}
|
||||
|
||||
/* update the return value */
|
||||
@ -752,6 +758,12 @@ ompi_convertor_pack_no_conv_contig_with_gaps( ompi_convertor_t* pConv,
|
||||
* it's supposed to be useless from now.
|
||||
*/
|
||||
user_memory = pConv->pBaseBuf + pStack[0].disp;
|
||||
/* We compute the checksum if we have to. But we will store the temporary
|
||||
* values in the a and b variables, and only at the end take in account the
|
||||
* value of the convertor checksum.
|
||||
*/
|
||||
COMPUTE_SPECIFIC_CHECKSUM( iov[iov_count].iov_base, iov[iov_count].iov_len,
|
||||
pConv->checksum );
|
||||
}
|
||||
*max_data = total_bytes_converted;
|
||||
pConv->bConverted += total_bytes_converted;
|
||||
|
@ -390,6 +390,12 @@ static int ompi_convertor_unpack_homogeneous_contig( ompi_convertor_t* pConv,
|
||||
stack->disp = user_memory - pData->true_lb - pConv->pBaseBuf; /* save the position */
|
||||
}
|
||||
pConv->bConverted += bConverted;
|
||||
/* We compute the checksum if we have to. But we will store the temporary
|
||||
* values in the a and b variables, and only at the end take in account the
|
||||
* value of the convertor checksum.
|
||||
*/
|
||||
COMPUTE_SPECIFIC_CHECKSUM( iov[iov_count].iov_base, iov[iov_count].iov_len,
|
||||
pConv->checksum );
|
||||
}
|
||||
*out_size = iov_count;
|
||||
*max_data = (pConv->bConverted - initial_bytes_converted);
|
||||
|
@ -266,6 +266,12 @@ int ompi_convertor_generic_simple_pack( ompi_convertor_t* pConvertor,
|
||||
total_packed += iov[iov_count].iov_len;
|
||||
pConvertor->bConverted += iov[iov_count].iov_len; /* update the already converted bytes */
|
||||
assert( iov_len_local >= 0 );
|
||||
/* We compute the checksum if we have to. But we will store the temporary
|
||||
* values in the a and b variables, and only at the end take in account the
|
||||
* value of the convertor checksum.
|
||||
*/
|
||||
COMPUTE_SPECIFIC_CHECKSUM( iov[iov_count].iov_base, iov[iov_count].iov_len,
|
||||
pConvertor->checksum );
|
||||
}
|
||||
*max_data = total_packed;
|
||||
*out_size = iov_count;
|
||||
|
@ -278,6 +278,12 @@ int ompi_convertor_generic_simple_unpack( ompi_convertor_t* pConvertor,
|
||||
DO_DEBUG( opal_output( 0, "Saving %d bytes for the next call\n", iov_len_local ); );
|
||||
pConvertor->pending_length = iov_len_local;
|
||||
}
|
||||
/* We compute the checksum if we have to. But we will store the temporary
|
||||
* values in the a and b variables, and only at the end take in account the
|
||||
* value of the convertor checksum.
|
||||
*/
|
||||
COMPUTE_SPECIFIC_CHECKSUM( iov[iov_count].iov_base, iov[iov_count].iov_len,
|
||||
pConvertor->checksum );
|
||||
}
|
||||
*max_data = total_unpacked;
|
||||
*out_size = iov_count;
|
||||
|
Загрузка…
Ссылка в новой задаче
Block a user