📄 datatype_pack.c
字号:
max_allowed -= done; total_bytes_converted += done; user_memory += (extent - pData->size + done); } counter = (uint32_t)(max_allowed / pData->size); if( counter > pConv->count ) counter = pConv->count; for( i = 0; i < counter; i++ ) { OMPI_DDT_SAFEGUARD_POINTER( user_memory, pData->size, pConv->pBaseBuf, pData, pConv->count ); MEMCPY_CSUM( packed_buffer, user_memory, pData->size, pConv ); packed_buffer+= pData->size; user_memory += extent; } done = (counter * pData->size); max_allowed -= done; total_bytes_converted += done; /* If there is anything pending ... */ if( 0 != max_allowed ) { done = max_allowed; OMPI_DDT_SAFEGUARD_POINTER( user_memory, done, pConv->pBaseBuf, pData, pConv->count ); MEMCPY_CSUM( packed_buffer, user_memory, done, pConv ); packed_buffer += done; max_allowed = 0; total_bytes_converted += done; user_memory += done; } } } pStack[0].disp = (intptr_t)user_memory - (intptr_t)pConv->pBaseBuf - initial_displ; pStack[1].disp = max_allowed; *max_data = total_bytes_converted; pConv->bConverted += total_bytes_converted; *out_size = iov_count; if( pConv->bConverted == pConv->local_size ) { pConv->flags |= CONVERTOR_COMPLETED; return 1; } return 0;}/* The pack/unpack functions need a cleanup. I have to create a proper interface to access * all basic functionalities, hence using them as basic blocks for all conversion functions. * * But first let's make some global assumptions: * - a datatype (with the flag DT_DATA set) will have the contiguous flags set if and only if * the data is really contiguous (extent equal with size) * - for the DT_LOOP type the DT_CONTIGUOUS flag set means that the content of the loop is * contiguous but with a gap in the begining or at the end. * - the DT_CONTIGUOUS flag for the type DT_END_LOOP is meaningless. */int32_tompi_generic_simple_pack_function( ompi_convertor_t* pConvertor, struct iovec* iov, uint32_t* out_size, size_t* max_data ){ dt_stack_t* pStack; /* pointer to the position on the stack */ uint32_t pos_desc; /* actual position in the description of the derived datatype */ uint32_t count_desc; /* the number of items already done in the actual pos_desc */ uint16_t type; /* type at current position */ size_t total_packed = 0; /* total amount packed this time */ dt_elem_desc_t* description; dt_elem_desc_t* pElem; const ompi_datatype_t *pData = pConvertor->pDesc; char *source_base, *destination; size_t iov_len_local; uint32_t iov_count; DO_DEBUG( opal_output( 0, "ompi_convertor_generic_simple_pack( %p, {%p, %lu}, %d )\n", (void*)pConvertor, iov[0].iov_base, (unsigned long)iov[0].iov_len, *out_size ); ); description = pConvertor->use_desc->desc; /* For the first step we have to add both displacement to the source. After in the * main while loop we will set back the source_base to the correct value. This is * due to the fact that the convertor can stop in the middle of a data with a count */ pStack = pConvertor->pStack + pConvertor->stack_pos; pos_desc = pStack->index; source_base = pConvertor->pBaseBuf + pStack->disp; count_desc = (uint32_t)pStack->count; pStack--; pConvertor->stack_pos--; pElem = &(description[pos_desc]); source_base += pStack->disp; DO_DEBUG( opal_output( 0, "unpack start pos_desc %d count_desc %d disp %ld\n" "stack_pos %d pos_desc %d count_desc %d disp %ld\n", pos_desc, count_desc, (long)(source_base - pConvertor->pBaseBuf), pConvertor->stack_pos, pStack->index, (int)pStack->count, (long)pStack->disp ); ); for( iov_count = 0; iov_count < (*out_size); iov_count++ ) { destination = iov[iov_count].iov_base; iov_len_local = iov[iov_count].iov_len; while( 1 ) { while( pElem->elem.common.flags & DT_FLAG_DATA ) { /* now here we have a basic datatype */ PACK_PREDEFINED_DATATYPE( pConvertor, pElem, count_desc, source_base, destination, iov_len_local ); if( 0 == count_desc ) { /* completed */ source_base = pConvertor->pBaseBuf + pStack->disp; pos_desc++; /* advance to the next data */ UPDATE_INTERNAL_COUNTERS( description, pos_desc, pElem, count_desc ); continue; } type = pElem->elem.common.type; goto complete_loop; } if( DT_END_LOOP == pElem->elem.common.type ) { /* end of the current loop */ DO_DEBUG( opal_output( 0, "pack end_loop count %d stack_pos %d pos_desc %d disp %ld space %lu\n", (int)pStack->count, pConvertor->stack_pos, pos_desc, (long)pStack->disp, (unsigned long)iov_len_local ); ); if( --(pStack->count) == 0 ) { /* end of loop */ if( pConvertor->stack_pos == 0 ) { /* we lie about the size of the next element in order to * make sure we exit the main loop. */ *out_size = iov_count; goto complete_loop; /* completed */ } pConvertor->stack_pos--; pStack--; pos_desc++; } else { pos_desc = pStack->index + 1; if( pStack->index == -1 ) { pStack->disp += (pData->ub - pData->lb); } else { assert( DT_LOOP == description[pStack->index].loop.common.type ); pStack->disp += description[pStack->index].loop.extent; } } source_base = pConvertor->pBaseBuf + pStack->disp; UPDATE_INTERNAL_COUNTERS( description, pos_desc, pElem, count_desc ); DO_DEBUG( opal_output( 0, "pack new_loop count %d stack_pos %d pos_desc %d disp %ld space %lu\n", (int)pStack->count, pConvertor->stack_pos, pos_desc, (long)pStack->disp, (unsigned long)iov_len_local ); ); } if( DT_LOOP == pElem->elem.common.type ) { ptrdiff_t local_disp = (ptrdiff_t)source_base; if( pElem->loop.common.flags & DT_FLAG_CONTIGUOUS ) { PACK_CONTIGUOUS_LOOP( pConvertor, pElem, count_desc, source_base, destination, iov_len_local ); if( 0 == count_desc ) { /* completed */ pos_desc += pElem->loop.items + 1; goto update_loop_description; } /* Save the stack with the correct last_count value. */ } local_disp = (ptrdiff_t)source_base - local_disp; PUSH_STACK( pStack, pConvertor->stack_pos, pos_desc, DT_LOOP, count_desc, pStack->disp + local_disp); pos_desc++; update_loop_description: /* update the current state */ source_base = pConvertor->pBaseBuf + pStack->disp; UPDATE_INTERNAL_COUNTERS( description, pos_desc, pElem, count_desc ); DDT_DUMP_STACK( pConvertor->pStack, pConvertor->stack_pos, pElem, "advance loop" ); continue; } } complete_loop: iov[iov_count].iov_len -= iov_len_local; /* update the amount of valid data */ total_packed += iov[iov_count].iov_len; pConvertor->bConverted += iov[iov_count].iov_len; /* update the already converted bytes */ } *max_data = total_packed; *out_size = iov_count;#if 0 if( pConvertor->flags & CONVERTOR_WITH_CHECKSUM ) { uint32_t ui1 = 0, ui2 = 0, csum = OPAL_CSUM_ZERO; /** * Check the checksum correctness. */ for( iov_count = 0; iov_count < (*out_size); iov_count++ ) { csum += opal_uicsum_partial( iov[iov_count].iov_base, iov[iov_count].iov_len, &ui1, &ui2 ); } if( csum != pConvertor->checksum ) { opal_output( 0, "error in the pack function the checksum does not match\n" "(%d != %d)\n", csum, pConvertor->checksum ); } }#endif if( pConvertor->bConverted == pConvertor->local_size ) { pConvertor->flags |= CONVERTOR_COMPLETED; return 1; } /* I complete an element, next step I should go to the next one */ PUSH_STACK( pStack, pConvertor->stack_pos, pos_desc, DT_BYTE, count_desc, source_base - pStack->disp - pConvertor->pBaseBuf ); DO_DEBUG( opal_output( 0, "pack save stack stack_pos %d pos_desc %d count_desc %d disp %ld\n", pConvertor->stack_pos, pStack->index, (int)pStack->count, (long)pStack->disp ); ); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -