/* smpi_datatype.cpp -- MPI primitives to handle datatypes */
-/* Copyright (c) 2009-2018. The SimGrid Team. All rights reserved. */
+/* Copyright (c) 2009-2019. The SimGrid Team. All rights reserved. */
/* This program is free software; you can redistribute it and/or modify it
* under the terms of the license (GNU LGPL) which comes with this package. */
-#include "simgrid/modelchecker.h"
#include "private.hpp"
+#include "simgrid/modelchecker.h"
#include "smpi_datatype_derived.hpp"
#include "smpi_op.hpp"
-#include "smpi_process.hpp"
+#include "src/instr/instr_private.hpp"
+#include "src/smpi/include/smpi_actor.hpp"
+
+#include <string>
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_datatype, smpi, "Logging specific to SMPI (datatype)");
-static std::unordered_map<int, simgrid::smpi::Datatype*> id2type_lookup;
+static std::unordered_map<std::string, simgrid::smpi::Datatype*> id2type_lookup;
#define CREATE_MPI_DATATYPE(name, id, type) \
static simgrid::smpi::Datatype mpi_##name((char*)#name, id, sizeof(type), /* size */ \
CREATE_MPI_DATATYPE(MPI_REAL, 38, float);
CREATE_MPI_DATATYPE(MPI_REAL4, 39, float);
-CREATE_MPI_DATATYPE(MPI_REAL8, 40, float);
-CREATE_MPI_DATATYPE(MPI_REAL16, 41, double);
+CREATE_MPI_DATATYPE(MPI_REAL8, 40, double);
+CREATE_MPI_DATATYPE(MPI_REAL16, 41, long double);
+CREATE_MPI_DATATYPE_NULL(MPI_DATATYPE_NULL, -1);
CREATE_MPI_DATATYPE_NULL(MPI_COMPLEX8, 42);
CREATE_MPI_DATATYPE_NULL(MPI_COMPLEX16, 43);
CREATE_MPI_DATATYPE_NULL(MPI_COMPLEX32, 44);
std::unordered_map<int, smpi_key_elem> Datatype::keyvals_; // required by the Keyval class implementation
int Datatype::keyval_id_=0; // required by the Keyval class implementation
-Datatype::Datatype(int id, int size, MPI_Aint lb, MPI_Aint ub, int flags) : Datatype(size, lb, ub, flags)
+Datatype::Datatype(int ident, int size, MPI_Aint lb, MPI_Aint ub, int flags) : Datatype(size, lb, ub, flags)
{
- id = id;
+ id = std::to_string(ident);
}
Datatype::Datatype(int size,MPI_Aint lb, MPI_Aint ub, int flags) : name_(nullptr), size_(size), lb_(lb), ub_(ub), flags_(flags), refcount_(1){
#if SIMGRID_HAVE_MC
}
//for predefined types, so in_use = 0.
-Datatype::Datatype(char* name, int id, int size, MPI_Aint lb, MPI_Aint ub, int flags)
- : name_(name), id(id), size_(size), lb_(lb), ub_(ub), flags_(flags), refcount_(0)
+Datatype::Datatype(char* name, int ident, int size, MPI_Aint lb, MPI_Aint ub, int flags)
+ : name_(name), id(std::to_string(ident)), size_(size), lb_(lb), ub_(ub), flags_(flags), refcount_(0)
{
id2type_lookup.insert({id, this});
#if SIMGRID_HAVE_MC
*ret = MPI_SUCCESS;
if(datatype->name_)
name_ = xbt_strdup(datatype->name_);
-
+
if (not datatype->attributes()->empty()) {
- int flag;
+ int flag=0;
void* value_out;
- for(auto it = datatype->attributes()->begin(); it != datatype->attributes()->end(); it++){
- smpi_key_elem elem = keyvals_.at((*it).first);
-
- if (elem != nullptr && elem->copy_fn.type_copy_fn != MPI_NULL_COPY_FN) {
- *ret = elem->copy_fn.type_copy_fn(datatype, (*it).first, nullptr, (*it).second, &value_out, &flag);
+ for (auto const& it : *(datatype->attributes())) {
+ smpi_key_elem elem = keyvals_.at(it.first);
+ if (elem != nullptr){
+ if( elem->copy_fn.type_copy_fn != MPI_NULL_COPY_FN &&
+ elem->copy_fn.type_copy_fn != MPI_TYPE_DUP_FN)
+ *ret = elem->copy_fn.type_copy_fn(datatype, it.first, elem->extra_state, it.second, &value_out, &flag);
+ else if ( elem->copy_fn.type_copy_fn_fort != MPI_NULL_COPY_FN &&
+ (*(int*)*elem->copy_fn.type_copy_fn_fort) != 1){
+ value_out=(int*)xbt_malloc(sizeof(int));
+ elem->copy_fn.type_copy_fn_fort(datatype, it.first, elem->extra_state, it.second, value_out, &flag,ret);
+ }
if (*ret != MPI_SUCCESS) {
break;
}
- if (flag){
+ if(elem->copy_fn.type_copy_fn == MPI_TYPE_DUP_FN ||
+ ((elem->copy_fn.type_copy_fn_fort != MPI_NULL_COPY_FN) && (*(int*)*elem->copy_fn.type_copy_fn_fort == 1))){
+ elem->refcount++;
+ attributes()->insert({it.first, it.second});
+ } else if (flag){
elem->refcount++;
- attributes()->insert({(*it).first, value_out});
+ attributes()->insert({it.first, value_out});
}
}
}
xbt_free(name_);
}
-
void Datatype::ref(){
refcount_++;
return (flags_ & DT_FLAG_BASIC);
}
-const char* Datatype::encode()
-{
- return std::to_string(id).c_str();
-}
-
-MPI_Datatype Datatype::decode(const char* const datatype_id)
-{
- return id2type_lookup.find(std::stoi(datatype_id))->second;
-}
-
bool Datatype::is_replayable()
{
- return ((this==MPI_BYTE)||(this==MPI_DOUBLE)||(this==MPI_INT)||
- (this==MPI_CHAR)||(this==MPI_SHORT)||(this==MPI_LONG)||(this==MPI_FLOAT));
-}
-
-size_t Datatype::size(){
- return size_;
-}
-
-int Datatype::flags(){
- return flags_;
+ return (simgrid::instr::trace_format == simgrid::instr::TraceFormat::Ti) &&
+ ((this == MPI_BYTE) || (this == MPI_DOUBLE) || (this == MPI_INT) || (this == MPI_CHAR) ||
+ (this == MPI_SHORT) || (this == MPI_LONG) || (this == MPI_FLOAT));
}
-int Datatype::refcount(){
- return refcount_;
+MPI_Datatype Datatype::decode(const std::string& datatype_id)
+{
+ return id2type_lookup.find(datatype_id)->second;
}
void Datatype::addflag(int flag){
flags_ &= flag;
}
-MPI_Aint Datatype::lb(){
- return lb_;
-}
-
-MPI_Aint Datatype::ub(){
- return ub_;
-}
-
-char* Datatype::name(){
- return name_;
-}
-
-
int Datatype::extent(MPI_Aint * lb, MPI_Aint * extent){
*lb = lb_;
*extent = ub_ - lb_;
return MPI_SUCCESS;
}
-MPI_Aint Datatype::get_extent(){
- return ub_ - lb_;
-}
-
void Datatype::get_name(char* name, int* length){
*length = strlen(name_);
strncpy(name, name_, *length+1);
return MPI_SUCCESS;
}
-
int Datatype::copy(void *sendbuf, int sendcount, MPI_Datatype sendtype,
void *recvbuf, int recvcount, MPI_Datatype recvtype){
// FIXME Handle the case of a partial shared malloc.
- if(smpi_privatize_global_variables == SMPI_PRIVATIZE_MMAP){
+ if (smpi_privatize_global_variables == SmpiPrivStrategies::MMAP) {
smpi_switch_data_segment(simgrid::s4u::Actor::self());
}
/* First check if we really have something to do */
}
//Default serialization method : memcpy.
-void Datatype::serialize( void* noncontiguous_buf, void *contiguous_buf, int count){
+void Datatype::serialize(void* noncontiguous_buf, void* contiguous_buf, int count)
+{
char* contiguous_buf_char = static_cast<char*>(contiguous_buf);
char* noncontiguous_buf_char = static_cast<char*>(noncontiguous_buf)+lb_;
memcpy(contiguous_buf_char, noncontiguous_buf_char, count*size_);
-
}
void Datatype::unserialize( void* contiguous_buf, void *noncontiguous_buf, int count, MPI_Op op){
return MPI_ERR_ARG;
}
}
-
+
MPI_Aint extent = oldtype->get_extent();
int i;
step = 1;
end = ndims;
}
-
+
MPI_Aint size = (MPI_Aint)array_of_sizes[i] * (MPI_Aint)array_of_sizes[i+step];
MPI_Aint lb = (MPI_Aint)array_of_starts[i] + (MPI_Aint)array_of_starts[i+step] *(MPI_Aint)array_of_sizes[i];
//handle LB and UB with a resized call
create_hindexed( 1, sizes, lbs, tmp, newtype);
unref(tmp);
-
+
tmp = *newtype;
create_resized(tmp, 0, extent, newtype);