|
Packit Service |
c5cf8c |
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
|
|
Packit Service |
c5cf8c |
/*
|
|
Packit Service |
c5cf8c |
* (C) 2018 by Argonne National Laboratory.
|
|
Packit Service |
c5cf8c |
* See COPYRIGHT in top-level directory.
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* Portions of this code were written by Intel Corporation.
|
|
Packit Service |
c5cf8c |
* Copyright (C) 2011-2018 Intel Corporation. Intel provides this material
|
|
Packit Service |
c5cf8c |
* to Argonne National Laboratory subject to Software Grant and Corporate
|
|
Packit Service |
c5cf8c |
* Contributor License Agreement dated February 8, 2012.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#include "mpiimpl.h"
|
|
Packit Service |
c5cf8c |
#include "datatype.h"
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#define COPY_BUFFER_SZ 16384
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#undef FUNCNAME
|
|
Packit Service |
c5cf8c |
#define FUNCNAME MPIR_Localcopy
|
|
Packit Service |
c5cf8c |
#undef FCNAME
|
|
Packit Service |
c5cf8c |
#define FCNAME "MPIR_Localcopy"
|
|
Packit Service |
c5cf8c |
int MPIR_Localcopy(const void *sendbuf, MPI_Aint sendcount, MPI_Datatype sendtype,
|
|
Packit Service |
c5cf8c |
void *recvbuf, MPI_Aint recvcount, MPI_Datatype recvtype)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int mpi_errno = MPI_SUCCESS;
|
|
Packit Service |
c5cf8c |
int sendtype_iscontig, recvtype_iscontig;
|
|
Packit Service |
c5cf8c |
MPI_Aint sendsize, recvsize, sdata_sz, rdata_sz, copy_sz;
|
|
Packit Service |
c5cf8c |
MPI_Aint true_extent, sendtype_true_lb, recvtype_true_lb;
|
|
Packit Service |
c5cf8c |
MPIR_CHKLMEM_DECL(1);
|
|
Packit Service |
c5cf8c |
MPIR_FUNC_TERSE_STATE_DECL(MPID_STATE_MPIR_LOCALCOPY);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPIR_FUNC_TERSE_ENTER(MPID_STATE_MPIR_LOCALCOPY);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPIR_Datatype_get_size_macro(sendtype, sendsize);
|
|
Packit Service |
c5cf8c |
MPIR_Datatype_get_size_macro(recvtype, recvsize);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
sdata_sz = sendsize * sendcount;
|
|
Packit Service |
c5cf8c |
rdata_sz = recvsize * recvcount;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* if there is no data to copy, bail out */
|
|
Packit Service |
c5cf8c |
if (!sdata_sz || !rdata_sz)
|
|
Packit Service |
c5cf8c |
goto fn_exit;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#if defined(HAVE_ERROR_CHECKING)
|
|
Packit Service |
c5cf8c |
if (sdata_sz > rdata_sz) {
|
|
Packit Service |
c5cf8c |
MPIR_ERR_SET2(mpi_errno, MPI_ERR_TRUNCATE, "**truncate", "**truncate %d %d", sdata_sz,
|
|
Packit Service |
c5cf8c |
rdata_sz);
|
|
Packit Service |
c5cf8c |
copy_sz = rdata_sz;
|
|
Packit Service |
c5cf8c |
} else
|
|
Packit Service |
c5cf8c |
#endif /* HAVE_ERROR_CHECKING */
|
|
Packit Service |
c5cf8c |
copy_sz = sdata_sz;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Builtin types is the common case; optimize for it */
|
|
Packit Service |
c5cf8c |
if ((HANDLE_GET_KIND(sendtype) == HANDLE_KIND_BUILTIN) &&
|
|
Packit Service |
c5cf8c |
HANDLE_GET_KIND(recvtype) == HANDLE_KIND_BUILTIN) {
|
|
Packit Service |
c5cf8c |
MPIR_Memcpy(recvbuf, sendbuf, copy_sz);
|
|
Packit Service |
c5cf8c |
goto fn_exit;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPIR_Datatype_iscontig(sendtype, &sendtype_iscontig);
|
|
Packit Service |
c5cf8c |
MPIR_Datatype_iscontig(recvtype, &recvtype_iscontig);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPIR_Type_get_true_extent_impl(sendtype, &sendtype_true_lb, &true_extent);
|
|
Packit Service |
c5cf8c |
MPIR_Type_get_true_extent_impl(recvtype, &recvtype_true_lb, &true_extent);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (sendtype_iscontig && recvtype_iscontig) {
|
|
Packit Service |
c5cf8c |
#if defined(HAVE_ERROR_CHECKING)
|
|
Packit Service |
c5cf8c |
MPIR_ERR_CHKMEMCPYANDJUMP(mpi_errno,
|
|
Packit Service |
c5cf8c |
((char *) recvbuf + recvtype_true_lb),
|
|
Packit Service |
c5cf8c |
((char *) sendbuf + sendtype_true_lb), copy_sz);
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
MPIR_Memcpy(((char *) recvbuf + recvtype_true_lb),
|
|
Packit Service |
c5cf8c |
((char *) sendbuf + sendtype_true_lb), copy_sz);
|
|
Packit Service |
c5cf8c |
} else if (sendtype_iscontig) {
|
|
Packit Service |
c5cf8c |
MPIR_Segment seg;
|
|
Packit Service |
c5cf8c |
MPI_Aint last;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPIR_Segment_init(recvbuf, recvcount, recvtype, &seg;;
|
|
Packit Service |
c5cf8c |
last = copy_sz;
|
|
Packit Service |
c5cf8c |
MPIR_Segment_unpack(&seg, 0, &last, (char *) sendbuf + sendtype_true_lb);
|
|
Packit Service |
c5cf8c |
MPIR_ERR_CHKANDJUMP(last != copy_sz, mpi_errno, MPI_ERR_TYPE, "**dtypemismatch");
|
|
Packit Service |
c5cf8c |
} else if (recvtype_iscontig) {
|
|
Packit Service |
c5cf8c |
MPIR_Segment seg;
|
|
Packit Service |
c5cf8c |
MPI_Aint last;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPIR_Segment_init(sendbuf, sendcount, sendtype, &seg;;
|
|
Packit Service |
c5cf8c |
last = copy_sz;
|
|
Packit Service |
c5cf8c |
MPIR_Segment_pack(&seg, 0, &last, (char *) recvbuf + recvtype_true_lb);
|
|
Packit Service |
c5cf8c |
MPIR_ERR_CHKANDJUMP(last != copy_sz, mpi_errno, MPI_ERR_TYPE, "**dtypemismatch");
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
char *buf;
|
|
Packit Service |
c5cf8c |
intptr_t buf_off;
|
|
Packit Service |
c5cf8c |
MPIR_Segment sseg;
|
|
Packit Service |
c5cf8c |
intptr_t sfirst;
|
|
Packit Service |
c5cf8c |
MPIR_Segment rseg;
|
|
Packit Service |
c5cf8c |
intptr_t rfirst;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPIR_CHKLMEM_MALLOC(buf, char *, COPY_BUFFER_SZ, mpi_errno, "buf", MPL_MEM_BUFFER);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPIR_Segment_init(sendbuf, sendcount, sendtype, &sseg;;
|
|
Packit Service |
c5cf8c |
MPIR_Segment_init(recvbuf, recvcount, recvtype, &rseg);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
sfirst = 0;
|
|
Packit Service |
c5cf8c |
rfirst = 0;
|
|
Packit Service |
c5cf8c |
buf_off = 0;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
while (1) {
|
|
Packit Service |
c5cf8c |
MPI_Aint last;
|
|
Packit Service |
c5cf8c |
char *buf_end;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (copy_sz - sfirst > COPY_BUFFER_SZ - buf_off) {
|
|
Packit Service |
c5cf8c |
last = sfirst + (COPY_BUFFER_SZ - buf_off);
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
last = copy_sz;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPIR_Segment_pack(&sseg, sfirst, &last, buf + buf_off);
|
|
Packit Service |
c5cf8c |
MPIR_Assert(last > sfirst);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
buf_end = buf + buf_off + (last - sfirst);
|
|
Packit Service |
c5cf8c |
sfirst = last;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPIR_Segment_unpack(&rseg, rfirst, &last, buf);
|
|
Packit Service |
c5cf8c |
MPIR_Assert(last > rfirst);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
rfirst = last;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (rfirst == copy_sz) {
|
|
Packit Service |
c5cf8c |
/* successful completion */
|
|
Packit Service |
c5cf8c |
break;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* if the send side finished, but the recv side couldn't unpack it, there's a datatype mismatch */
|
|
Packit Service |
c5cf8c |
MPIR_ERR_CHKANDJUMP(sfirst == copy_sz, mpi_errno, MPI_ERR_TYPE, "**dtypemismatch");
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* if not all data was unpacked, copy it to the front of the buffer for next time */
|
|
Packit Service |
c5cf8c |
buf_off = sfirst - rfirst;
|
|
Packit Service |
c5cf8c |
if (buf_off > 0) {
|
|
Packit Service |
c5cf8c |
memmove(buf, buf_end - buf_off, buf_off);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
fn_exit:
|
|
Packit Service |
c5cf8c |
MPIR_CHKLMEM_FREEALL();
|
|
Packit Service |
c5cf8c |
MPIR_FUNC_TERSE_EXIT(MPID_STATE_MPIR_LOCALCOPY);
|
|
Packit Service |
c5cf8c |
return mpi_errno;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
fn_fail:
|
|
Packit Service |
c5cf8c |
goto fn_exit;
|
|
Packit Service |
c5cf8c |
}
|