MPIR_Copy_data(src_addr, src_count, src_datatype, dest_buff_addr, dest_count, dest_datatype) { if (MPIR_Datatype_iscontig(src_count, src_datatype) && MPIR_Datatype_iscontig(dest_count, dest_datatype)) { /* * If the data arrangement is contiguous at both the src and dest * buffers, then we can simply copy the raw bytes from the src buffer * to the dest buffer. Remember the type signatures have to match, so * this is a safe operation. * * NOTE: This code assumes that the (dest_count, dest_datatype) * represents enough space to accomodate (src_count, src_datatype) and * that enough space exists in the dest buffer to cover (dest_count, * dest_datatype). This implies that truncation and buffer overruns * errors must be caught before this routine is called. * * Q: Does a datatype be denoted as "contiguous" imply that the extent * and the true extent (size) are the same? In other words, can a * contiguous datatype have padding? If it can, then we can't use a * straight memory copy because we will be copying unwanted bytes. * * For the simple case where neither the src nor the dest datatypes * contain any padding a simple memory copy with work. If padding * exists in either datatype, we need a loop and extra logic to ensure * that we don't touch the padded areas. This is true even if they are * the two datatypes are the same. We simply don't know if the padding * represents a skip over unused memory resulting from alignment * problems, or if it is being used to skip over locations containing * data we don't need for this operation. If the latter is true, then * a straight memory copy would wipe out live data. */ } else if (MPIR_Datatype_iscontig(src_count, src_datatype)) { /* * The data arrangment at the src buffer is contiguous, but not at the * dest. We should be able to "unpack" the data directly into the dest * buffer. */ } else if (MPIR_Datatype_iscontig(dest_count, dest_datatype)) { /* * The data arrangment at the dest buffer is contiguous, but not at the * src. We should be able to "pack" the data directly into the dest * buffer. */ } else { /* * The data arrangement at both the src and dest buffers is * non-contiguous. Theoretically, we should be able to manage the two * dataloops and copy the data without an intermediate buffer. I need * to talk to Rob/Bill about this. */ } rc = MPI_SUCCESS; } /* MPIR_Copy_data() */ MPIR_Win_verify_dt_compat(src_count, src_datatype, dest_count, dest_datatype) { /* * Verify that the datatypes are compatible for the copy from the src * buffer to the dest buffer. This includes checking for truncation. */ if (src_datatype != dest_datatype && src_datatype != MPI_PACKED && src_datatype != MPI_PACKED) { /* * If the datatypes are not the same basic type and neither is * MPI_PACKED, so they are incompatible. */ rc = MPI_ERR_XXX; } /* * Since one of the datatypes can be MPI_PACKED, we have to compare the * byte counts in order to detect truncation. */ if (dest_count * dest_datatype.size < src_count * src_datatype.size) { /* * NOTE: The standard does not define what the application should * expect when truncation occurs. We could copy as much data as * possible before rc =ing an error, but that would only delay * reporting the error to the application. Besides, a portable * application cannot rely on any of the data being placed into dest * buffer, so it seems pointless to perform a partial copy. */ rc = MPI_ERR_TRUNCATE; } rc = MPI_SUCCESS; } MPIR_Win_verify_dt_op_compat(src_count, src_datatype, dest_count, dest_datatype, op) { /* * The standard requires that datatypes contain one and only one basic type * and that this basic type be the same for both datatypes. See section * 6.3.4, page 120, line 6 for details. * * NOTE: Since we are presently assuming all datatypes are basic, this * check is easy. */ if (src_datatype != dest_datatype) { rc = MPI_ERR_XXX; } /* * Verify that the datatypes are compatible with the specified operation. * See section 4.9.2, "Predefined reduce operations", of the MPI-1.1 * standard for details. */ if (MPIR_Op_dt_compat(op, src_datatype)) { rc = MPI_ERR_XXX; } /* * Verify that truncation will not occur */ if (dest_count < src_count) { /* * NOTE: The standard does not define what the application should * expect when truncation occurs. We could peform the operation on as * much data as possible before rc =ing an error, but that would only * delay reporting the error to the application. Besides, a portable * application cannot rely on any of the operations being completed, so * it seems pointless to perform a partial accumulate. */ rc = MPI_ERR_TRUNCATE; } rc = MPI_SUCCESS; } MPIR_Win_verify_buffer(count, datatype, rank, disp, dwin) { win_size = ((dwin->flags & MPID_WIN_CONST_SIZE) ? dwin->size : dwin->sizes[target_size]); win_displ = ((dwin->flags & MPID_WIN_CONST_DISPL) ? dwin->displs : dwin->displs[target_size]); /* * Verify that the target buffer is contained within the target's local * window. */ byte_count = count * datatype.size; offset = win_displ * disp; if (offset >= win_size) { rc = MPI_ERR_DISP; } if (offset + byte_count > win_size) { rc = MPI_ERR_XXX; } rc = MPI_SUCCESS; } MPIR_Win_compute_addr(dwin, rank, disp) { win_base = ((dwin->flags & MPID_WIN_CONST_BASE) ? dwin->base : dwin->sizes[target_base]); win_displ = ((dwin->flags & MPID_WIN_CONST_DISPL) ? dwin->displs : dwin->displs[target_size]); return (win_base + win_displ * disp); }