- Remove portability wrapper to condition variables
- Remove xbt_os_thread_yield()
+SMPI:
+ - MPICH collective selector now mimics MPICH 3.3b
+ - OpenMPI collective selector now mimics OpenMPI 3.1.2 (default "tuned" setting)
+ - MPI_Init(NULL,NULL) is now allowed
+ - smpi/wtime option now injects time in gettimeofday or clock_gettime calls
+ - Command-line arguments should now be handled properly in Fortran simulations
+ - MPI Attributes and related callbacks should work in Fortran
+ - Apps using C + Fortran should now work
+ - MPI_* calls now check for non MPI_SUCCESS return values and emit warnings
+ - Support MPI_Error_String
+
Java:
- Due to an internal bug, Msg.run() must now be your last line.
We hope to fix it in a future release, and we are sorry for the inconvenience.
actor-lifetime actor-migration actor-suspend actor-yield
app-chainsend app-pingpong app-token-ring
async-ready async-wait async-waitany async-waitall async-waituntil
- barrier
cloud-capping cloud-migration cloud-simple
energy-exec energy-boot energy-link energy-vm
engine-filtering
exec-async exec-basic exec-dvfs exec-monitor exec-ptask exec-remote
io-async io-file-system io-file-remote io-storage-raw
- mutex
platform-failures platform-properties plugin-hostload
replay-comm replay-storage
routing-get-clusters
+ synchro-barrier synchro-mutex
trace-platform)
add_executable (s4u-${example} ${example}/s4u-${example}.cpp)
target_link_libraries(s4u-${example} simgrid)
actor-lifetime actor-migration actor-suspend actor-yield
app-bittorrent app-chainsend app-masterworkers app-pingpong app-token-ring
async-ready async-wait async-waitall async-waitany async-waituntil
- barrier
cloud-capping cloud-migration cloud-simple
dht-chord dht-kademlia
energy-exec energy-boot energy-link energy-vm
engine-filtering
exec-async exec-basic exec-dvfs exec-monitor exec-ptask exec-remote
- platform-properties plugin-hostload mutex # FIXME: platform-failures is disabled
+ platform-properties plugin-hostload # FIXME: platform-failures is disabled
io-async io-file-system io-file-remote io-storage-raw
replay-comm replay-storage
routing-get-clusters
+ synchro-barrier synchro-mutex
)
ADD_TESH_FACTORIES(s4u-${example} "thread;ucontext;raw;boost"
--setenv bindir=${CMAKE_CURRENT_BINARY_DIR}/${example}
- **Mutex:**
Shows how to use simgrid::s4u::Mutex synchronization objects.
- |br| `examples/s4u/mutex/s4u-mutex.cpp <https://framagit.org/simgrid/simgrid/tree/master/examples/s4u/mutex/s4u-mutex.cpp>`_
+ |br| `examples/s4u/synchro-mutex/s4u-synchro-mutex.cpp <https://framagit.org/simgrid/simgrid/tree/master/examples/s4u/synchro-mutex/s4u-synchro-mutex.cpp>`_
+
+ - **Barrier:**
+ Shows how to use simgrid::s4u::Barrier synchronization objects.
+ |br| `examples/s4u/synchro-barrier/s4u-synchro-barrier.cpp <https://framagit.org/simgrid/simgrid/tree/master/examples/s4u/synchro-barrier/s4u-synchro-barrier.cpp>`_
.............................
Interacting with the platform
#!/usr/bin/env tesh
-$ $SG_TEST_EXENV ${bindir:=.}/s4u-barrier 1
+$ $SG_TEST_EXENV ${bindir:=.}/s4u-synchro-barrier 1
> [Tremblay:master:(1) 0.000000] [s4u_test/INFO] Spawning 0 workers
> [Tremblay:master:(1) 0.000000] [s4u_test/INFO] Waiting on the barrier
> [Tremblay:master:(1) 0.000000] [s4u_test/INFO] Bye
-$ $SG_TEST_EXENV ${bindir:=.}/s4u-barrier 2
+$ $SG_TEST_EXENV ${bindir:=.}/s4u-synchro-barrier 2
> [Tremblay:master:(1) 0.000000] [s4u_test/INFO] Spawning 1 workers
> [Jupiter:worker:(2) 0.000000] [s4u_test/INFO] Waiting on the barrier
> [Tremblay:master:(1) 0.000000] [s4u_test/INFO] Waiting on the barrier
> [Tremblay:master:(1) 0.000000] [s4u_test/INFO] Bye
> [Jupiter:worker:(2) 0.000000] [s4u_test/INFO] Bye
-$ $SG_TEST_EXENV ${bindir:=.}/s4u-barrier 3
+$ $SG_TEST_EXENV ${bindir:=.}/s4u-synchro-barrier 3
> [Tremblay:master:(1) 0.000000] [s4u_test/INFO] Spawning 2 workers
> [Jupiter:worker:(2) 0.000000] [s4u_test/INFO] Waiting on the barrier
> [Jupiter:worker:(3) 0.000000] [s4u_test/INFO] Waiting on the barrier
> [Jupiter:worker:(2) 0.000000] [s4u_test/INFO] Bye
> [Jupiter:worker:(3) 0.000000] [s4u_test/INFO] Bye
-$ $SG_TEST_EXENV ${bindir:=.}/s4u-barrier 10
+$ $SG_TEST_EXENV ${bindir:=.}/s4u-synchro-barrier 10
> [Tremblay:master:(1) 0.000000] [s4u_test/INFO] Spawning 9 workers
> [Jupiter:worker:(2) 0.000000] [s4u_test/INFO] Waiting on the barrier
> [Jupiter:worker:(3) 0.000000] [s4u_test/INFO] Waiting on the barrier
#!/usr/bin/env tesh
-$ $SG_TEST_EXENV ${bindir:=.}/s4u-mutex
+$ $SG_TEST_EXENV ${bindir:=.}/s4u-synchro-mutex
> [Jupiter:worker:(2) 0.000000] [s4u_test/INFO] Hello s4u, I'm ready to compute after a lock_guard
> [Jupiter:worker:(2) 0.000000] [s4u_test/INFO] I'm done, good bye
> [Tremblay:worker:(3) 0.000000] [s4u_test/INFO] Hello s4u, I'm ready to compute after a regular lock
1. Sleep until job's starting time is reached (if needed)
2. Launch the replay of the corresponding time-indepent trace.
3. Create inter-process noise, by spawning useless actors.
- 4. Wait for completion (implicitly, via MSG_main's return)
+ 4. Wait for completion (via s4u::Engine's run method)
*/
#include <algorithm>
struct s_smpi_replay_process_args {
Job* job;
- msg_sem_t semaphore;
+ simgrid::s4u::BarrierPtr barrier;
int rank;
};
{
s_smpi_replay_process_args* args = static_cast<s_smpi_replay_process_args*>(MSG_process_get_data(MSG_process_self()));
- if (args->semaphore != nullptr)
- MSG_sem_acquire(args->semaphore);
-
XBT_INFO("Replaying rank %d of job %d (smpi_app '%s')", args->rank, args->job->unique_job_number,
args->job->smpi_app_name.c_str());
XBT_INFO("Finished replaying rank %d of job %d (smpi_app '%s')", args->rank, args->job->unique_job_number,
args->job->smpi_app_name.c_str());
- if (args->semaphore != nullptr)
- MSG_sem_release(args->semaphore);
+ args->barrier->wait();
delete args;
return 0;
static int job_executor_process(Job* job)
{
- msg_sem_t job_semaphore = MSG_sem_init(1);
XBT_INFO("Executing job %d (smpi_app '%s')", job->unique_job_number, job->smpi_app_name.c_str());
+ simgrid::s4u::BarrierPtr barrier = simgrid::s4u::Barrier::create(job->app_size + 1);
+
for (int i = 0; i < job->app_size; ++i) {
char** argv = xbt_new(char*, 5);
argv[0] = xbt_strdup("1"); // log only?
s_smpi_replay_process_args* args = new s_smpi_replay_process_args;
args->job = job;
- args->semaphore = nullptr;
+ args->barrier = barrier;
args->rank = i;
- if (i == 0)
- args->semaphore = job_semaphore;
-
char* str_pname = bprintf("%d_%d", job->unique_job_number, i);
MSG_process_create_with_arguments(str_pname, smpi_replay_process, (void*)args, hosts[job->allocation[i]], 5, argv);
xbt_free(str_pname);
}
- MSG_sem_acquire(job_semaphore);
- MSG_sem_destroy(job_semaphore);
+ barrier->wait();
XBT_INFO("Finished job %d (smpi_app '%s')", job->unique_job_number, job->smpi_app_name.c_str());
integer MPI_COMM_NULL_COPY_FN, MPI_COMM_NULL_DELETE_FN
parameter(MPI_COMM_NULL_COPY_FN =0)
parameter(MPI_COMM_NULL_DELETE_FN =0)
- integer MPI_COMM_NULL_DUP_FN, MPI_COMM_DUP_FN
- parameter(MPI_COMM_NULL_DUP_FN =0)
- parameter(MPI_COMM_DUP_FN =0)
+ integer MPI_COMM_DUP_FN
+ parameter(MPI_COMM_DUP_FN =1)
integer MPI_WIN_NULL_COPY_FN, MPI_WIN_NULL_DELETE_FN
parameter(MPI_WIN_NULL_COPY_FN =0)
parameter(MPI_WIN_NULL_DELETE_FN =0)
integer MPI_WIN_DUP_FN
- parameter(MPI_WIN_DUP_FN =0)
+ parameter(MPI_WIN_DUP_FN =1)
+ integer MPI_TYPE_NULL_COPY_FN, MPI_TYPE_NULL_DELETE_FN
+ parameter(MPI_TYPE_NULL_COPY_FN =0)
+ parameter(MPI_TYPE_NULL_DELETE_FN =0)
+ integer MPI_TYPE_DUP_FN
+ parameter(MPI_TYPE_DUP_FN =1)
integer MPI_ROOT, MPI_COMM_TYPE_SHARED
parameter(MPI_ROOT=0)
typedef int MPI_Copy_function(MPI_Comm oldcomm, int keyval, void* extra_state, void* attribute_val_in,
void* attribute_val_out, int* flag);
typedef int MPI_Delete_function(MPI_Comm comm, int keyval, void* attribute_val, void* extra_state);
+typedef void MPI_Copy_function_fort(MPI_Comm oldcomm, int keyval, void* extra_state, void* attribute_val_in,
+ void* attribute_val_out, int* flag, int* ierr);
+typedef void MPI_Delete_function_fort(MPI_Comm comm, int keyval, void* attribute_val, void* extra_state, int* ierr);
#define MPI_Comm_copy_attr_function MPI_Copy_function
#define MPI_Comm_delete_attr_function MPI_Delete_function
+#define MPI_Comm_copy_attr_function_fort MPI_Copy_function_fort
+#define MPI_Comm_delete_attr_function_fort MPI_Delete_function_fort
typedef int MPI_Type_copy_attr_function(MPI_Datatype type, int keyval, void* extra_state, void* attribute_val_in,
void* attribute_val_out, int* flag);
typedef int MPI_Type_delete_attr_function(MPI_Datatype type, int keyval, void* attribute_val, void* extra_state);
typedef int MPI_Win_copy_attr_function(MPI_Win win, int keyval, void* extra_state, void* attribute_val_in,
void* attribute_val_out, int* flag);
typedef int MPI_Win_delete_attr_function(MPI_Win win, int keyval, void* attribute_val, void* extra_state);
+typedef void MPI_Type_copy_attr_function_fort(MPI_Datatype type, int keyval, void* extra_state, void* attribute_val_in,
+ void* attribute_val_out, int* flag, int* ierr);
+typedef void MPI_Type_delete_attr_function_fort(MPI_Datatype type, int keyval, void* attribute_val, void* extra_state, int* ierr);
+typedef void MPI_Win_copy_attr_function_fort(MPI_Win win, int keyval, void* extra_state, void* attribute_val_in,
+ void* attribute_val_out, int* flag, int* ierr);
+typedef void MPI_Win_delete_attr_function_fort(MPI_Win win, int keyval, void* attribute_val, void* extra_state, int* ierr);
#define MPI_COMM_NULL_COPY_FN ((MPI_Comm_copy_attr_function*)0)
#define MPI_COMM_NULL_DELETE_FN ((MPI_Comm_delete_attr_function*)0)
#define MPI_TYPE_NULL_COPY_FN ((MPI_Type_copy_attr_function*)0)
typedef int MPI_Grequest_query_function(void *extra_state, MPI_Status *status);
typedef int MPI_Grequest_free_function(void *extra_state);
typedef int MPI_Grequest_cancel_function(void *extra_state, int complete);
-#define MPI_DUP_FN MPI_Comm_dup
+#define MPI_DUP_FN 1
#define MPI_WIN_DUP_FN ((MPI_Win_copy_attr_function*)MPI_DUP_FN)
#define MPI_TYPE_DUP_FN ((MPI_Type_copy_attr_function*)MPI_DUP_FN)
void mpi_attr_get_(int* comm, int* keyval, int* attr_value, int* flag, int* ierr ){
int* value = nullptr;
*ierr = MPI_Attr_get(simgrid::smpi::Comm::f2c(*comm), *keyval, &value, flag);
- *attr_value = *value;
+ if(*flag == 1)
+ *attr_value=*value;
}
void mpi_error_string_(int* errorcode, char* string, int* resultlen, int* ierr){
void mpi_win_get_attr_(int* win, int* type_keyval, int* attribute_val, int* flag, int* ierr){
int* value = nullptr;
*ierr = MPI_Win_get_attr(simgrid::smpi::Win::f2c(*win), *type_keyval, &value, flag);
- *attribute_val=*value;
+ if (*flag == 1)
+ *attribute_val = *value;
}
-void mpi_win_set_attr_(int* win, int* type_keyval, void* att, int* ierr){
- *ierr = MPI_Win_set_attr(simgrid::smpi::Win::f2c(*win), *type_keyval, att);
+void mpi_win_set_attr_(int* win, int* type_keyval, int* att, int* ierr){
+ int* val = (int*)xbt_malloc(sizeof(int));
+ *val=*att;
+ *ierr = MPI_Win_set_attr(simgrid::smpi::Win::f2c(*win), *type_keyval, val);
}
void mpi_win_delete_attr_(int* win, int* comm_keyval, int* ierr){
}
void mpi_win_create_keyval_(void* copy_fn, void* delete_fn, int* keyval, void* extra_state, int* ierr){
- *ierr = MPI_Win_create_keyval(reinterpret_cast<MPI_Win_copy_attr_function*>(copy_fn),
- reinterpret_cast<MPI_Win_delete_attr_function*>(delete_fn), keyval, extra_state);
+ smpi_copy_fn _copy_fn={nullptr,nullptr,nullptr,nullptr,nullptr,(*(int*)copy_fn) == 0 ? nullptr : reinterpret_cast<MPI_Win_copy_attr_function_fort*>(copy_fn)};
+ smpi_delete_fn _delete_fn={nullptr,nullptr,nullptr,nullptr,nullptr,(*(int*)delete_fn) == 0 ? nullptr : reinterpret_cast<MPI_Win_delete_attr_function_fort*>(delete_fn)};
+ *ierr = simgrid::smpi::Keyval::keyval_create<simgrid::smpi::Win>(_copy_fn, _delete_fn, keyval, extra_state);
}
void mpi_win_free_keyval_(int* keyval, int* ierr){
*ierr = MPI_Attr_delete(simgrid::smpi::Comm::f2c(*comm), *keyval);
}
-void mpi_attr_put_ (int* comm, int* keyval, void* attr_value, int* ierr) {
- *ierr = MPI_Attr_put(simgrid::smpi::Comm::f2c(*comm), *keyval, attr_value);
+void mpi_attr_put_ (int* comm, int* keyval, int* attr_value, int* ierr) {
+ int* val = (int*)xbt_malloc(sizeof(int));
+ *val=*attr_value;
+ *ierr = MPI_Attr_put(simgrid::smpi::Comm::f2c(*comm), *keyval, val);
}
void mpi_keyval_create_ (void* copy_fn, void* delete_fn, int* keyval, void* extra_state, int* ierr) {
- *ierr = MPI_Keyval_create(reinterpret_cast<MPI_Copy_function*>(copy_fn),reinterpret_cast<MPI_Delete_function*>(delete_fn), keyval, extra_state);
+ smpi_copy_fn _copy_fn={nullptr,nullptr,nullptr,(*(int*)copy_fn) == 0 ? nullptr : reinterpret_cast<MPI_Copy_function_fort*>(copy_fn),nullptr,nullptr};
+ smpi_delete_fn _delete_fn={nullptr,nullptr,nullptr,(*(int*)delete_fn) == 0 ? nullptr : reinterpret_cast<MPI_Delete_function_fort*>(delete_fn),nullptr,nullptr};
+ *ierr = simgrid::smpi::Keyval::keyval_create<simgrid::smpi::Comm>(_copy_fn, _delete_fn, keyval, extra_state);
}
void mpi_keyval_free_ (int* keyval, int* ierr) {
void mpi_comm_get_attr_ (int* comm, int* comm_keyval, int *attribute_val, int *flag, int* ierr){
int* value = nullptr;
*ierr = MPI_Comm_get_attr (simgrid::smpi::Comm::f2c(*comm), *comm_keyval, &value, flag);
- *attribute_val = *value;
+ if (*flag == 1)
+ *attribute_val = *value;
}
-void mpi_comm_set_attr_ (int* comm, int* comm_keyval, void *attribute_val, int* ierr){
-
- *ierr = MPI_Comm_set_attr ( simgrid::smpi::Comm::f2c(*comm), *comm_keyval, attribute_val);
+void mpi_comm_set_attr_ (int* comm, int* comm_keyval, int *attribute_val, int* ierr){
+ int* val = (int*)xbt_malloc(sizeof(int));
+ *val=*attribute_val;
+ *ierr = MPI_Comm_set_attr ( simgrid::smpi::Comm::f2c(*comm), *comm_keyval, val);
}
void mpi_comm_delete_attr_ (int* comm, int* comm_keyval, int* ierr){
}
void mpi_comm_create_keyval_ (void* copy_fn, void* delete_fn, int* keyval, void* extra_state, int* ierr){
-
- *ierr = MPI_Comm_create_keyval(reinterpret_cast<MPI_Comm_copy_attr_function*>(copy_fn), reinterpret_cast<MPI_Comm_delete_attr_function*>(delete_fn),
- keyval, extra_state) ;
+ smpi_copy_fn _copy_fn={nullptr,nullptr,nullptr,(*(int*)copy_fn) == 0 ? nullptr : reinterpret_cast<MPI_Comm_copy_attr_function_fort*>(copy_fn),nullptr,nullptr};
+ smpi_delete_fn _delete_fn={nullptr,nullptr,nullptr,(*(int*)delete_fn) == 0 ? nullptr : reinterpret_cast<MPI_Comm_delete_attr_function_fort*>(delete_fn),nullptr,nullptr};
+ *ierr = simgrid::smpi::Keyval::keyval_create<simgrid::smpi::Comm>(_copy_fn, _delete_fn, keyval, extra_state);
}
void mpi_comm_free_keyval_ (int* keyval, int* ierr) {
void mpi_type_get_attr_ (int* type, int* type_keyval, int *attribute_val, int* flag, int* ierr){
int* value = nullptr;
*ierr = MPI_Type_get_attr ( simgrid::smpi::Datatype::f2c(*type), *type_keyval, &value, flag);
- *attribute_val = *value;
+ if (*flag == 1)
+ *attribute_val = *value;
}
-void mpi_type_set_attr_ (int* type, int* type_keyval, void *attribute_val, int* ierr){
-
- *ierr = MPI_Type_set_attr ( simgrid::smpi::Datatype::f2c(*type), *type_keyval, attribute_val);
+void mpi_type_set_attr_ (int* type, int* type_keyval, int *attribute_val, int* ierr){
+ int* val = (int*)xbt_malloc(sizeof(int));
+ *val=*attribute_val;
+ *ierr = MPI_Type_set_attr ( simgrid::smpi::Datatype::f2c(*type), *type_keyval, val);
}
void mpi_type_delete_attr_ (int* type, int* type_keyval, int* ierr){
}
void mpi_type_create_keyval_ (void* copy_fn, void* delete_fn, int* keyval, void* extra_state, int* ierr){
-
- *ierr = MPI_Type_create_keyval(reinterpret_cast<MPI_Type_copy_attr_function*>(copy_fn), reinterpret_cast<MPI_Type_delete_attr_function*>(delete_fn),
- keyval, extra_state) ;
+ smpi_copy_fn _copy_fn={nullptr,nullptr,nullptr,nullptr,(*(int*)copy_fn) == 0 ? nullptr : reinterpret_cast<MPI_Type_copy_attr_function_fort*>(copy_fn),nullptr};
+ smpi_delete_fn _delete_fn={nullptr,nullptr,nullptr,nullptr,(*(int*)delete_fn) == 0 ? nullptr : reinterpret_cast<MPI_Type_delete_attr_function_fort*>(delete_fn),nullptr};
+ *ierr = simgrid::smpi::Keyval::keyval_create<simgrid::smpi::Datatype>(_copy_fn, _delete_fn, keyval, extra_state);
}
void mpi_type_free_keyval_ (int* keyval, int* ierr) {
char error_string[MPI_MAX_ERROR_STRING]; \
int error_size; \
PMPI_Error_string(ret, error_string, &error_size); \
- XBT_DEBUG("%s - returned %.*s instead of MPI_SUCCESS", __func__, error_size,error_string); \
+ XBT_WARN("%s - returned %.*s instead of MPI_SUCCESS", __func__, error_size,error_string); \
} \
XBT_VERB("SMPI - Leaving %s", __func__); \
return ret; \
}
int PMPI_Keyval_create(MPI_Copy_function* copy_fn, MPI_Delete_function* delete_fn, int* keyval, void* extra_state) {
- smpi_copy_fn _copy_fn={copy_fn,nullptr,nullptr};
- smpi_delete_fn _delete_fn={delete_fn,nullptr,nullptr};
+ smpi_copy_fn _copy_fn={copy_fn,nullptr,nullptr,nullptr,nullptr,nullptr};
+ smpi_delete_fn _delete_fn={delete_fn,nullptr,nullptr,nullptr,nullptr,nullptr};
return simgrid::smpi::Keyval::keyval_create<simgrid::smpi::Comm>(_copy_fn, _delete_fn, keyval, extra_state);
}
int PMPI_Type_create_keyval(MPI_Type_copy_attr_function* copy_fn, MPI_Type_delete_attr_function* delete_fn, int* keyval,
void* extra_state)
{
- smpi_copy_fn _copy_fn={nullptr,copy_fn,nullptr};
- smpi_delete_fn _delete_fn={nullptr,delete_fn,nullptr};
+ smpi_copy_fn _copy_fn={nullptr,copy_fn,nullptr,nullptr,nullptr,nullptr};
+ smpi_delete_fn _delete_fn={nullptr,delete_fn,nullptr,nullptr,nullptr,nullptr};
return simgrid::smpi::Keyval::keyval_create<simgrid::smpi::Datatype>(_copy_fn, _delete_fn, keyval, extra_state);
}
int PMPI_Win_create_keyval(MPI_Win_copy_attr_function* copy_fn, MPI_Win_delete_attr_function* delete_fn, int* keyval,
void* extra_state)
{
- smpi_copy_fn _copy_fn={nullptr, nullptr, copy_fn};
- smpi_delete_fn _delete_fn={nullptr, nullptr, delete_fn};
+ smpi_copy_fn _copy_fn={nullptr, nullptr,copy_fn,nullptr, nullptr,nullptr};
+ smpi_delete_fn _delete_fn={nullptr, nullptr,delete_fn,nullptr, nullptr,nullptr};
return simgrid::smpi::Keyval::keyval_create<simgrid::smpi::Win>(_copy_fn, _delete_fn, keyval, extra_state);
}
void mpi_win_get_info_(int* win, int* info, int* ierr);
void mpi_win_get_group_(int* win, int* group, int* ierr);
void mpi_win_get_attr_(int* win, int* type_keyval, int* attribute_val, int* flag, int* ierr);
-void mpi_win_set_attr_(int* win, int* type_keyval, void* att, int* ierr);
+void mpi_win_set_attr_(int* win, int* type_keyval, int* att, int* ierr);
void mpi_win_delete_attr_(int* win, int* comm_keyval, int* ierr);
void mpi_win_create_keyval_(void* copy_fn, void* delete_fn, int* keyval, void* extra_state, int* ierr);
void mpi_win_free_keyval_(int* keyval, int* ierr);
void mpi_type_set_name_(int* datatype, char* name, int* ierr, int size);
void mpi_type_get_name_(int* datatype, char* name, int* len, int* ierr);
void mpi_type_get_attr_(int* type, int* type_keyval, int* attribute_val, int* flag, int* ierr);
-void mpi_type_set_attr_(int* type, int* type_keyval, void* attribute_val, int* ierr);
+void mpi_type_set_attr_(int* type, int* type_keyval, int* attribute_val, int* ierr);
void mpi_type_delete_attr_(int* type, int* type_keyval, int* ierr);
void mpi_type_create_keyval_(void* copy_fn, void* delete_fn, int* keyval, void* extra_state, int* ierr);
void mpi_type_free_keyval_(int* keyval, int* ierr);
void mpi_group_range_incl_(int* group, int* n, int ranges[][3], int* newgroup, int* ierr);
void mpi_group_range_excl_(int* group, int* n, int ranges[][3], int* newgroup, int* ierr);
void mpi_comm_get_attr_(int* comm, int* comm_keyval, int* attribute_val, int* flag, int* ierr);
-void mpi_comm_set_attr_(int* comm, int* comm_keyval, void* attribute_val, int* ierr);
+void mpi_comm_set_attr_(int* comm, int* comm_keyval, int* attribute_val, int* ierr);
void mpi_comm_delete_attr_(int* comm, int* comm_keyval, int* ierr);
void mpi_comm_create_keyval_(void* copy_fn, void* delete_fn, int* keyval, void* extra_state, int* ierr);
void mpi_comm_free_keyval_(int* keyval, int* ierr);
void mpi_issend_(void* buf, int* count, int* datatype, int* dest, int* tag, int* comm, int* request, int* ierr);
void mpi_probe_(int* source, int* tag, int* comm, MPI_Status* status, int* ierr);
void mpi_attr_delete_(int* comm, int* keyval, int* ierr);
-void mpi_attr_put_(int* comm, int* keyval, void* attr_value, int* ierr);
+void mpi_attr_put_(int* comm, int* keyval, int* attr_value, int* ierr);
void mpi_rsend_init_(void* buf, int* count, int* datatype, int* dest, int* tag, int* comm, int* request, int* ierr);
void mpi_keyval_create_(void* copy_fn, void* delete_fn, int* keyval, void* extra_state, int* ierr);
void mpi_keyval_free_(int* keyval, int* ierr);
MPI_Comm_delete_attr_function *comm_delete_fn;
MPI_Type_delete_attr_function *type_delete_fn;
MPI_Win_delete_attr_function *win_delete_fn;
+ MPI_Comm_delete_attr_function_fort *comm_delete_fn_fort;
+ MPI_Type_delete_attr_function_fort *type_delete_fn_fort;
+ MPI_Win_delete_attr_function_fort *win_delete_fn_fort;
};
struct smpi_copy_fn {
MPI_Comm_copy_attr_function *comm_copy_fn;
MPI_Type_copy_attr_function *type_copy_fn;
MPI_Win_copy_attr_function *win_copy_fn;
+ MPI_Comm_copy_attr_function_fort *comm_copy_fn_fort;
+ MPI_Type_copy_attr_function_fort *type_copy_fn_fort;
+ MPI_Win_copy_attr_function_fort *win_copy_fn_fort;
};
struct s_smpi_key_elem_t {
smpi_copy_fn copy_fn;
smpi_delete_fn delete_fn;
+ void* extra_state;
int refcount;
};
value->copy_fn=copy_fn;
value->delete_fn=delete_fn;
+ value->extra_state=extra_state;
value->refcount=1;
*keyval = T::keyval_id_;
if(elem==nullptr)
return MPI_ERR_ARG;
elem->refcount++;
- void * value = nullptr;
int flag=0;
- this->attr_get<T>(keyval, &value, &flag);
- if(flag!=0){
- int ret = call_deleter<T>((T*)this, elem, keyval,value,&flag);
+ auto p = attributes()->insert({keyval, attr_value});
+ if (!p.second) {
+ int ret = call_deleter<T>((T*)this, elem, keyval,p.first->second,&flag);
+ // overwrite previous value
+ p.first->second = attr_value;
if(ret!=MPI_SUCCESS)
- return ret;
+ return ret;
}
- attributes()->insert({keyval, attr_value});
return MPI_SUCCESS;
}
int ret = MPI_SUCCESS;
if (not attributes()->empty()) {
- int flag;
- void* value_out;
+ int flag=0;
+ void* value_out=nullptr;
for (auto const& it : *attributes()) {
smpi_key_elem elem = keyvals_.at(it.first);
- if (elem != nullptr && elem->copy_fn.comm_copy_fn != MPI_NULL_COPY_FN) {
- ret = elem->copy_fn.comm_copy_fn(this, it.first, nullptr, it.second, &value_out, &flag);
+ if (elem != nullptr){
+ if( elem->copy_fn.comm_copy_fn != MPI_NULL_COPY_FN &&
+ elem->copy_fn.comm_copy_fn != MPI_COMM_DUP_FN)
+ ret = elem->copy_fn.comm_copy_fn(this, it.first, elem->extra_state, it.second, &value_out, &flag);
+ else if ( elem->copy_fn.comm_copy_fn_fort != MPI_NULL_COPY_FN &&
+ *(int*)*elem->copy_fn.comm_copy_fn_fort != 1){
+ value_out=(int*)xbt_malloc(sizeof(int));
+ elem->copy_fn.comm_copy_fn_fort(this, it.first, elem->extra_state, it.second, value_out, &flag,&ret);
+ }
if (ret != MPI_SUCCESS) {
Comm::destroy(*newcomm);
*newcomm = MPI_COMM_NULL;
return ret;
}
- if (flag){
+ if (elem->copy_fn.comm_copy_fn == MPI_COMM_DUP_FN ||
+ ((elem->copy_fn.comm_copy_fn_fort != MPI_NULL_COPY_FN) && *(int*)*elem->copy_fn.comm_copy_fn_fort == 1)){
+ elem->refcount++;
+ (*newcomm)->attributes()->insert({it.first, it.second});
+ }else if (flag){
elem->refcount++;
(*newcomm)->attributes()->insert({it.first, value_out});
}
*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});
}
}
}
template <> int Keyval::call_deleter<Comm>(Comm* obj, smpi_key_elem elem, int keyval, void * value, int* flag){
- if(elem->delete_fn.comm_delete_fn!=MPI_NULL_DELETE_FN){
- int ret = elem->delete_fn.comm_delete_fn(obj, keyval, value, flag);
- if(ret!=MPI_SUCCESS)
- return ret;
- }
- return MPI_SUCCESS;
+ int ret = MPI_SUCCESS;
+ if(elem->delete_fn.comm_delete_fn!=MPI_NULL_DELETE_FN)
+ ret = elem->delete_fn.comm_delete_fn(obj, keyval, value, elem->extra_state);
+ else if(elem->delete_fn.comm_delete_fn_fort!=MPI_NULL_DELETE_FN)
+ elem->delete_fn.comm_delete_fn_fort(obj, keyval, value, elem->extra_state, &ret);
+ return ret;
}
template <> int Keyval::call_deleter<Win>(Win* obj, smpi_key_elem elem, int keyval, void * value, int* flag){
- if(elem->delete_fn.win_delete_fn!=MPI_NULL_DELETE_FN){
- int ret = elem->delete_fn.win_delete_fn(obj, keyval, value, flag);
- if(ret!=MPI_SUCCESS)
- return ret;
- }
- return MPI_SUCCESS;
+ int ret = MPI_SUCCESS;
+ if(elem->delete_fn.win_delete_fn!=MPI_NULL_DELETE_FN)
+ ret = elem->delete_fn.win_delete_fn(obj, keyval, value, elem->extra_state);
+ else if(elem->delete_fn.win_delete_fn_fort!=MPI_NULL_DELETE_FN)
+ elem->delete_fn.win_delete_fn_fort(obj, keyval, value, elem->extra_state, &ret);
+ return ret;
}
template <> int Keyval::call_deleter<Datatype>(Datatype* obj, smpi_key_elem elem, int keyval, void * value, int* flag){
- if(elem->delete_fn.type_delete_fn!=MPI_NULL_DELETE_FN){
- int ret = elem->delete_fn.type_delete_fn(obj, keyval, value, flag);
- if(ret!=MPI_SUCCESS)
- return ret;
- }
- return MPI_SUCCESS;
+ int ret = MPI_SUCCESS;
+ if(elem->delete_fn.type_delete_fn!=MPI_NULL_DELETE_FN)
+ ret = elem->delete_fn.type_delete_fn(obj, keyval, value, elem->extra_state);
+ else if(elem->delete_fn.type_delete_fn_fort!=MPI_NULL_DELETE_FN)
+ elem->delete_fn.type_delete_fn_fort(obj, keyval, value, elem->extra_state, &ret);
+ return ret;
}
}
-#attr
+attr
coll
datatype
pt2pt
teshsuite/smpi/mpich3-test/coll/CMakeLists.txt
teshsuite/smpi/mpich3-test/comm/CMakeLists.txt
teshsuite/smpi/mpich3-test/datatype/CMakeLists.txt
-# teshsuite/smpi/mpich3-test/f77/attr/CMakeLists.txt
+ teshsuite/smpi/mpich3-test/f77/attr/CMakeLists.txt
teshsuite/smpi/mpich3-test/f77/coll/CMakeLists.txt
teshsuite/smpi/mpich3-test/f77/info/CMakeLists.txt
teshsuite/smpi/mpich3-test/f77/comm/CMakeLists.txt