Mainly useful for MPI_IN_PLACE collectives.
/* C++ declarations for shared_malloc */
#ifdef __cplusplus
/* C++ declarations for shared_malloc */
#ifdef __cplusplus
-XBT_PUBLIC int smpi_is_shared(void* ptr, std::vector<std::pair<size_t, size_t>>& private_blocks, size_t* offset);
+XBT_PUBLIC int smpi_is_shared(const void* ptr, std::vector<std::pair<size_t, size_t>>& private_blocks, size_t* offset);
std::vector<std::pair<size_t, size_t>> shift_and_frame_private_blocks(const std::vector<std::pair<size_t, size_t>>& vec,
size_t offset, size_t buff_size);
std::vector<std::pair<size_t, size_t>> shift_and_frame_private_blocks(const std::vector<std::pair<size_t, size_t>>& vec,
size_t offset, size_t buff_size);
+ static const void* smpi_get_in_place_buf(const void* inplacebuf, const void* otherbuf,std::unique_ptr<unsigned char[]>& tmp_sendbuf, int count, MPI_Datatype datatype){
+ if (inplacebuf == MPI_IN_PLACE) {
+ tmp_sendbuf.reset(new unsigned char[count * datatype->get_extent()]);
+ simgrid::smpi::Datatype::copy(otherbuf, count, datatype, tmp_sendbuf.get(), count, datatype);
+ return tmp_sendbuf.get();
+ }else{
+ return inplacebuf;
+ }
+}
/* PMPI User level calls */
int PMPI_Barrier(MPI_Comm comm)
/* PMPI User level calls */
int PMPI_Barrier(MPI_Comm comm)
"Iscatterv: the recvtype cannot be NULL when not receiving in place");
CHECK_ARGS(request == nullptr, MPI_ERR_ARG, "Iscatterv: param 10 request cannot be NULL");
CHECK_ARGS(recvbuf != MPI_IN_PLACE && recvcount < 0, MPI_ERR_COUNT,
"Iscatterv: the recvtype cannot be NULL when not receiving in place");
CHECK_ARGS(request == nullptr, MPI_ERR_ARG, "Iscatterv: param 10 request cannot be NULL");
CHECK_ARGS(recvbuf != MPI_IN_PLACE && recvcount < 0, MPI_ERR_COUNT,
- "Iscatterv: When not receiving in place, the recvcound cannot be negative");
+ "Iscatterv: When not receiving in place, the recvcount cannot be negative");
CHECK_ARGS(root < 0, MPI_ERR_ROOT, "Iscatterv: root cannot be negative");
CHECK_ARGS(root >= comm->size(), MPI_ERR_ROOT, "Iscatterv: root (=%d) is larger than communicator size (=%d)", root,
comm->size());
CHECK_ARGS(root < 0, MPI_ERR_ROOT, "Iscatterv: root cannot be negative");
CHECK_ARGS(root >= comm->size(), MPI_ERR_ROOT, "Iscatterv: root (=%d) is larger than communicator size (=%d)", root,
comm->size());
return MPI_ERR_ARG;
smpi_bench_end();
return MPI_ERR_ARG;
smpi_bench_end();
- const void* real_sendbuf = sendbuf;
std::unique_ptr<unsigned char[]> tmp_sendbuf;
std::unique_ptr<unsigned char[]> tmp_sendbuf;
- if (sendbuf == MPI_IN_PLACE) {
- tmp_sendbuf.reset(new unsigned char[count * datatype->get_extent()]);
- simgrid::smpi::Datatype::copy(recvbuf, count, datatype, tmp_sendbuf.get(), count, datatype);
- real_sendbuf = tmp_sendbuf.get();
- }
+ const void* real_sendbuf = smpi_get_in_place_buf(sendbuf, recvbuf, tmp_sendbuf, count, datatype);
+
int rank = simgrid::s4u::this_actor::get_pid();
TRACE_smpi_comm_in(rank, request == MPI_REQUEST_IGNORED ? "PMPI_Allreduce" : "PMPI_Iallreduce",
int rank = simgrid::s4u::this_actor::get_pid();
TRACE_smpi_comm_in(rank, request == MPI_REQUEST_IGNORED ? "PMPI_Allreduce" : "PMPI_Iallreduce",
smpi_bench_end();
int rank = simgrid::s4u::this_actor::get_pid();
smpi_bench_end();
int rank = simgrid::s4u::this_actor::get_pid();
- const void* real_sendbuf = sendbuf;
std::unique_ptr<unsigned char[]> tmp_sendbuf;
std::unique_ptr<unsigned char[]> tmp_sendbuf;
- if (sendbuf == MPI_IN_PLACE) {
- tmp_sendbuf.reset(new unsigned char[count * datatype->size()]);
- real_sendbuf = memcpy(tmp_sendbuf.get(), recvbuf, count * datatype->size());
- }
+ const void* real_sendbuf = smpi_get_in_place_buf(sendbuf, recvbuf, tmp_sendbuf, count, datatype);;
+
TRACE_smpi_comm_in(rank, request == MPI_REQUEST_IGNORED ? "PMPI_Scan" : "PMPI_Iscan",
new simgrid::instr::Pt2PtTIData(request == MPI_REQUEST_IGNORED ? "scan" : "iscan", -1,
datatype->is_replayable() ? count : count * datatype->size(),
TRACE_smpi_comm_in(rank, request == MPI_REQUEST_IGNORED ? "PMPI_Scan" : "PMPI_Iscan",
new simgrid::instr::Pt2PtTIData(request == MPI_REQUEST_IGNORED ? "scan" : "iscan", -1,
datatype->is_replayable() ? count : count * datatype->size(),
smpi_bench_end();
int rank = simgrid::s4u::this_actor::get_pid();
smpi_bench_end();
int rank = simgrid::s4u::this_actor::get_pid();
- const void* real_sendbuf = sendbuf;
std::unique_ptr<unsigned char[]> tmp_sendbuf;
std::unique_ptr<unsigned char[]> tmp_sendbuf;
- if (sendbuf == MPI_IN_PLACE) {
- tmp_sendbuf.reset(new unsigned char[count * datatype->size()]);
- real_sendbuf = memcpy(tmp_sendbuf.get(), recvbuf, count * datatype->size());
- }
+ const void* real_sendbuf = smpi_get_in_place_buf(sendbuf, recvbuf, tmp_sendbuf, count, datatype);;
TRACE_smpi_comm_in(rank, request == MPI_REQUEST_IGNORED ? "PMPI_Exscan" : "PMPI_Iexscan",
new simgrid::instr::Pt2PtTIData(request == MPI_REQUEST_IGNORED ? "exscan" : "iexscan", -1,
TRACE_smpi_comm_in(rank, request == MPI_REQUEST_IGNORED ? "PMPI_Exscan" : "PMPI_Iexscan",
new simgrid::instr::Pt2PtTIData(request == MPI_REQUEST_IGNORED ? "exscan" : "iexscan", -1,
trace_recvcounts->push_back(recvcounts[i] * dt_send_size);
totalcount += recvcounts[i];
}
trace_recvcounts->push_back(recvcounts[i] * dt_send_size);
totalcount += recvcounts[i];
}
-
- const void* real_sendbuf = sendbuf;
std::unique_ptr<unsigned char[]> tmp_sendbuf;
std::unique_ptr<unsigned char[]> tmp_sendbuf;
- if (sendbuf == MPI_IN_PLACE) {
- tmp_sendbuf.reset(new unsigned char[totalcount * datatype->size()]);
- real_sendbuf = memcpy(tmp_sendbuf.get(), recvbuf, totalcount * datatype->size());
- }
+ const void* real_sendbuf = smpi_get_in_place_buf(sendbuf, recvbuf, tmp_sendbuf, totalcount, datatype);;
TRACE_smpi_comm_in(rank, request == MPI_REQUEST_IGNORED ? "PMPI_Reduce_scatter" : "PMPI_Ireduce_scatter",
new simgrid::instr::VarCollTIData(
TRACE_smpi_comm_in(rank, request == MPI_REQUEST_IGNORED ? "PMPI_Reduce_scatter" : "PMPI_Ireduce_scatter",
new simgrid::instr::VarCollTIData(
int rank = simgrid::s4u::this_actor::get_pid();
int dt_send_size = datatype->is_replayable() ? 1 : datatype->size();
std::vector<int>* trace_recvcounts = new std::vector<int>(recvcount * dt_send_size); // copy data to avoid bad free
int rank = simgrid::s4u::this_actor::get_pid();
int dt_send_size = datatype->is_replayable() ? 1 : datatype->size();
std::vector<int>* trace_recvcounts = new std::vector<int>(recvcount * dt_send_size); // copy data to avoid bad free
-
- const void* real_sendbuf = sendbuf;
std::unique_ptr<unsigned char[]> tmp_sendbuf;
std::unique_ptr<unsigned char[]> tmp_sendbuf;
- if (sendbuf == MPI_IN_PLACE) {
- tmp_sendbuf.reset(new unsigned char[recvcount * count * datatype->size()]);
- real_sendbuf = memcpy(tmp_sendbuf.get(), recvbuf, recvcount * count * datatype->size());
- }
+ const void* real_sendbuf = smpi_get_in_place_buf(sendbuf, recvbuf, tmp_sendbuf, recvcount * count, datatype);
TRACE_smpi_comm_in(
rank, request == MPI_REQUEST_IGNORED ? "PMPI_Reduce_scatter_block" : "PMPI_Ireduce_scatter_block",
TRACE_smpi_comm_in(
rank, request == MPI_REQUEST_IGNORED ? "PMPI_Reduce_scatter_block" : "PMPI_Ireduce_scatter_block",
smpi_bench_end();
int rank = simgrid::s4u::this_actor::get_pid();
smpi_bench_end();
int rank = simgrid::s4u::this_actor::get_pid();
- const void* real_sendbuf = sendbuf;
int real_sendcount = sendcount;
MPI_Datatype real_sendtype = sendtype;
int real_sendcount = sendcount;
MPI_Datatype real_sendtype = sendtype;
std::unique_ptr<unsigned char[]> tmp_sendbuf;
std::unique_ptr<unsigned char[]> tmp_sendbuf;
+ const void* real_sendbuf = smpi_get_in_place_buf(sendbuf, recvbuf, tmp_sendbuf, recvcount * comm->size(), recvtype);
+
if (sendbuf == MPI_IN_PLACE) {
if (sendbuf == MPI_IN_PLACE) {
- tmp_sendbuf.reset(new unsigned char[recvcount * comm->size() * recvtype->size()]);
- // memcpy(??,nullptr,0) is actually undefined behavior, even if harmless.
- if (recvbuf != nullptr)
- memcpy(tmp_sendbuf.get(), recvbuf, recvcount * comm->size() * recvtype->size());
- real_sendbuf = tmp_sendbuf.get();
real_sendcount = recvcount;
real_sendtype = recvtype;
}
real_sendcount = recvcount;
real_sendtype = recvtype;
}
std::vector<int>* trace_recvcounts = new std::vector<int>;
int dt_size_recv = recvtype->size();
std::vector<int>* trace_recvcounts = new std::vector<int>;
int dt_size_recv = recvtype->size();
- const void* real_sendbuf = sendbuf;
const int* real_sendcounts = sendcounts;
const int* real_senddisps = senddisps;
MPI_Datatype real_sendtype = sendtype;
const int* real_sendcounts = sendcounts;
const int* real_senddisps = senddisps;
MPI_Datatype real_sendtype = sendtype;
std::unique_ptr<unsigned char[]> tmp_sendbuf;
std::unique_ptr<int[]> tmp_sendcounts;
std::unique_ptr<int[]> tmp_senddisps;
std::unique_ptr<unsigned char[]> tmp_sendbuf;
std::unique_ptr<int[]> tmp_sendcounts;
std::unique_ptr<int[]> tmp_senddisps;
+ const void* real_sendbuf = smpi_get_in_place_buf(sendbuf, recvbuf, tmp_sendbuf, maxsize, MPI_CHAR);
if (sendbuf == MPI_IN_PLACE) {
if (sendbuf == MPI_IN_PLACE) {
- tmp_sendbuf.reset(new unsigned char[maxsize]);
- real_sendbuf = memcpy(tmp_sendbuf.get(), recvbuf, maxsize);
tmp_sendcounts.reset(new int[size]);
std::copy(recvcounts, recvcounts + size, tmp_sendcounts.get());
real_sendcounts = tmp_sendcounts.get();
tmp_sendcounts.reset(new int[size]);
std::copy(recvcounts, recvcounts + size, tmp_sendcounts.get());
real_sendcounts = tmp_sendcounts.get();
std::vector<int>* trace_sendcounts = new std::vector<int>;
std::vector<int>* trace_recvcounts = new std::vector<int>;
std::vector<int>* trace_sendcounts = new std::vector<int>;
std::vector<int>* trace_recvcounts = new std::vector<int>;
- const void* real_sendbuf = sendbuf;
const int* real_sendcounts = sendcounts;
const int* real_senddisps = senddisps;
const MPI_Datatype* real_sendtypes = sendtypes;
const int* real_sendcounts = sendcounts;
const int* real_senddisps = senddisps;
const MPI_Datatype* real_sendtypes = sendtypes;
std::unique_ptr<int[]> tmp_sendcounts;
std::unique_ptr<int[]> tmp_senddisps;
std::unique_ptr<MPI_Datatype[]> tmp_sendtypes;
std::unique_ptr<int[]> tmp_sendcounts;
std::unique_ptr<int[]> tmp_senddisps;
std::unique_ptr<MPI_Datatype[]> tmp_sendtypes;
+ const void* real_sendbuf = smpi_get_in_place_buf(sendbuf, recvbuf, tmp_sendbuf, maxsize, MPI_CHAR);
if (sendbuf == MPI_IN_PLACE) {
if (sendbuf == MPI_IN_PLACE) {
- tmp_sendbuf.reset(new unsigned char[maxsize]);
- real_sendbuf = memcpy(tmp_sendbuf.get(), recvbuf, maxsize);
tmp_sendcounts.reset(new int[size]);
std::copy(recvcounts, recvcounts + size, tmp_sendcounts.get());
real_sendcounts = tmp_sendcounts.get();
tmp_sendcounts.reset(new int[size]);
std::copy(recvcounts, recvcounts + size, tmp_sendcounts.get());
real_sendcounts = tmp_sendcounts.get();
shared_data_key_type* data;
};
shared_data_key_type* data;
};
-std::map<void*, shared_metadata_t> allocs_metadata;
+std::map<const void*, shared_metadata_t> allocs_metadata;
std::map<std::string, void*> calls;
#ifndef WIN32
std::map<std::string, void*> calls;
#ifndef WIN32
return ::operator new(size);
}
return ::operator new(size);
}
-int smpi_is_shared(void* ptr, std::vector<std::pair<size_t, size_t>> &private_blocks, size_t *offset){
+int smpi_is_shared(const void* ptr, std::vector<std::pair<size_t, size_t>> &private_blocks, size_t *offset){
private_blocks.clear(); // being paranoid
if (allocs_metadata.empty())
return 0;
private_blocks.clear(); // being paranoid
if (allocs_metadata.empty())
return 0;
smpi_switch_data_segment(simgrid::s4u::Actor::self());
}
/* First check if we really have something to do */
smpi_switch_data_segment(simgrid::s4u::Actor::self());
}
/* First check if we really have something to do */
+ size_t offset = 0;
+ std::vector<std::pair<size_t, size_t>> private_blocks;
+ if(smpi_is_shared(sendbuf,private_blocks,&offset)
+ && (private_blocks.size()==1
+ && (private_blocks[0].second - private_blocks[0].first)==(unsigned long)(sendcount * sendtype->get_extent()))){
+ return 0;
+ }
+ if(smpi_is_shared(recvbuf,private_blocks,&offset)
+ && (private_blocks.size()==1
+ && (private_blocks[0].second - private_blocks[0].first)==(unsigned long)(recvcount * recvtype->get_extent()))){
+ return 0;
+ }
+
if (recvcount > 0 && recvbuf != sendbuf) {
sendcount *= sendtype->size();
recvcount *= recvtype->size();
if (recvcount > 0 && recvbuf != sendbuf) {
sendcount *= sendtype->size();
recvcount *= recvtype->size();