Commit ac4f4cd1 authored by Jayesh Krishna's avatar Jayesh Krishna
Browse files

[svn-r4062] 1) Modifying the datatype code to find the number of contig blocks...

[svn-r4062] 1) Modifying the datatype code to find the number of contig blocks in an instance of an MPI derived datatype - Since finding the real number of contig blocks is not easy we find a reasonable upper bound instead. This also fixes the case where the number of contig blocks was uninitialized for contiguous datatypes. Refer ticket #428 for details (2) Adding a test case, test1_dt.c, to test the fix - Review @ rross, thakur
parent 9dbae30f
......@@ -731,7 +731,7 @@ int MPID_nem_mx_process_rdtype(MPID_Request **rreq_p, MPID_Datatype * dt_ptr, MP
MPID_IOV *iov;
MPIDI_msg_sz_t last;
int num_entries = MX_MAX_SEGMENTS;
int iov_num_ub = rreq->dev.user_count * dt_ptr->n_contig_blocks;
int iov_num_ub = rreq->dev.user_count * dt_ptr->max_contig_blocks;
int n_iov = iov_num_ub;
int mpi_errno = MPI_SUCCESS;
int index;
......
......@@ -395,7 +395,7 @@ int MPID_nem_mx_process_sdtype(MPID_Request **sreq_p, MPI_Datatype datatype, M
MPID_IOV *iov;
MPIDI_msg_sz_t last;
int num_entries = MX_MAX_SEGMENTS - first_free_slot;
int iov_num_ub = count * dt_ptr->n_contig_blocks;
int iov_num_ub = count * dt_ptr->max_contig_blocks;
int n_iov = iov_num_ub;
int mpi_errno = MPI_SUCCESS;
int index;
......
......@@ -289,7 +289,7 @@ int MPID_nem_newmad_process_sdtype(MPID_Request **sreq_p, MPI_Datatype datatype
{
MPID_Request *sreq =*sreq_p;
MPIDI_msg_sz_t last;
int iov_num_ub = count * dt_ptr->n_contig_blocks;
int iov_num_ub = count * dt_ptr->max_contig_blocks;
int n_iov = iov_num_ub;
int mpi_errno = MPI_SUCCESS;
......
......@@ -13,7 +13,7 @@
/* to send derived datatype across in RMA ops */
typedef struct MPIDI_RMA_dtype_info { /* for derived datatypes */
int is_contig;
int n_contig_blocks;
int max_contig_blocks;
int size;
MPI_Aint extent;
int dataloop_size; /* not needed because this info is sent in packet header. remove it after lock/unlock is implemented in the device */
......
......@@ -574,7 +574,7 @@ static int create_derived_datatype(MPID_Request *req, MPID_Datatype **dtp)
new_dtp->cache_id = 0;
new_dtp->name[0] = 0;
new_dtp->is_contig = dtype_info->is_contig;
new_dtp->n_contig_blocks = dtype_info->n_contig_blocks;
new_dtp->max_contig_blocks = dtype_info->max_contig_blocks;
new_dtp->size = dtype_info->size;
new_dtp->extent = dtype_info->extent;
new_dtp->dataloop_size = dtype_info->dataloop_size;
......@@ -681,7 +681,7 @@ static int do_accumulate_op(MPID_Request *rreq)
last = SEGMENT_IGNORE_LAST;
MPID_Datatype_get_ptr(rreq->dev.datatype, dtp);
vec_len = dtp->n_contig_blocks * rreq->dev.user_count + 1;
vec_len = dtp->max_contig_blocks * rreq->dev.user_count + 1;
/* +1 needed because Rob says so */
dloop_vec = (DLOOP_VECTOR *)
MPIU_Malloc(vec_len * sizeof(DLOOP_VECTOR));
......
......@@ -517,7 +517,7 @@ int MPIDI_Accumulate(void *origin_addr, int origin_count, MPI_Datatype
last = SEGMENT_IGNORE_LAST;
MPID_Datatype_get_ptr(target_datatype, dtp);
vec_len = dtp->n_contig_blocks * target_count + 1;
vec_len = dtp->max_contig_blocks * target_count + 1;
/* +1 needed because Rob says so */
MPIU_CHKLMEM_MALLOC(dloop_vec, DLOOP_VECTOR *,
vec_len * sizeof(DLOOP_VECTOR),
......
......@@ -507,7 +507,7 @@ static int MPIDI_CH3I_Send_rma_msg(MPIDI_RMA_ops *rma_op, MPID_Win *win_ptr,
{
/* derived datatype on target. fill derived datatype info */
dtype_info->is_contig = target_dtp->is_contig;
dtype_info->n_contig_blocks = target_dtp->n_contig_blocks;
dtype_info->max_contig_blocks = target_dtp->max_contig_blocks;
dtype_info->size = target_dtp->size;
dtype_info->extent = target_dtp->extent;
dtype_info->dataloop_size = target_dtp->dataloop_size;
......@@ -731,7 +731,7 @@ static int MPIDI_CH3I_Recv_rma_msg(MPIDI_RMA_ops *rma_op, MPID_Win *win_ptr,
MPID_Datatype_get_ptr(rma_op->target_datatype, dtp);
dtype_info->is_contig = dtp->is_contig;
dtype_info->n_contig_blocks = dtp->n_contig_blocks;
dtype_info->max_contig_blocks = dtp->max_contig_blocks;
dtype_info->size = dtp->size;
dtype_info->extent = dtp->extent;
dtype_info->dataloop_size = dtp->dataloop_size;
......
......@@ -381,7 +381,11 @@ typedef struct MPID_Datatype {
* contiguous.
*/
int is_contig;
int n_contig_blocks; /* # of contig blocks in one instance */
/* Upper bound on the number of contig blocks for one instance.
* It is not trivial to calculate the *real* number of contig
* blocks in the case where old datatype is non-contiguous
*/
int max_contig_blocks;
/* pointer to contents and envelope data for the datatype */
MPID_Datatype_contents *contents;
......
......@@ -100,7 +100,7 @@ int MPID_Type_blockindexed(int count,
new_dtp->element_size = el_sz;
new_dtp->eltype = el_type;
new_dtp->n_contig_blocks = count;
new_dtp->max_contig_blocks = count;
}
else
{
......@@ -129,7 +129,7 @@ int MPID_Type_blockindexed(int count,
new_dtp->element_size = el_sz;
new_dtp->eltype = el_type;
new_dtp->n_contig_blocks = count * old_dtp->n_contig_blocks;
new_dtp->max_contig_blocks = old_dtp->max_contig_blocks * count * blocklength;
}
/* priming for loop */
......@@ -172,18 +172,20 @@ int MPID_Type_blockindexed(int count,
* its size and extent are the same, and the old type was also
* contiguous.
*/
if (old_is_contig && ((MPI_Aint) new_dtp->size == new_dtp->extent))
new_dtp->is_contig = 0;
if (old_is_contig)
{
contig_count = MPID_Type_blockindexed_count_contig(count,
blocklength,
displacement_array,
dispinbytes,
old_extent);
new_dtp->is_contig = (contig_count == 1) ? 1 : 0;
}
else
{
new_dtp->is_contig = 0;
new_dtp->max_contig_blocks = contig_count;
if( (contig_count == 1) &&
((MPI_Aint) new_dtp->size == new_dtp->extent) )
{
new_dtp->is_contig = 1;
}
}
*newtype = new_dtp->handle;
......
......@@ -87,7 +87,7 @@ int MPID_Type_commit(MPI_Datatype *datatype_p)
#endif
MPIU_DBG_PRINTF(("# contig blocks = %d\n",
(int) datatype_ptr->n_contig_blocks));
(int) datatype_ptr->max_contig_blocks));
#if 0
MPIDI_Dataloop_dot_printf(datatype_ptr->dataloop, 0, 1);
......
......@@ -86,6 +86,7 @@ int MPID_Type_contiguous(int count,
new_dtp->element_size = el_sz;
new_dtp->eltype = el_type;
new_dtp->is_contig = 1;
new_dtp->max_contig_blocks = 1;
}
else
......@@ -121,6 +122,10 @@ int MPID_Type_contiguous(int count,
new_dtp->eltype = el_type;
new_dtp->is_contig = old_dtp->is_contig;
if(old_dtp->is_contig)
new_dtp->max_contig_blocks = 1;
else
new_dtp->max_contig_blocks = count * old_dtp->max_contig_blocks;
}
*newtype = new_dtp->handle;
......
......@@ -167,7 +167,7 @@ int MPID_Type_create_pairtype(MPI_Datatype type,
}
new_dtp->is_contig = (((MPI_Aint) type_size) == type_extent) ? 1 : 0;
new_dtp->n_contig_blocks = (((MPI_Aint) type_size) == type_extent) ? 1 : 2;
new_dtp->max_contig_blocks = (((MPI_Aint) type_size) == type_extent) ? 1 : 2;
/* fill in dataloops -- only case where we precreate dataloops
*
......
......@@ -108,7 +108,7 @@ int MPID_Type_indexed(int count,
new_dtp->element_size = (MPI_Aint) el_sz;
new_dtp->eltype = el_type;
new_dtp->n_contig_blocks = count;
new_dtp->max_contig_blocks = count;
}
else
{
......@@ -137,7 +137,11 @@ int MPID_Type_indexed(int count,
new_dtp->element_size = (MPI_Aint) el_sz;
new_dtp->eltype = el_type;
new_dtp->n_contig_blocks = old_dtp->n_contig_blocks * count;
new_dtp->max_contig_blocks = 0;
for(i=0; i<count; i++)
new_dtp->max_contig_blocks
+= old_dtp->max_contig_blocks
* ((MPI_Aint *)blocklength_array)[i];
}
/* find the first nonzero blocklength element */
......@@ -203,19 +207,20 @@ int MPID_Type_indexed(int count,
* block, its size and extent are the same, and the old type
* was also contiguous.
*/
contig_count = MPID_Type_indexed_count_contig(count,
new_dtp->is_contig = 0;
if(old_is_contig)
{
contig_count = MPID_Type_indexed_count_contig(count,
blocklength_array,
displacement_array,
dispinbytes,
old_extent);
if ((contig_count == 1) && ((MPI_Aint) new_dtp->size == new_dtp->extent))
{
new_dtp->is_contig = old_is_contig;
}
else
{
new_dtp->is_contig = 0;
new_dtp->max_contig_blocks = contig_count;
if( (contig_count == 1) &&
((MPI_Aint) new_dtp->size == new_dtp->extent))
{
new_dtp->is_contig = 1;
}
}
*newtype = new_dtp->handle;
......
......@@ -209,7 +209,7 @@ int MPID_Type_struct(int count,
return MPID_Type_zerolen(newtype);
}
new_dtp->n_contig_blocks = 0;
new_dtp->max_contig_blocks = 0;
for (i=0; i < count; i++)
{
int is_builtin =
......@@ -241,7 +241,7 @@ int MPID_Type_struct(int count,
size += tmp_el_sz * blocklength_array[i];
new_dtp->n_contig_blocks++;
new_dtp->max_contig_blocks++;
}
else
{
......@@ -265,7 +265,7 @@ int MPID_Type_struct(int count,
size += old_dtp->size * blocklength_array[i];
new_dtp->n_contig_blocks += old_dtp->n_contig_blocks;
new_dtp->max_contig_blocks += old_dtp->max_contig_blocks;
}
/* element size and type */
......
......@@ -97,7 +97,7 @@ int MPID_Type_vector(int count,
new_dtp->element_size = el_sz;
new_dtp->eltype = el_type;
new_dtp->n_contig_blocks = count;
new_dtp->max_contig_blocks = count;
eff_stride = (strideinbytes) ? stride : (stride * el_sz);
}
......@@ -125,7 +125,7 @@ int MPID_Type_vector(int count,
new_dtp->element_size = el_sz;
new_dtp->eltype = el_type;
new_dtp->n_contig_blocks = old_dtp->n_contig_blocks * count;
new_dtp->max_contig_blocks = old_dtp->max_contig_blocks * count * blocklength;
eff_stride = (strideinbytes) ? stride : (stride * old_dtp->extent);
}
......@@ -151,6 +151,7 @@ int MPID_Type_vector(int count,
old_is_contig)
{
new_dtp->is_contig = 1;
new_dtp->max_contig_blocks = 1;
}
else {
new_dtp->is_contig = 0;
......
......@@ -41,7 +41,7 @@ int MPIR_Type_flatten(MPI_Datatype type,
MPID_Datatype_get_ptr(type, datatype_ptr);
MPIU_Assert(datatype_ptr->is_committed);
MPIU_Assert(*array_len_p >= datatype_ptr->n_contig_blocks);
MPIU_Assert(*array_len_p >= datatype_ptr->max_contig_blocks);
segp = MPID_Segment_alloc();
MPID_Segment_init(0, 1, type, segp, 0); /* first 0 is bufptr,
......
......@@ -36,6 +36,6 @@ int MPIR_Type_get_contig_blocks(MPI_Datatype type,
MPID_Datatype_get_ptr(type, datatype_ptr);
MPIU_Assert(datatype_ptr->is_committed);
*nr_blocks_p = datatype_ptr->n_contig_blocks;
*nr_blocks_p = datatype_ptr->max_contig_blocks;
return 0;
}
......@@ -92,7 +92,7 @@ void make_dt_map_vec(MPI_Datatype dt, mpid_dt_info *dti) {
/* Use existing routines to get IOV */
MPID_Datatype_get_ptr(dt, dtp);
nb = dtp->n_contig_blocks + 1;
nb = dtp->max_contig_blocks + 1;
MPIDU_MALLOC(mv, MPID_Type_map, nb * sizeof(*mv), last, "MPID_Type_map");
MPID_assert(mv != NULL);
......
......@@ -47,6 +47,8 @@ fetchandadd_am_SOURCES = fetchandadd_am.c
fetchandadd_tree_am_SOURCES = fetchandadd_tree_am.c
accfence2_am_SOURCES = accfence2_am.c
test1_dt_SOURCES = test1_dt.c
attrorderwin_SOURCES = attrorderwin.c
wincall_SOURCES = wincall.c
fkeyvalwin_SOURCES = fkeyvalwin.c
......
/* -*- Mode: C; c-basic-offset:4 ; -*- */
/*
* (C) 2001 by Argonne National Laboratory.
* See COPYRIGHT in top-level directory.
*/
#include "mpi.h"
#include "stdio.h"
#include "mpitest.h"
/* tests a series of puts, gets, and accumulate on 2 processes using fence */
/* Same as test1.c but uses derived datatypes to receive data */
#define SIZE 100
int main(int argc, char *argv[])
{
int rank, nprocs, A[SIZE], B[SIZE], i;
MPI_Win win;
MPI_Datatype contig_2ints;
int errs = 0;
MTest_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD,&nprocs);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
if (nprocs != 2) {
printf("Run this program with 2 processes\n");
MPI_Abort(MPI_COMM_WORLD,1);
}
if (rank == 0) {
for (i=0; i<SIZE; i++)
A[i] = B[i] = i;
}
else {
for (i=0; i<SIZE; i++) {
A[i] = (-3)*i;
B[i] = (-4)*i;
}
}
MPI_Type_contiguous(2, MPI_INT, &contig_2ints);
MPI_Type_commit(&contig_2ints);
MPI_Win_create(B, SIZE*sizeof(int), sizeof(int), MPI_INFO_NULL,
MPI_COMM_WORLD, &win);
MPI_Win_fence(0, win);
if (rank == 0) {
for (i=0; i<SIZE-1; i++)
MPI_Put(A+i, 2, MPI_INT, 1, i, 1, contig_2ints, win);
}
else {
for (i=0; i<SIZE-1; i++)
MPI_Get(A+i, 2, MPI_INT, 0, i, 1, contig_2ints, win);
MPI_Accumulate(A+i, 2, MPI_INT, 0, i, 1, contig_2ints, MPI_SUM, win);
}
MPI_Win_fence(0, win);
if (rank == 1) {
for (i=0; i<SIZE-1; i++) {
if (A[i] != B[i]) {
printf("Put/Get Error: A[i]=%d, B[i]=%d\n", A[i], B[i]);
errs++;
}
}
}
else {
if (B[SIZE-1] != SIZE - 1 - 3*(SIZE-1)) {
printf("Accumulate Error: B[SIZE-1] is %d, should be %d\n", B[SIZE-1], SIZE - 1 - 3*(SIZE-1));
errs++;
}
}
MPI_Win_free(&win);
MPI_Type_free(&contig_2ints);
MTest_Finalize(errs);
MPI_Finalize();
return 0;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment