Add a check for the unexpected handler. If enabled, allow the zero-copy
protocol over the MX BTL. Now, we have only one matching, the one in Open MPI. The problem is that when the unexpected handler is triggered, not all the message is on the host memory. In the best case we get one MX fragment (internal MX fragment), in the worst we get NULL. The only way to fit this with the design of the PML is to force the eager protocol at the MX internal fragment size, and to limit the send/receive protocol at the same size. Tests show the outcome is not far from optimal (if the pipeline depth is increased a little bit). Set MX_PIPELINE_LOG in order to allow MX to use internal fragments of 4K. This commit was SVN r12930.
Этот коммит содержится в:
родитель
ff2319dcb7
Коммит
3903009b8b
@ -3,7 +3,7 @@
|
||||
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
# University Research and Technology
|
||||
# Corporation. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
# Copyright (c) 2004-2006 The University of Tennessee and The University
|
||||
# of Tennessee Research Foundation. All rights
|
||||
# reserved.
|
||||
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
@ -17,25 +17,28 @@
|
||||
# $HEADER$
|
||||
#
|
||||
|
||||
AC_DEFUN([_OMPI_CHECK_MX_REGISTER_CALLBACK],[
|
||||
AC_DEFUN([_OMPI_CHECK_MX_UNEXP_HANDLER],[
|
||||
#
|
||||
# Check if the MX library provide the mx_register_unexp_callback function.
|
||||
# Check if the MX library provide the mx_register_unexp_handler function.
|
||||
# With this function, OMPI can avoid having a double matching logic
|
||||
# (one on the MX library and one on OMPI) by registering our own matching
|
||||
# function.
|
||||
# function. Moreover, we can handle all eager messages with just one
|
||||
# memcpy.
|
||||
|
||||
AC_MSG_CHECKING([for a MX version with mx_register_match_callback])
|
||||
AC_TRY_LINK([#include <myriexpress.h>],
|
||||
[mx_register_unexp_callback(0, 0, 0);],
|
||||
[mx_provide_match_callback="yes"],
|
||||
[mx_provide_match_callback="no"])
|
||||
AC_MSG_RESULT([$mx_provide_match_callback])
|
||||
AS_IF([test x"$mx_provide_match_callback" = "xyes"],
|
||||
[AC_DEFINE_UNQUOTED([OMPI_MCA_MX_HAVE_MATCH_CALLBACK], [1],
|
||||
[MX define a match callback])
|
||||
AC_MSG_CHECKING([for a MX version with mx_register_unexp_handler])
|
||||
AC_TRY_LINK([#include <mx_extensions.h>],
|
||||
[mx_register_unexp_handler(0, 0, 0);],
|
||||
[mx_provide_unexp_handler="yes"],
|
||||
[mx_provide_unexp_handler="no"])
|
||||
AC_MSG_RESULT([$mx_provide_unexp_handler])
|
||||
AS_IF([test x"$mx_provide_unexp_handler" = "xyes"],
|
||||
[mx_provide_unexp_handler=1
|
||||
$2],
|
||||
[$3])
|
||||
unset mx_provide_match_callback
|
||||
[mx_provide_unexp_handler=0
|
||||
$3])
|
||||
AC_DEFINE_UNQUOTED([MX_HAVE_UNEXPECTED_HANDLER], [$mx_provide_unexp_handler],
|
||||
[MX allow registration of an unexpected handler])
|
||||
unset mx_provide_unexp_handler
|
||||
])
|
||||
|
||||
AC_DEFUN([_OMPI_CHECK_MX_CONFIG],[
|
||||
@ -106,7 +109,7 @@ AC_DEFUN([OMPI_CHECK_MX],[
|
||||
[_OMPI_CHECK_MX_CONFIG($1, [ompi_check_mx_happy="yes"],
|
||||
[ompi_check_mx_happy="no"])])
|
||||
AS_IF([test "$ompi_check_mx_happy" = "yes"],
|
||||
[_OMPI_CHECK_MX_REGISTER_CALLBACK($1, [ompi_check_mx_register="yes"],
|
||||
[_OMPI_CHECK_MX_UNEXP_HANDLER($1, [ompi_check_mx_register="yes"],
|
||||
[ompi_check_mx_register="no"])])
|
||||
|
||||
CPPFLAGS="$ompi_check_mx_$1_save_CPPFLAGS"
|
||||
|
@ -17,18 +17,14 @@
|
||||
*/
|
||||
|
||||
#include "ompi_config.h"
|
||||
#include "opal/util/output.h"
|
||||
#include "opal/util/if.h"
|
||||
#include "ompi/mca/pml/pml.h"
|
||||
#include "ompi/mca/btl/btl.h"
|
||||
|
||||
#include "btl_mx.h"
|
||||
#include "btl_mx_frag.h"
|
||||
#include "btl_mx_proc.h"
|
||||
#include "btl_mx_endpoint.h"
|
||||
#include "ompi/datatype/convertor.h"
|
||||
#include "ompi/mca/mpool/base/base.h"
|
||||
#include "ompi/mca/mpool/mpool.h"
|
||||
#include "opal/prefetch.h"
|
||||
|
||||
/**
|
||||
*
|
||||
@ -114,22 +110,25 @@ int mca_btl_mx_register( struct mca_btl_base_module_t* btl,
|
||||
void* cbdata )
|
||||
{
|
||||
mca_btl_mx_module_t* mx_btl = (mca_btl_mx_module_t*) btl;
|
||||
|
||||
mx_btl->mx_reg[tag].cbfunc = cbfunc;
|
||||
mx_btl->mx_reg[tag].cbdata = cbdata;
|
||||
|
||||
#if !MX_HAVE_UNEXPECTED_HANDLER
|
||||
if( NULL != cbfunc ) {
|
||||
mca_btl_mx_frag_t* frag;
|
||||
mx_return_t mx_return;
|
||||
mx_segment_t mx_segment;
|
||||
int i, rc;
|
||||
|
||||
mx_btl->mx_reg[tag].cbfunc = cbfunc;
|
||||
mx_btl->mx_reg[tag].cbdata = cbdata;
|
||||
/*
|
||||
* Post the receives
|
||||
*/
|
||||
/* Post the receives if there is no unexpected handler */
|
||||
for( i = 0; i < mca_btl_mx_component.mx_max_posted_recv; i++ ) {
|
||||
MCA_BTL_MX_FRAG_ALLOC_EAGER( mx_btl, frag, rc );
|
||||
if( NULL == frag ) {
|
||||
opal_output( 0, "mca_btl_mx_register: unable to allocate more eager fragments\n" );
|
||||
if( 0 == i ) {
|
||||
return OMPI_ERROR;
|
||||
}
|
||||
break; /* some fragments are already registered. Try to continue... */
|
||||
}
|
||||
frag->base.des_dst = frag->segment;
|
||||
frag->base.des_dst_cnt = 1;
|
||||
@ -144,9 +143,14 @@ int mca_btl_mx_register( struct mca_btl_base_module_t* btl,
|
||||
BTL_MX_RECV_MASK,
|
||||
frag, &(frag->mx_request) );
|
||||
if( MX_SUCCESS != mx_return ) {
|
||||
opal_output( 0, "mca_btl_mx_register: mx_irecv failed with status %d (%s)\n",
|
||||
mx_return, mx_strerror(mx_return) );
|
||||
MCA_BTL_MX_FRAG_RETURN( mx_btl, frag );
|
||||
return OMPI_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* MX_HAVE_UNEXPECTED_HANDLER */
|
||||
|
||||
return OMPI_SUCCESS;
|
||||
}
|
||||
@ -166,20 +170,10 @@ mca_btl_base_descriptor_t* mca_btl_mx_alloc( struct mca_btl_base_module_t* btl,
|
||||
mca_btl_mx_frag_t* frag;
|
||||
int rc;
|
||||
|
||||
#if 0
|
||||
if(size <= mx_btl->super.btl_eager_limit) {
|
||||
MCA_BTL_MX_FRAG_ALLOC_EAGER(mx_btl, frag, rc);
|
||||
frag->segment[0].seg_len =
|
||||
size <= mx_btl->super.btl_eager_limit ?
|
||||
size : mx_btl->super.btl_eager_limit ;
|
||||
} else {
|
||||
MCA_BTL_MX_FRAG_ALLOC_USER(mx_btl, frag, rc);
|
||||
frag->segment[0].seg_len =
|
||||
size <= mx_btl->super.btl_max_send_size ?
|
||||
size : mx_btl->super.btl_max_send_size ;
|
||||
if( OPAL_UNLIKELY(NULL == frag) ) {
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
MCA_BTL_MX_FRAG_ALLOC_EAGER(mx_btl, frag, rc);
|
||||
frag->segment[0].seg_len =
|
||||
size <= mx_btl->super.btl_eager_limit ?
|
||||
size : mx_btl->super.btl_eager_limit ;
|
||||
@ -196,7 +190,6 @@ mca_btl_base_descriptor_t* mca_btl_mx_alloc( struct mca_btl_base_module_t* btl,
|
||||
/**
|
||||
* Return a segment
|
||||
*/
|
||||
|
||||
int mca_btl_mx_free( struct mca_btl_base_module_t* btl,
|
||||
mca_btl_base_descriptor_t* des )
|
||||
{
|
||||
@ -237,28 +230,33 @@ mca_btl_mx_prepare_src( struct mca_btl_base_module_t* btl,
|
||||
* to the user memory.
|
||||
*/
|
||||
if( 0 == ompi_convertor_need_buffers(convertor) ) {
|
||||
/**
|
||||
* let the convertor figure out the correct pointer depending
|
||||
* on the data layout
|
||||
*/
|
||||
iov.iov_base = NULL;
|
||||
if( 0 == reserve ) {
|
||||
MCA_BTL_MX_FRAG_ALLOC_USER(btl, frag, rc);
|
||||
if( NULL == frag ) {
|
||||
if( OPAL_UNLIKELY(NULL == frag) ) {
|
||||
return NULL;
|
||||
}
|
||||
max_data = *size;
|
||||
frag->base.des_src_cnt = 1;
|
||||
} else {
|
||||
MCA_BTL_MX_FRAG_ALLOC_EAGER( mx_btl, frag, rc );
|
||||
if( NULL == frag ) {
|
||||
if( OPAL_UNLIKELY(NULL == frag) ) {
|
||||
return NULL;
|
||||
}
|
||||
#if 1
|
||||
frag->base.des_src_cnt = 2;
|
||||
#else
|
||||
frag->base.des_src_cnt = 1;
|
||||
iov.iov_base = (void*)((unsigned char*)frag->segment[0].seg_addr.pval + reserve);
|
||||
#endif
|
||||
}
|
||||
/**
|
||||
* let the convertor figure out the correct pointer depending
|
||||
* on the data layout
|
||||
*/
|
||||
iov.iov_base = NULL;
|
||||
} else {
|
||||
MCA_BTL_MX_FRAG_ALLOC_EAGER( mx_btl, frag, rc );
|
||||
if( NULL == frag ) {
|
||||
if( OPAL_UNLIKELY(NULL == frag) ) {
|
||||
return NULL;
|
||||
}
|
||||
frag->base.des_src_cnt = 1;
|
||||
@ -279,9 +277,6 @@ mca_btl_mx_prepare_src( struct mca_btl_base_module_t* btl,
|
||||
frag->segment[1].seg_addr.pval = iov.iov_base;
|
||||
}
|
||||
frag->base.des_src = frag->segment;
|
||||
frag->base.des_dst = NULL;
|
||||
frag->base.des_dst_cnt = 0;
|
||||
frag->base.des_flags = 0;
|
||||
return &frag->base;
|
||||
}
|
||||
|
||||
@ -360,6 +355,8 @@ static int mca_btl_mx_put( struct mca_btl_base_module_t* btl,
|
||||
if( MCA_BTL_MX_CONNECTED != ((mca_btl_mx_endpoint_t*)endpoint)->status ) {
|
||||
if( MCA_BTL_MX_NOT_REACHEABLE == ((mca_btl_mx_endpoint_t*)endpoint)->status )
|
||||
return OMPI_ERROR;
|
||||
if( MCA_BTL_MX_CONNECTION_PENDING == ((mca_btl_mx_endpoint_t*)endpoint)->status )
|
||||
return OMPI_ERR_OUT_OF_RESOURCE;
|
||||
if( OMPI_SUCCESS != mca_btl_mx_proc_connect( (mca_btl_mx_endpoint_t*)endpoint ) )
|
||||
return OMPI_ERROR;
|
||||
}
|
||||
@ -409,6 +406,8 @@ int mca_btl_mx_send( struct mca_btl_base_module_t* btl,
|
||||
if( MCA_BTL_MX_CONNECTED != ((mca_btl_mx_endpoint_t*)endpoint)->status ) {
|
||||
if( MCA_BTL_MX_NOT_REACHEABLE == ((mca_btl_mx_endpoint_t*)endpoint)->status )
|
||||
return OMPI_ERROR;
|
||||
if( MCA_BTL_MX_CONNECTION_PENDING == ((mca_btl_mx_endpoint_t*)endpoint)->status )
|
||||
return OMPI_ERR_OUT_OF_RESOURCE;
|
||||
if( OMPI_SUCCESS != mca_btl_mx_proc_connect( (mca_btl_mx_endpoint_t*)endpoint ) )
|
||||
return OMPI_ERROR;
|
||||
}
|
||||
|
@ -29,13 +29,12 @@
|
||||
/* Open MPI includes */
|
||||
#include "ompi/class/ompi_free_list.h"
|
||||
#include "ompi/class/ompi_bitmap.h"
|
||||
#include "opal/util/output.h"
|
||||
#include "opal/event/event.h"
|
||||
#include "ompi/mca/pml/pml.h"
|
||||
#include "ompi/mca/btl/btl.h"
|
||||
#include "ompi/mca/btl/base/base.h"
|
||||
#include "opal/util/output.h"
|
||||
#include "ompi/mca/mpool/mpool.h"
|
||||
#include "ompi/mca/btl/btl.h"
|
||||
|
||||
#include "myriexpress.h"
|
||||
|
||||
@ -285,41 +284,6 @@ mca_btl_mx_prepare_dst( struct mca_btl_base_module_t* btl,
|
||||
size_t reserve,
|
||||
size_t* size );
|
||||
|
||||
#define MCA_BTL_MX_PROGRESS(mx_btl, mx_status) \
|
||||
do { \
|
||||
mca_btl_mx_frag_t* __frag = mx_status.context; \
|
||||
mx_segment_t __mx_segment; \
|
||||
mx_return_t __mx_return; \
|
||||
\
|
||||
if( NULL != __frag ) { \
|
||||
if( 0xff == __frag->tag ) { /* it's a send */ \
|
||||
/* call the completion callback */ \
|
||||
__frag->base.des_cbfunc( &(mx_btl->super), __frag->endpoint, \
|
||||
&(__frag->base), OMPI_SUCCESS ); \
|
||||
} else { /* and this one is a receive */ \
|
||||
mca_btl_base_recv_reg_t* __reg; \
|
||||
\
|
||||
__reg = &(mx_btl->mx_reg[__frag->tag]); \
|
||||
__frag->base.des_dst->seg_len = mx_status.msg_length; \
|
||||
__reg->cbfunc( &(mx_btl->super), __frag->tag, &(__frag->base), \
|
||||
__reg->cbdata ); \
|
||||
/** \
|
||||
* The upper level extract the data from the fragment. \
|
||||
* Now we can register the fragment \
|
||||
* again with the MX BTL. \
|
||||
*/ \
|
||||
__mx_segment.segment_ptr = __frag->base.des_dst->seg_addr.pval; \
|
||||
__mx_segment.segment_length = mca_btl_mx_module.super.btl_eager_limit; \
|
||||
__mx_return = mx_irecv( mx_btl->mx_endpoint, &__mx_segment, 1, \
|
||||
(uint64_t)__frag->tag, BTL_MX_RECV_MASK, \
|
||||
__frag, &(__frag->mx_request) ); \
|
||||
if( MX_SUCCESS != __mx_return ) { \
|
||||
opal_output( 0, "Fail to re-register a fragment with the MX NIC ...\n" ); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#if defined(c_plusplus) || defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
@ -18,24 +18,23 @@
|
||||
|
||||
|
||||
#include "ompi_config.h"
|
||||
#include "ompi/constants.h"
|
||||
#include "opal/event/event.h"
|
||||
#include "opal/prefetch.h"
|
||||
#include "opal/util/opal_environ.h"
|
||||
#include "opal/util/if.h"
|
||||
#include "opal/util/argv.h"
|
||||
#include "opal/util/output.h"
|
||||
#include "ompi/mca/pml/pml.h"
|
||||
#include "ompi/mca/btl/btl.h"
|
||||
#include "ompi/constants.h"
|
||||
|
||||
#include "opal/mca/base/mca_base_param.h"
|
||||
#include "ompi/mca/pml/base/pml_base_module_exchange.h"
|
||||
#include "orte/mca/errmgr/errmgr.h"
|
||||
#include "ompi/mca/mpool/base/base.h"
|
||||
#include "ompi/mca/pml/base/pml_base_module_exchange.h"
|
||||
#include "ompi/mca/btl/base/btl_base_error.h"
|
||||
#include "btl_mx.h"
|
||||
#include "btl_mx_frag.h"
|
||||
#include "btl_mx_endpoint.h"
|
||||
#include "ompi/mca/btl/base/base.h"
|
||||
#include "ompi/mca/btl/base/btl_base_error.h"
|
||||
|
||||
#if MX_HAVE_UNEXPECTED_HANDLER
|
||||
#include "mx_extensions.h"
|
||||
#endif /* MX_HAVE_UNEXPECTED_HANDLER */
|
||||
|
||||
extern char** environ;
|
||||
|
||||
@ -133,7 +132,7 @@ int mca_btl_mx_component_open(void)
|
||||
false, false, 50, (int*) &mca_btl_mx_module.super.btl_exclusivity );
|
||||
mca_base_param_reg_int( (mca_base_component_t*)&mca_btl_mx_component, "first_frag_size",
|
||||
"Size of the first fragment for the rendez-vous protocol over MX",
|
||||
true, true, 16*1024 - 20, &tmp);
|
||||
false, false, 16*1024 - 20, &tmp);
|
||||
mca_btl_mx_module.super.btl_eager_limit = tmp;
|
||||
mca_base_param_reg_int( (mca_base_component_t*)&mca_btl_mx_component, "min_send_size",
|
||||
"Minimum send fragment size ...",
|
||||
@ -179,11 +178,51 @@ int mca_btl_mx_component_close(void)
|
||||
return OMPI_SUCCESS;
|
||||
}
|
||||
|
||||
#if MX_HAVE_UNEXPECTED_HANDLER
|
||||
/**
|
||||
* In order to avoid useless memcpy, the unexpected handler will be called
|
||||
* by the MX library before doing any match in the MX internal queues. Here
|
||||
* we have a chance to match the message using our own matching logic from
|
||||
* the PML. If the match is realized, we will return MX_RECV_FINISHED (the
|
||||
* MX request will vanish in the MX library). If the match do not succeed
|
||||
* MX_RECV_CONTINUE have to be returned and the MX library will do the
|
||||
* match itself.
|
||||
*/
|
||||
static mx_unexp_handler_action_t
|
||||
mca_btl_mx_unexpected_handler( void *context, mx_endpoint_addr_t source,
|
||||
uint64_t match_value, uint32_t length,
|
||||
void * data_if_available )
|
||||
{
|
||||
mca_btl_mx_module_t* mx_btl = (mca_btl_mx_module_t*)context;
|
||||
mca_btl_base_recv_reg_t* reg;
|
||||
mca_btl_base_tag_t tag;
|
||||
mca_btl_base_descriptor_t descriptor;
|
||||
mca_btl_base_segment_t segment;
|
||||
|
||||
/*opal_output( 0, "Get unexpected handler context %p source %lld match_value %lld\n"
|
||||
"\tlength %d data %p\n", context, source.stuff[0], match_value, length,
|
||||
data_if_available );*/
|
||||
if( match_value > 16 )
|
||||
return MX_RECV_CONTINUE;
|
||||
|
||||
tag = match_value & 0xff;
|
||||
assert( tag < 16 );
|
||||
reg = &(mx_btl->mx_reg[tag]);
|
||||
|
||||
segment.seg_addr.pval = data_if_available;
|
||||
segment.seg_len = length;
|
||||
descriptor.des_dst = &segment;
|
||||
descriptor.des_dst_cnt = 1;
|
||||
reg->cbfunc( &(mx_btl->super), tag, &descriptor, reg->cbdata );
|
||||
|
||||
return MX_RECV_FINISHED;
|
||||
}
|
||||
#endif /* MX_HAVE_UNEXPECTED_HANDLER */
|
||||
|
||||
/*
|
||||
* Create and intialize an MX PTL module, where each module
|
||||
* represents a specific NIC.
|
||||
*/
|
||||
|
||||
static mca_btl_mx_module_t* mca_btl_mx_create(uint64_t addr)
|
||||
{
|
||||
mca_btl_mx_module_t* mx_btl;
|
||||
@ -207,7 +246,8 @@ static mca_btl_mx_module_t* mca_btl_mx_create(uint64_t addr)
|
||||
mca_btl_mx_component.mx_filter,
|
||||
NULL, 0, &mx_btl->mx_endpoint);
|
||||
if(status != MX_SUCCESS) {
|
||||
opal_output(0, "mca_btl_mx_init: mx_open_endpoint() failed with status=%d\n", status);
|
||||
opal_output( 0, "mca_btl_mx_init: mx_open_endpoint() failed with status %d (%s)\n",
|
||||
status, mx_strerror(status) );
|
||||
mca_btl_mx_finalize( &mx_btl->super );
|
||||
return NULL;
|
||||
}
|
||||
@ -215,11 +255,21 @@ static mca_btl_mx_module_t* mca_btl_mx_create(uint64_t addr)
|
||||
/* query the endpoint address */
|
||||
if((status = mx_get_endpoint_addr( mx_btl->mx_endpoint,
|
||||
&mx_btl->mx_endpoint_addr)) != MX_SUCCESS) {
|
||||
opal_output(0, "mca_btl_mx_init: mx_get_endpoint_addr() failed with status=%d\n", status);
|
||||
opal_output( 0, "mca_btl_mx_init: mx_get_endpoint_addr() failed with status %d (%s)\n",
|
||||
status, mx_strerror(status) );
|
||||
mca_btl_mx_finalize( &mx_btl->super );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if MX_HAVE_UNEXPECTED_HANDLER
|
||||
status = mx_register_unexp_handler( mx_btl->mx_endpoint, mca_btl_mx_unexpected_handler,
|
||||
(void*)mx_btl );
|
||||
if( MX_SUCCESS != status ) {
|
||||
opal_output( 0, "mca_btl_mx_init: mx_register_unexp_handler() failed with status %d (%s)\n",
|
||||
status, mx_strerror(status) );
|
||||
mca_btl_mx_finalize( &mx_btl->super );
|
||||
return NULL;
|
||||
}
|
||||
#endif /* MX_HAVE_UNEXPECTED_HANDLER */
|
||||
return mx_btl;
|
||||
}
|
||||
|
||||
@ -258,6 +308,8 @@ mca_btl_base_module_t** mca_btl_mx_component_init(int *num_btl_modules,
|
||||
opal_setenv( "MX_DISABLE_SHMEM", "1", true, &environ );
|
||||
if( 0 == mca_btl_mx_component.mx_support_self )
|
||||
opal_setenv( "MX_DISABLE_SELF", "1", true, &environ );
|
||||
/* Force the long pipeline (up to 4Kb fragments) */
|
||||
opal_setenv( "MX_PIPELINE_LOG", "0", true, &environ );
|
||||
|
||||
/* First check if MX is available ... */
|
||||
if( MX_SUCCESS != (status = mx_init()) ) {
|
||||
@ -306,7 +358,8 @@ mca_btl_base_module_t** mca_btl_mx_component_init(int *num_btl_modules,
|
||||
/* get the number of card available on the system */
|
||||
if( (status = mx_get_info( NULL, MX_NIC_COUNT, NULL, 0,
|
||||
&mca_btl_mx_component.mx_num_btls, sizeof(uint32_t))) != MX_SUCCESS ) {
|
||||
opal_output(0, "mca_btl_mx_component_init: mx_get_info(MX_NIC_COUNT) failed with status=%d\n", status);
|
||||
opal_output( 0, "mca_btl_mx_component_init: mx_get_info(MX_NIC_COUNT) failed with status %d(%s)\n",
|
||||
status, mx_strerror(status) );
|
||||
mca_pml_base_modex_send(&mca_btl_mx_component.super.btl_version,
|
||||
NULL, 0);
|
||||
return NULL;
|
||||
@ -393,40 +446,32 @@ mca_btl_base_module_t** mca_btl_mx_component_init(int *num_btl_modules,
|
||||
/*
|
||||
* MX component progress.
|
||||
*/
|
||||
int mca_btl_mx_component_progress()
|
||||
int mca_btl_mx_component_progress(void)
|
||||
{
|
||||
int32_t num_progressed = 0, i;
|
||||
mx_status_t mx_status;
|
||||
mx_return_t mx_return;
|
||||
mx_request_t mx_request;
|
||||
mca_btl_mx_frag_t* frag;
|
||||
|
||||
for( i = 0; i < mca_btl_mx_component.mx_num_btls; i++ ) {
|
||||
mca_btl_mx_module_t* mx_btl = mca_btl_mx_component.mx_btls[i];
|
||||
uint32_t mx_result = 0;
|
||||
|
||||
/* pre-post receive */
|
||||
#if 0
|
||||
if( mx_btl->mx_recvs_posted == 0 ) {
|
||||
OPAL_THREAD_ADD32( &mx_btl->mx_recvs_posted, 1 );
|
||||
MCA_BTL_MX_POST( mx_btl, frag );
|
||||
}
|
||||
#endif
|
||||
|
||||
/*if( mx_btl->mx_posted_request ) { */
|
||||
mx_return = mx_ipeek( mx_btl->mx_endpoint, &mx_request, &mx_result );
|
||||
if( mx_return != MX_SUCCESS ) {
|
||||
opal_output(0, "mca_btl_mx_component_progress: mx_ipeek() failed with status %d\n",
|
||||
mx_return);
|
||||
if( OPAL_UNLIKELY(mx_return != MX_SUCCESS) ) {
|
||||
opal_output( 0, "mca_btl_mx_component_progress: mx_ipeek() failed with status %d (%s)\n",
|
||||
mx_return, mx_strerror(mx_return) );
|
||||
continue;
|
||||
}
|
||||
if( mx_result == 0 ) {
|
||||
if( OPAL_LIKELY(mx_result == 0) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
mx_return = mx_test( mx_btl->mx_endpoint, &mx_request, &mx_status, &mx_result);
|
||||
if( mx_return != MX_SUCCESS ) {
|
||||
opal_output(0, "mca_btl_mx_progress: mx_test() failed with status=%dn",
|
||||
mx_return);
|
||||
if( OPAL_UNLIKELY(mx_return != MX_SUCCESS) ) {
|
||||
opal_output(0, "mca_btl_mx_progress: mx_test() failed with status %d (%s)\n",
|
||||
mx_return, mx_strerror(mx_return));
|
||||
continue;
|
||||
}
|
||||
/* on the mx_status we have now the pointer attached to the request.
|
||||
@ -434,7 +479,38 @@ int mca_btl_mx_component_progress()
|
||||
* status we have the status of the operation, so we know what we
|
||||
* are supposed to do next.
|
||||
*/
|
||||
MCA_BTL_MX_PROGRESS(mx_btl, mx_status);
|
||||
frag = mx_status.context;
|
||||
if( NULL != frag ) {
|
||||
if( 0xff == frag->tag ) { /* it's a send */
|
||||
/* call the completion callback */
|
||||
frag->base.des_cbfunc( &(mx_btl->super), frag->endpoint,
|
||||
&(frag->base), OMPI_SUCCESS );
|
||||
#if !MX_HAVE_UNEXPECTED_HANDLER
|
||||
} else { /* and this one is a receive */
|
||||
mca_btl_base_recv_reg_t* reg;
|
||||
mx_segment_t mx_segment;
|
||||
|
||||
reg = &(mx_btl->mx_reg[frag->tag]);
|
||||
frag->base.des_dst->seg_len = mx_status.msg_length;
|
||||
reg->cbfunc( &(mx_btl->super), frag->tag, &(frag->base),
|
||||
reg->cbdata );
|
||||
/**
|
||||
* The upper level extract the data from the fragment.
|
||||
* Now we can register the fragment
|
||||
* again with the MX BTL.
|
||||
*/
|
||||
mx_segment.segment_ptr = frag->base.des_dst->seg_addr.pval;
|
||||
mx_segment.segment_length = mca_btl_mx_module.super.btl_eager_limit;
|
||||
mx_return = mx_irecv( mx_btl->mx_endpoint, &mx_segment, 1,
|
||||
(uint64_t)frag->tag, BTL_MX_RECV_MASK,
|
||||
frag, &(frag->mx_request) );
|
||||
if( MX_SUCCESS != mx_return ) {
|
||||
opal_output( 0, "Fail to re-register a fragment with the MX NIC ... (%s)\n",
|
||||
mx_strerror(mx_return) );
|
||||
}
|
||||
#endif /* !MX_HAVE_UNEXPECTED_HANDLER */
|
||||
}
|
||||
}
|
||||
num_progressed++;
|
||||
}
|
||||
return num_progressed;
|
||||
|
@ -34,7 +34,8 @@ extern "C" {
|
||||
|
||||
#define MCA_BTL_MX_NOT_CONNECTED 0x0000
|
||||
#define MCA_BTL_MX_NOT_REACHEABLE 0x0001
|
||||
#define MCA_BTL_MX_CONNECTED 0x0002
|
||||
#define MCA_BTL_MX_CONNECTION_PENDING 0x0002
|
||||
#define MCA_BTL_MX_CONNECTED 0x0004
|
||||
|
||||
/**
|
||||
* Structure used to publish MX information to peers
|
||||
|
@ -180,6 +180,8 @@ int mca_btl_mx_proc_connect( mca_btl_mx_endpoint_t* module_endpoint )
|
||||
mx_endpoint_addr_t mx_remote_addr;
|
||||
mca_btl_mx_proc_t* module_proc = module_endpoint->endpoint_proc;
|
||||
|
||||
module_endpoint->status = MCA_BTL_MX_CONNECTION_PENDING;
|
||||
|
||||
for( i = module_proc->proc_addr_index; i < module_proc->mx_peers_count; i++ ) {
|
||||
|
||||
retry_connect:
|
||||
@ -210,6 +212,7 @@ int mca_btl_mx_proc_connect( mca_btl_mx_endpoint_t* module_endpoint )
|
||||
}
|
||||
|
||||
if( i == module_proc->mx_peers_count ) { /* no available connection */
|
||||
module_endpoint->status = MCA_BTL_MX_NOT_REACHEABLE;
|
||||
return OMPI_ERROR;
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
# University Research and Technology
|
||||
# Corporation. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
# Copyright (c) 2004-2006 The University of Tennessee and The University
|
||||
# of Tennessee Research Foundation. All rights
|
||||
# reserved.
|
||||
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user