diff --git a/oshmem/mca/scoll/basic/scoll_basic_alltoall.c b/oshmem/mca/scoll/basic/scoll_basic_alltoall.c index 1698ee1335..6a87e85578 100644 --- a/oshmem/mca/scoll/basic/scoll_basic_alltoall.c +++ b/oshmem/mca/scoll/basic/scoll_basic_alltoall.c @@ -61,6 +61,11 @@ int mca_scoll_basic_alltoall(struct oshmem_group_t *group, return OSHMEM_ERR_BAD_PARAM; } + /* Do nothing on zero-length request */ + if (OPAL_UNLIKELY(!nelems)) { + return OPAL_SUCCESS; + } + if ((sst == 1) && (dst == 1)) { rc = a2a_alg_simple(group, target, source, nelems, element_size); } else { diff --git a/oshmem/mca/scoll/basic/scoll_basic_broadcast.c b/oshmem/mca/scoll/basic/scoll_basic_broadcast.c index ef9bf1869b..80059d462d 100644 --- a/oshmem/mca/scoll/basic/scoll_basic_broadcast.c +++ b/oshmem/mca/scoll/basic/scoll_basic_broadcast.c @@ -55,6 +55,11 @@ int mca_scoll_basic_broadcast(struct oshmem_group_t *group, if ((rc == OSHMEM_SUCCESS) && oshmem_proc_group_is_member(group)) { int i = 0; + /* Do nothing on zero-length request */ + if (OPAL_UNLIKELY(!nlong)) { + return OSHMEM_SUCCESS; + } + if (pSync) { alg = (alg == SCOLL_DEFAULT_ALG ? mca_scoll_basic_param_broadcast_algorithm : alg); diff --git a/oshmem/mca/scoll/basic/scoll_basic_collect.c b/oshmem/mca/scoll/basic/scoll_basic_collect.c index eda5f93406..e631a31557 100644 --- a/oshmem/mca/scoll/basic/scoll_basic_collect.c +++ b/oshmem/mca/scoll/basic/scoll_basic_collect.c @@ -66,6 +66,11 @@ int mca_scoll_basic_collect(struct oshmem_group_t *group, if ((rc == OSHMEM_SUCCESS) && oshmem_proc_group_is_member(group)) { int i = 0; + /* Do nothing on zero-length request */ + if (OPAL_UNLIKELY(!nlong)) { + return OPAL_SUCCESS; + } + if (nlong_type) { alg = (alg == SCOLL_DEFAULT_ALG ? mca_scoll_basic_param_collect_algorithm : alg); diff --git a/oshmem/mca/scoll/basic/scoll_basic_reduce.c b/oshmem/mca/scoll/basic/scoll_basic_reduce.c index 9d6db9eed4..b7f6f12310 100644 --- a/oshmem/mca/scoll/basic/scoll_basic_reduce.c +++ b/oshmem/mca/scoll/basic/scoll_basic_reduce.c @@ -78,6 +78,11 @@ int mca_scoll_basic_reduce(struct oshmem_group_t *group, if ((rc == OSHMEM_SUCCESS) && oshmem_proc_group_is_member(group)) { int i = 0; + /* Do nothing on zero-length request */ + if (OPAL_UNLIKELY(!nlong)) { + return OSHMEM_SUCCESS; + } + if (pSync) { alg = (alg == SCOLL_DEFAULT_ALG ? mca_scoll_basic_param_reduce_algorithm : alg); diff --git a/oshmem/mca/scoll/mpi/scoll_mpi_ops.c b/oshmem/mca/scoll/mpi/scoll_mpi_ops.c index 8506dd524d..a52a832588 100644 --- a/oshmem/mca/scoll/mpi/scoll_mpi_ops.c +++ b/oshmem/mca/scoll/mpi/scoll_mpi_ops.c @@ -54,6 +54,12 @@ int mca_scoll_mpi_broadcast(struct oshmem_group_t *group, } dtype = &ompi_mpi_char.dt; root = oshmem_proc_group_find_id(group, PE_root); + + /* Do nothing on zero-length request */ + if (OPAL_UNLIKELY(!nlong)) { + return OSHMEM_SUCCESS; + } + /* Open SHMEM specification has the following constrains (page 85): * "If using C/C++, nelems must be of type integer. If you are using Fortran, it must be a * default integer value". And also fortran signature says "INTEGER". @@ -104,6 +110,12 @@ int mca_scoll_mpi_collect(struct oshmem_group_t *group, void *sbuf, *rbuf; MPI_COLL_VERBOSE(20,"RUNNING MPI ALLGATHER"); mpi_module = (mca_scoll_mpi_module_t *) group->g_scoll.scoll_collect_module; + + /* Do nothing on zero-length request */ + if (OPAL_UNLIKELY(!nlong)) { + return OSHMEM_SUCCESS; + } + if (nlong_type == true) { sbuf = (void *) source; rbuf = target; @@ -177,6 +189,12 @@ int mca_scoll_mpi_reduce(struct oshmem_group_t *group, dtype = shmem_dtype_to_ompi_dtype(op); h_op = shmem_op_to_ompi_op(op->op); count = nlong/op->dt_size; + + /* Do nothing on zero-length request */ + if (OPAL_UNLIKELY(!nlong)) { + return OSHMEM_SUCCESS; + } + /* Open SHMEM specification has the following constrains (page 85): * "If using C/C++, nelems must be of type integer. If you are using Fortran, it must be a * default integer value". And also fortran signature says "INTEGER". diff --git a/oshmem/runtime/runtime.h b/oshmem/runtime/runtime.h index f0a093438d..28f22f3eab 100644 --- a/oshmem/runtime/runtime.h +++ b/oshmem/runtime/runtime.h @@ -200,6 +200,13 @@ OSHMEM_DECLSPEC int oshmem_shmem_register_params(void); RUNTIME_CHECK_ERROR("Required address %p is not in symmetric space\n", ((void*)x)); \ oshmem_shmem_abort(-1); \ } +/* Check if address is in symmetric space or size is zero */ +#define RUNTIME_CHECK_ADDR_SIZE(x,s) \ + if (OPAL_UNLIKELY((s) && !MCA_MEMHEAP_CALL(is_symmetric_addr((x))))) \ + { \ + RUNTIME_CHECK_ERROR("Required address %p is not in symmetric space\n", ((void*)x)); \ + oshmem_shmem_abort(-1); \ + } #define RUNTIME_CHECK_WITH_MEMHEAP_SIZE(x) \ if (OPAL_UNLIKELY((long)(x) > MCA_MEMHEAP_CALL(size))) \ { \ @@ -212,6 +219,7 @@ OSHMEM_DECLSPEC int oshmem_shmem_register_params(void); #define RUNTIME_CHECK_INIT() #define RUNTIME_CHECK_PE(x) #define RUNTIME_CHECK_ADDR(x) +#define RUNTIME_CHECK_ADDR_SIZE(x,s) #define RUNTIME_CHECK_WITH_MEMHEAP_SIZE(x) #endif /* OSHMEM_PARAM_CHECK */ diff --git a/oshmem/shmem/c/shmem_alltoall.c b/oshmem/shmem/c/shmem_alltoall.c index 57f40f67bd..0bc115f713 100644 --- a/oshmem/shmem/c/shmem_alltoall.c +++ b/oshmem/shmem/c/shmem_alltoall.c @@ -30,7 +30,7 @@ static void _shmem_alltoall(void *target, int PE_size, long *pSync); -#define SHMEM_TYPE_ALLTOALL(name, element_size) \ +#define SHMEM_TYPE_ALLTOALL(name, element_size) \ void shmem##name(void *target, \ const void *source, \ size_t nelems, \ @@ -40,15 +40,15 @@ static void _shmem_alltoall(void *target, long *pSync) \ { \ RUNTIME_CHECK_INIT(); \ - RUNTIME_CHECK_ADDR(target); \ - RUNTIME_CHECK_ADDR(source); \ + RUNTIME_CHECK_ADDR_SIZE(target, nelems); \ + RUNTIME_CHECK_ADDR_SIZE(source, nelems); \ \ _shmem_alltoall(target, source, 1, 1, nelems, element_size, \ PE_start, logPE_stride, PE_size, \ pSync); \ } -#define SHMEM_TYPE_ALLTOALLS(name, element_size) \ +#define SHMEM_TYPE_ALLTOALLS(name, element_size) \ void shmem##name(void *target, \ const void *source, \ ptrdiff_t dst, ptrdiff_t sst, \ @@ -59,8 +59,8 @@ static void _shmem_alltoall(void *target, long *pSync) \ { \ RUNTIME_CHECK_INIT(); \ - RUNTIME_CHECK_ADDR(target); \ - RUNTIME_CHECK_ADDR(source); \ + RUNTIME_CHECK_ADDR_SIZE(target, nelems); \ + RUNTIME_CHECK_ADDR_SIZE(source, nelems); \ \ _shmem_alltoall(target, source, dst, sst, nelems, element_size, \ PE_start, logPE_stride, PE_size, \ diff --git a/oshmem/shmem/c/shmem_broadcast.c b/oshmem/shmem/c/shmem_broadcast.c index a618df733c..676cec02f2 100644 --- a/oshmem/shmem/c/shmem_broadcast.c +++ b/oshmem/shmem/c/shmem_broadcast.c @@ -29,7 +29,7 @@ static void _shmem_broadcast(void *target, int PE_size, long *pSync); -#define SHMEM_TYPE_BROADCAST(name, element_size) \ +#define SHMEM_TYPE_BROADCAST(name, element_size) \ void shmem##name( void *target, \ const void *source, \ size_t nelems, \ @@ -40,10 +40,10 @@ static void _shmem_broadcast(void *target, long *pSync) \ { \ RUNTIME_CHECK_INIT(); \ - RUNTIME_CHECK_ADDR(target); \ - RUNTIME_CHECK_ADDR(source); \ + RUNTIME_CHECK_ADDR_SIZE(target, nelems); \ + RUNTIME_CHECK_ADDR_SIZE(source, nelems); \ \ - _shmem_broadcast( target, source, nelems * element_size, \ + _shmem_broadcast( target, source, nelems * element_size, \ PE_root, PE_start, logPE_stride, PE_size, \ pSync); \ } diff --git a/oshmem/shmem/c/shmem_collect.c b/oshmem/shmem/c/shmem_collect.c index 91502035fc..423093d6c1 100644 --- a/oshmem/shmem/c/shmem_collect.c +++ b/oshmem/shmem/c/shmem_collect.c @@ -39,10 +39,10 @@ static void _shmem_collect(void *target, long *pSync) \ { \ RUNTIME_CHECK_INIT(); \ - RUNTIME_CHECK_ADDR(target); \ - RUNTIME_CHECK_ADDR(source); \ + RUNTIME_CHECK_ADDR_SIZE(target, nelems); \ + RUNTIME_CHECK_ADDR_SIZE(source, nelems); \ \ - _shmem_collect( target, source, nelems * element_size, \ + _shmem_collect( target, source, nelems * element_size, \ PE_start, logPE_stride, PE_size, \ pSync, \ nelems_type); \ diff --git a/oshmem/shmem/c/shmem_reduce.c b/oshmem/shmem/c/shmem_reduce.c index 11654196ab..02c47023ce 100644 --- a/oshmem/shmem/c/shmem_reduce.c +++ b/oshmem/shmem/c/shmem_reduce.c @@ -26,8 +26,8 @@ * object of every PE in the active set. The active set of PEs is defined by the triple PE_start, * logPE_stride and PE_size. */ -#define SHMEM_TYPE_REDUCE_OP(name, type_name, type, prefix) \ - void prefix##type_name##_##name##_to_all( type *target, \ +#define SHMEM_TYPE_REDUCE_OP(name, type_name, type, prefix) \ + void prefix##type_name##_##name##_to_all( type *target, \ const type *source, \ int nreduce, \ int PE_start, \ @@ -40,8 +40,8 @@ oshmem_group_t* group = NULL; \ \ RUNTIME_CHECK_INIT(); \ - RUNTIME_CHECK_ADDR(target); \ - RUNTIME_CHECK_ADDR(source); \ + RUNTIME_CHECK_ADDR_SIZE(target, nreduce); \ + RUNTIME_CHECK_ADDR_SIZE(source, nreduce); \ \ { \ group = oshmem_proc_group_create_nofail(PE_start, 1<