📄 dt_args.c
字号:
/* -*- Mode: C; c-basic-offset:4 ; -*- *//* * Copyright (c) 2004-2006 The Trustees of Indiana University and Indiana * University Research and Technology * Corporation. All rights reserved. * Copyright (c) 2004-2006 The University of Tennessee and The University * of Tennessee Research Foundation. All rights * reserved. * Copyright (c) 2004-2006 High Performance Computing Center Stuttgart, * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2006 The Regents of the University of California. * All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow * * $HEADER$ */#include "ompi_config.h"#include "mpi.h"#include "ompi/datatype/datatype.h"#include "ompi/datatype/datatype_internal.h"#include "ompi/datatype/dt_arch.h"#include "ompi/proc/proc.h"static inline int__ompi_ddt_pack_description( ompi_datatype_t* datatype, void** packed_buffer, int* next_index );static ompi_datatype_t*__ompi_ddt_create_from_args( int32_t* i, MPI_Aint* a, MPI_Datatype* d, int32_t type );typedef struct __dt_args { int ref_count; int create_type; size_t total_pack_size; int ci; int ca; int cd; int* i; MPI_Aint* a; MPI_Datatype* d;} ompi_ddt_args_t;/** * Some architecture require that 64 bits pointers (to pointers) has to * be 64 bits aligned. As in the ompi_ddt_args_t structure we have 2 such * pointers and one to an array of ints, if we start by setting the 64 * bits aligned one we will not have any trouble. Problem arise on * SPARC 64. */#define ALLOC_ARGS(PDATA, IC, AC, DC) \ do { \ int length = sizeof(ompi_ddt_args_t) + (IC) * sizeof(int) + \ (AC) * sizeof(MPI_Aint) + (DC) * sizeof(MPI_Datatype); \ char* buf = (char*)malloc( length ); \ ompi_ddt_args_t* pArgs = (ompi_ddt_args_t*)buf; \ pArgs->ci = (IC); \ pArgs->ca = (AC); \ pArgs->cd = (DC); \ buf += sizeof(ompi_ddt_args_t); \ if( pArgs->ca == 0 ) pArgs->a = NULL; \ else { \ pArgs->a = (MPI_Aint*)buf; \ buf += pArgs->ca * sizeof(MPI_Aint); \ } \ if( pArgs->cd == 0 ) pArgs->d = NULL; \ else { \ pArgs->d = (MPI_Datatype*)buf; \ buf += pArgs->cd * sizeof(MPI_Datatype); \ } \ if( pArgs->ci == 0 ) pArgs->i = NULL; \ else pArgs->i = (int*)buf; \ pArgs->ref_count = 1; \ pArgs->total_pack_size = (4 + (IC)) * sizeof(int) + \ (AC) * sizeof(MPI_Aint) + (DC) * sizeof(int); \ (PDATA)->args = (void*)pArgs; \ (PDATA)->packed_description = NULL; \ } while(0)int32_t ompi_ddt_set_args( ompi_datatype_t* pData, int32_t ci, int32_t** i, int32_t ca, MPI_Aint* a, int32_t cd, MPI_Datatype* d, int32_t type){ int pos; ompi_ddt_args_t* pArgs; assert( NULL == pData->args ); ALLOC_ARGS( pData, ci, ca, cd ); pArgs = (ompi_ddt_args_t*)pData->args; pArgs->create_type = type; switch(type){ case MPI_COMBINER_DUP: /* Recompute the data description packed size based on the optimization * for MPI_COMBINER_DUP. */ pArgs->total_pack_size = 2 * sizeof(int); break; case MPI_COMBINER_CONTIGUOUS: pArgs->i[0] = i[0][0]; break; case MPI_COMBINER_VECTOR: pArgs->i[0] = i[0][0]; pArgs->i[1] = i[1][0]; pArgs->i[2] = i[2][0]; break; case MPI_COMBINER_HVECTOR_INTEGER: case MPI_COMBINER_HVECTOR: pArgs->i[0] = i[0][0]; pArgs->i[1] = i[1][0]; break; case MPI_COMBINER_INDEXED: pos = 1; pArgs->i[0] = i[0][0]; memcpy( pArgs->i + pos, i[1], i[0][0] * sizeof(int) ); pos += i[0][0]; memcpy( pArgs->i + pos, i[2], i[0][0] * sizeof(int) ); break; case MPI_COMBINER_HINDEXED_INTEGER: case MPI_COMBINER_HINDEXED: pArgs->i[0] = i[0][0]; memcpy( pArgs->i + 1, i[1], i[0][0] * sizeof(int) ); break; case MPI_COMBINER_INDEXED_BLOCK: pArgs->i[0] = i[0][0]; pArgs->i[1] = i[1][0]; memcpy( pArgs->i + 2, i[2], i[0][0] * sizeof(int) ); break; case MPI_COMBINER_STRUCT_INTEGER: case MPI_COMBINER_STRUCT: pArgs->i[0] = i[0][0]; memcpy( pArgs->i + 1, i[1], i[0][0] * sizeof(int) ); break; case MPI_COMBINER_SUBARRAY: pos = 1; pArgs->i[0] = i[0][0]; memcpy( pArgs->i + pos, i[1], pArgs->i[0] * sizeof(int) ); pos += pArgs->i[0]; memcpy( pArgs->i + pos, i[2], pArgs->i[0] * sizeof(int) ); pos += pArgs->i[0]; memcpy( pArgs->i + pos, i[3], pArgs->i[0] * sizeof(int) ); pos += pArgs->i[0]; pArgs->i[pos] = i[4][0]; break; case MPI_COMBINER_DARRAY: pos = 3; pArgs->i[0] = i[0][0]; pArgs->i[1] = i[1][0]; pArgs->i[2] = i[2][0]; memcpy( pArgs->i + pos, i[3], i[2][0] * sizeof(int) ); pos += i[2][0]; memcpy( pArgs->i + pos, i[4], i[2][0] * sizeof(int) ); pos += i[2][0]; memcpy( pArgs->i + pos, i[5], i[2][0] * sizeof(int) ); pos += i[2][0]; memcpy( pArgs->i + pos, i[6], i[2][0] * sizeof(int) ); pos += i[2][0]; pArgs->i[pos] = i[7][0]; break; case MPI_COMBINER_F90_REAL: case MPI_COMBINER_F90_COMPLEX: pArgs->i[0] = i[0][0]; pArgs->i[1] = i[1][0]; break; case MPI_COMBINER_F90_INTEGER: pArgs->i[0] = i[0][0]; break; case MPI_COMBINER_RESIZED: break; default: break; } /* copy the array of MPI_Aint */ if( pArgs->a != NULL ) memcpy( pArgs->a, a, ca * sizeof(MPI_Aint) ); for( pos = 0; pos < cd; pos++ ) { pArgs->d[pos] = d[pos]; if( !(d[pos]->flags & DT_FLAG_PREDEFINED) ) { /* We handle a user defined datatype. We should make sure that the * user will not have the oportunity to destroy it before all derived * datatypes are destroyed. As we keep pointers to every datatype * (for MPI_Type_get_content and MPI_Type_get_envelope) we have to make * sure that those datatype will be available if the user ask for them. * However, there is no easy way to free them in this case ... */ OBJ_RETAIN( d[pos] ); pArgs->total_pack_size += ((ompi_ddt_args_t*)d[pos]->args)->total_pack_size; } } return MPI_SUCCESS;}int32_t ompi_ddt_print_args( const ompi_datatype_t* pData ){ int32_t i; ompi_ddt_args_t* pArgs = (ompi_ddt_args_t*)pData->args; if( pData->flags & DT_FLAG_PREDEFINED ) { /* nothing to do for predefined data-types */ return(MPI_SUCCESS); } if( pArgs == NULL ) return MPI_ERR_INTERN; printf( "type %d count ints %d count disp %d count datatype %d\n", pArgs->create_type, pArgs->ci, pArgs->ca, pArgs->cd ); if( pArgs->i != NULL ) { printf( "ints: " ); for( i = 0; i < pArgs->ci; i++ ) { printf( "%d ", pArgs->i[i] ); } printf( "\n" ); } if( pArgs->a != NULL ) { printf( "MPI_Aint: " ); for( i = 0; i < pArgs->ca; i++ ) { printf( "%ld ", (long)pArgs->a[i] ); } printf( "\n" ); } if( pArgs->d != NULL ) { int count = 1; ompi_datatype_t *temp, *old; printf( "types: " ); old = pArgs->d[0]; for( i = 1; i < pArgs->cd; i++ ) { temp = pArgs->d[i]; if( old == temp ) { count++; continue; } if( count <= 1 ) { if( old->flags & DT_FLAG_PREDEFINED ) printf( "%s ", old->name ); else printf( "%p ", (void*)old ); } else { if( old->flags & DT_FLAG_PREDEFINED ) printf( "(%d * %s) ", count, old->name ); else printf( "(%d * %p) ", count, (void*)old ); } count = 1; old = temp; } if( count <= 1 ) { if( old->flags & DT_FLAG_PREDEFINED ) printf( "%s ", old->name ); else printf( "%p ", (void*)old ); } else { if( old->flags & DT_FLAG_PREDEFINED ) printf( "(%d * %s) ", count, old->name ); else printf( "(%d * %p) ", count, (void*)old ); } printf( "\n" ); } return MPI_SUCCESS;}int32_t ompi_ddt_get_args( const ompi_datatype_t* pData, int32_t which, int32_t* ci, int32_t* i, int32_t* ca, MPI_Aint* a, int32_t* cd, MPI_Datatype* d, int32_t* type){ ompi_ddt_args_t* pArgs = (ompi_ddt_args_t*)pData->args; if( pData->flags & DT_FLAG_PREDEFINED ) { switch(which){ case 0: *ci = 0; *ca = 0; *cd = 0; *type = MPI_COMBINER_NAMED; break; default: return MPI_ERR_INTERN; } return(MPI_SUCCESS); } if( pArgs == NULL ) return MPI_ERR_INTERN; switch(which){ case 0: /* GET THE LENGTHS */ *ci = pArgs->ci; *ca = pArgs->ca; *cd = pArgs->cd; *type = pArgs->create_type; break; case 1: /* GET THE ARGUMENTS */ if(*ci < pArgs->ci || *ca < pArgs->ca || *cd < pArgs->cd) return MPI_ERR_ARG; if( pArgs->i != NULL ) memcpy( i, pArgs->i, pArgs->ci * sizeof(int) ); if( pArgs->a != NULL ) memcpy( a, pArgs->a, pArgs->ca * sizeof(MPI_Aint) ); if( pArgs->d != NULL ) memcpy( d, pArgs->d, pArgs->cd * sizeof(MPI_Datatype) ); break; default: return MPI_ERR_INTERN; } return MPI_SUCCESS;}int32_t ompi_ddt_copy_args( const ompi_datatype_t* source_data, ompi_datatype_t* dest_data ){ ompi_ddt_args_t* pArgs = (ompi_ddt_args_t*)source_data->args;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -