⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 datatype_pack.c

📁 MPI stands for the Message Passing Interface. Written by the MPI Forum (a large committee comprising
💻 C
📖 第 1 页 / 共 2 页
字号:
                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 + -