From 47b34ad8a08aee06205f94e54c16ade3dae51e54 Mon Sep 17 00:00:00 2001 From: Edgar Gabriel Date: Tue, 12 Mar 2024 07:18:18 -0700 Subject: [PATCH] smsc/accelerator: add new smsc component - add smsc component based on the accelerator API IPC functionality. - adjust smsc base selection logic to enable a pass-through mechanism with the new smsc/accelerator component Signed-off-by: Edgar Gabriel --- opal/mca/btl/sm/btl_sm_component.c | 4 + opal/mca/smsc/accelerator/Makefile.am | 58 +++++ opal/mca/smsc/accelerator/post_configure.sh | 1 + opal/mca/smsc/accelerator/smsc_accelerator.h | 34 +++ .../accelerator/smsc_accelerator_component.c | 133 +++++++++++ .../accelerator/smsc_accelerator_internal.h | 70 ++++++ .../accelerator/smsc_accelerator_module.c | 225 ++++++++++++++++++ opal/mca/smsc/base/base.h | 9 + opal/mca/smsc/base/smsc_base_frame.c | 58 +++-- opal/mca/smsc/smsc.h | 2 + 10 files changed, 580 insertions(+), 14 deletions(-) create mode 100644 opal/mca/smsc/accelerator/Makefile.am create mode 100644 opal/mca/smsc/accelerator/post_configure.sh create mode 100644 opal/mca/smsc/accelerator/smsc_accelerator.h create mode 100644 opal/mca/smsc/accelerator/smsc_accelerator_component.c create mode 100644 opal/mca/smsc/accelerator/smsc_accelerator_internal.h create mode 100644 opal/mca/smsc/accelerator/smsc_accelerator_module.c diff --git a/opal/mca/btl/sm/btl_sm_component.c b/opal/mca/btl/sm/btl_sm_component.c index 0eb00625efb..9815adf8d4e 100644 --- a/opal/mca/btl/sm/btl_sm_component.c +++ b/opal/mca/btl/sm/btl_sm_component.c @@ -340,6 +340,10 @@ mca_btl_sm_component_init(int *num_btls, bool enable_progress_threads, bool enab mca_btl_sm.super.btl_get = mca_btl_sm_get; mca_btl_sm.super.btl_put = mca_btl_sm_put; + if (mca_smsc_base_has_feature(MCA_SMSC_FEATURE_ACCELERATOR)) { + mca_btl_sm.super.btl_flags |= MCA_BTL_FLAGS_ACCELERATOR_GET; + } + mca_btl_sm.super.btl_bandwidth = 40000; /* Mbs */ if (mca_smsc_base_has_feature(MCA_SMSC_FEATURE_CAN_MAP)) { diff --git a/opal/mca/smsc/accelerator/Makefile.am b/opal/mca/smsc/accelerator/Makefile.am new file mode 100644 index 00000000000..145fea1f53c --- /dev/null +++ b/opal/mca/smsc/accelerator/Makefile.am @@ -0,0 +1,58 @@ +# +# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana +# University Research and Technology +# Corporation. All rights reserved. +# Copyright (c) 2004-2009 The University of Tennessee and The University +# of Tennessee Research Foundation. All rights +# reserved. +# Copyright (c) 2004-2009 High Performance Computing Center Stuttgart, +# University of Stuttgart. All rights reserved. +# Copyright (c) 2004-2005 The Regents of the University of California. +# All rights reserved. +# Copyright (c) 2009-2014 Cisco Systems, Inc. All rights reserved. +# Copyright (c) 2011-2014 Los Alamos National Security, LLC. All rights +# reserved. +# Copyright (c) 2017 IBM Corporation. All rights reserved. +# Copyright (c) 2020-2021 Google, LLC. All rights reserved. +# Copyright (c) 2024 Advanced Micro Devices, Inc. All Rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +EXTRA_DIST = post_configure.sh + +AM_CPPFLAGS = $(smsc_accelerator_CPPFLAGS) + + +libmca_smsc_accelerator_la_sources = \ + smsc_accelerator_component.c \ + smsc_accelerator_module.c \ + smsc_accelerator_internal.h \ + smsc_accelerator.h + +# Make the output library in this directory, and name it either +# mca__.la (for DSO builds) or libmca__.la +# (for static builds). + +if MCA_BUILD_opal_smsc_accelerator_DSO +component_noinst = +component_install = mca_smsc_accelerator.la +else +component_noinst = libmca_smsc_accelerator.la +component_install = +endif + +mcacomponentdir = $(opallibdir) +mcacomponent_LTLIBRARIES = $(component_install) +mca_smsc_accelerator_la_SOURCES = $(libmca_smsc_accelerator_la_sources) +mca_smsc_accelerator_la_LDFLAGS = -module -avoid-version $(smsc_accelerator_LDFLAGS) +mca_smsc_accelerator_la_LIBADD = $(top_builddir)/opal/lib@OPAL_LIB_NAME@.la \ + $(smsc_accelerator_LIBS) + +noinst_LTLIBRARIES = $(component_noinst) +libmca_smsc_accelerator_la_SOURCES = $(libmca_smsc_accelerator_la_sources) +libmca_smsc_accelerator_la_LIBADD = $(smsc_accelerator_LIBS) +libmca_smsc_accelerator_la_LDFLAGS = -module -avoid-version $(smsc_accelerator_LDFLAGS) diff --git a/opal/mca/smsc/accelerator/post_configure.sh b/opal/mca/smsc/accelerator/post_configure.sh new file mode 100644 index 00000000000..eaa00df0d92 --- /dev/null +++ b/opal/mca/smsc/accelerator/post_configure.sh @@ -0,0 +1 @@ +DIRECT_CALL_HEADER="opal/mca/smsc/accelerator/smsc_accelerator.h" diff --git a/opal/mca/smsc/accelerator/smsc_accelerator.h b/opal/mca/smsc/accelerator/smsc_accelerator.h new file mode 100644 index 00000000000..c7ed72b029e --- /dev/null +++ b/opal/mca/smsc/accelerator/smsc_accelerator.h @@ -0,0 +1,34 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2024 Advanced Micro Devices, Inc. All Rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#ifndef OPAL_MCA_SMSC_ACCELERATOR_H +#define OPAL_MCA_SMSC_ACCELERATOR_H + +#include "opal_config.h" + +#include "opal/mca/smsc/smsc.h" + +mca_smsc_endpoint_t *mca_smsc_accelerator_get_endpoint(opal_proc_t *peer_proc); +void mca_smsc_accelerator_return_endpoint(mca_smsc_endpoint_t *endpoint); + +int mca_smsc_accelerator_copy_to(mca_smsc_endpoint_t *endpoint, void *local_address, void *remote_address, + size_t size, void *reg_handle); + +int mca_smsc_accelerator_copy_from(mca_smsc_endpoint_t *endpoint, void *local_address, + void *remote_address, size_t size, void *reg_handle); + +void *mca_smsc_accelerator_map_peer_region(mca_smsc_endpoint_t *endpoint, uint64_t flags, + void *remote_ptr, size_t size, void **local_ptr); +void mca_smsc_accelerator_unmap_peer_region(void *ctx); + +void *mca_smsc_accelerator_register_region(void *local_address, size_t size); +void mca_smsc_accelerator_deregister_region(void *reg_data); + +#endif /* OPAL_MCA_SMSC_ACCELERATOR__H */ diff --git a/opal/mca/smsc/accelerator/smsc_accelerator_component.c b/opal/mca/smsc/accelerator/smsc_accelerator_component.c new file mode 100644 index 00000000000..85df3bf2dae --- /dev/null +++ b/opal/mca/smsc/accelerator/smsc_accelerator_component.c @@ -0,0 +1,133 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2024 Advanced Micro Devices, Inc. All Rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ +#include "opal_config.h" + +#include "opal/mca/smsc/base/base.h" +#include "opal/mca/smsc/accelerator/smsc_accelerator_internal.h" +#include "opal/mca/accelerator/accelerator.h" +#include "opal/mca/accelerator/base/base.h" + +static int mca_smsc_accelerator_component_register(void); +static int mca_smsc_accelerator_component_open(void); +static int mca_smsc_accelerator_component_close(void); +static int mca_smsc_accelerator_component_query(void); +static mca_smsc_module_t *mca_smsc_accelerator_component_enable(void); + +#define MCA_SMSC_ACCELERATOR_DEFAULT_PRIORITY 80 +static const int mca_smsc_accelerator_default_priority = MCA_SMSC_ACCELERATOR_DEFAULT_PRIORITY; + +mca_smsc_accelerator_component_t mca_smsc_accelerator_component = { + .super = { + .smsc_version = { + MCA_SMSC_DEFAULT_VERSION("accelerator"), + .mca_open_component = mca_smsc_accelerator_component_open, + .mca_close_component = mca_smsc_accelerator_component_close, + .mca_register_component_params = mca_smsc_accelerator_component_register, + }, + .priority = MCA_SMSC_ACCELERATOR_DEFAULT_PRIORITY, + .query = mca_smsc_accelerator_component_query, + .enable = mca_smsc_accelerator_component_enable, + }, +}; + +static int mca_smsc_accelerator_component_register(void) +{ + mca_smsc_base_register_default_params(&mca_smsc_accelerator_component.super, + mca_smsc_accelerator_default_priority); + return OPAL_SUCCESS; +} + +static int mca_smsc_accelerator_component_open(void) +{ + return OPAL_SUCCESS; +} + +static int mca_smsc_accelerator_component_close(void) +{ + if (mca_smsc_accelerator_module.rcache) { + (void) mca_rcache_base_module_destroy(mca_smsc_accelerator_module.rcache); + mca_smsc_accelerator_module.rcache = NULL; + } + + return OPAL_SUCCESS; +} + +static int mca_smsc_accelerator_component_query(void) +{ + if (0 == strcmp(opal_accelerator_base_selected_component.base_version.mca_component_name, + "null")) { + opal_output_verbose(10, opal_smsc_base_framework.framework_output, + "smsc:accelerator:component_query: accelerator component is null: disqualifying myself"); + return OPAL_ERROR; + } + + if (!opal_accelerator.is_ipc_enabled()) { + opal_output_verbose(10, opal_smsc_base_framework.framework_output, + "smsc:accelerator:component_query: accelerator component does not have support for IPC operations: disqualifying myself"); + return OPAL_ERROR; + } + + return OPAL_SUCCESS; +} + + +static int mca_smsc_accelerator_reg(void *reg_data, void *local_address, size_t size, + mca_rcache_base_registration_t *reg_handle) +{ + mca_smsc_accelerator_registration_handle_t *reg = (mca_smsc_accelerator_registration_handle_t *) reg_handle; + int ret; + + ret = opal_accelerator.get_ipc_handle (mca_smsc_accelerator_module.device_id, local_address, + ®->ipc_handle); + memcpy (reg->data.handle.accelerator, reg->ipc_handle.handle, SMSC_ACCELERATOR_HANDLE_SIZE); + if (OPAL_SUCCESS != ret ) { + return OPAL_ERROR; + } + + return OPAL_SUCCESS; +} + +static int mca_smsc_accelerator_dereg(void *reg_data, mca_rcache_base_registration_t *reg_handle) +{ + mca_smsc_accelerator_registration_handle_t *reg = (mca_smsc_accelerator_registration_handle_t *) reg_handle; + + OBJ_DESTRUCT(&(reg->ipc_handle)); + return OPAL_SUCCESS; +} + +static mca_smsc_module_t *mca_smsc_accelerator_component_enable(void) +{ + if (0 > mca_smsc_accelerator_component.super.priority) { + return NULL; + } + + mca_rcache_base_resources_t rcache_resources = {.cache_name = "smsc_accelerator", + .reg_data = NULL, + .sizeof_reg = sizeof( + mca_smsc_accelerator_registration_handle_t), + .register_mem = mca_smsc_accelerator_reg, + .deregister_mem = mca_smsc_accelerator_dereg}; + + mca_smsc_accelerator_module.rcache = mca_rcache_base_module_create("grdma", NULL, &rcache_resources); + if (NULL == mca_smsc_accelerator_module.rcache) { + return NULL; + } + + /* Not set. Will initialize later */ + mca_smsc_accelerator_module.device_id = MCA_ACCELERATOR_NO_DEVICE_ID; + + mca_smsc_accelerator_module.prev_smsc = mca_smsc; + if ((NULL != mca_smsc_accelerator_module.prev_smsc) && + (mca_smsc_accelerator_module.prev_smsc->features & MCA_SMSC_FEATURE_CAN_MAP)) { + mca_smsc_accelerator_module.super.features |= MCA_SMSC_FEATURE_CAN_MAP; + } + + return &mca_smsc_accelerator_module.super; +} diff --git a/opal/mca/smsc/accelerator/smsc_accelerator_internal.h b/opal/mca/smsc/accelerator/smsc_accelerator_internal.h new file mode 100644 index 00000000000..fde0a503aab --- /dev/null +++ b/opal/mca/smsc/accelerator/smsc_accelerator_internal.h @@ -0,0 +1,70 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2021 Google, Inc. All rights reserved. + * Copyright (c) 2024 Advanced Micro Devices, Inc. All Rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#ifndef OPAL_MCA_SMSC_ACCELERATOR_INTERNAL_H +#define OPAL_MCA_SMSC_ACCELERATOR_INTERNAL_H + +#include "opal_config.h" + +#include "opal/mca/rcache/base/base.h" +#include "opal/mca/rcache/rcache.h" +#include "opal/mca/smsc/accelerator/smsc_accelerator.h" +#include "opal/mca/accelerator/accelerator.h" + +#define SMSC_ACCELERATOR_HANDLE_SIZE IPC_MAX_HANDLE_SIZE +struct mca_smsc_accelerator_registration_data_t { + uint64_t base_addr; + union { + uint8_t accelerator[SMSC_ACCELERATOR_HANDLE_SIZE]; + void* host; + } handle; +}; +typedef struct mca_smsc_accelerator_registration_data_t mca_smsc_accelerator_registration_data_t; + +struct mca_smsc_accelerator_registration_handle_t { + mca_rcache_base_registration_t base; + mca_smsc_accelerator_registration_data_t data; + opal_accelerator_ipc_handle_t ipc_handle; +}; +typedef struct mca_smsc_accelerator_registration_handle_t mca_smsc_accelerator_registration_handle_t; +OBJ_CLASS_DECLARATION(mca_smsc_accelerator_registration_handle_t); + +#define MCA_SMSC_ACCELERATOR_REG_DATA_TO_HANDLE(data_ptr) \ + ((mca_smsc_accelerator_registration_handle_t *) ((uintptr_t) data_ptr \ + - offsetof(mca_smsc_accelerator_registration_handle_t, \ + data))) + + +struct mca_smsc_accelerator_endpoint_t { + mca_smsc_endpoint_t super; + mca_smsc_endpoint_t *prev_endpoint; + mca_rcache_base_module_t *rcache; +}; +typedef struct mca_smsc_accelerator_endpoint_t mca_smsc_accelerator_endpoint_t; +OBJ_CLASS_DECLARATION(mca_smsc_accelerator_endpoint_t); + +struct mca_smsc_accelerator_component_t { + mca_smsc_component_t super; +}; +typedef struct mca_smsc_accelerator_component_t mca_smsc_accelerator_component_t; + +struct mca_smsc_accelerator_module_t { + mca_smsc_module_t super; + mca_smsc_module_t *prev_smsc; + mca_rcache_base_module_t *rcache; + int device_id; +}; +typedef struct mca_smsc_accelerator_module_t mca_smsc_accelerator_module_t; + +extern mca_smsc_accelerator_module_t mca_smsc_accelerator_module; +extern mca_smsc_accelerator_component_t mca_smsc_accelerator_component; + +#endif /* OPAL_MCA_SMSC_ACCELERATOR_INTERNAL_H */ diff --git a/opal/mca/smsc/accelerator/smsc_accelerator_module.c b/opal/mca/smsc/accelerator/smsc_accelerator_module.c new file mode 100644 index 00000000000..3b930663b66 --- /dev/null +++ b/opal/mca/smsc/accelerator/smsc_accelerator_module.c @@ -0,0 +1,225 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ +/* + * Copyright (c) 2024 Advanced Micro Devices, Inc. All Rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#include "opal_config.h" + +#include "opal/include/opal/align.h" +#include "opal/mca/rcache/rcache.h" +#include "opal/mca/rcache/base/base.h" +#include "opal/mca/accelerator/accelerator.h" +#include "opal/mca/accelerator/base/base.h" +#include "opal/mca/smsc/base/base.h" +#include "opal/mca/smsc/accelerator/smsc_accelerator.h" +#include "opal/mca/smsc/accelerator/smsc_accelerator_internal.h" +#include "opal/include/opal/opal_gpu.h" + +OBJ_CLASS_INSTANCE(mca_smsc_accelerator_endpoint_t, opal_object_t, NULL, NULL); + +mca_smsc_endpoint_t *mca_smsc_accelerator_get_endpoint(opal_proc_t *peer_proc) +{ + mca_smsc_accelerator_endpoint_t *endpoint = OBJ_NEW(mca_smsc_accelerator_endpoint_t); + if (OPAL_UNLIKELY(NULL == endpoint)) { + return NULL; + } + + if (NULL != mca_smsc_accelerator_module.prev_smsc) { + endpoint->prev_endpoint = mca_smsc_accelerator_module.prev_smsc->get_endpoint(peer_proc); + } + + endpoint->rcache = mca_rcache_base_module_create("rgpusm", NULL, NULL); + + return &endpoint->super; +} + +void mca_smsc_accelerator_return_endpoint(mca_smsc_endpoint_t *endpoint) +{ + mca_smsc_accelerator_endpoint_t *ep = (mca_smsc_accelerator_endpoint_t *)endpoint; + + if ((NULL != mca_smsc_accelerator_module.prev_smsc) && + (NULL != ep->prev_endpoint)) { + mca_smsc_accelerator_module.prev_smsc->return_endpoint(ep->prev_endpoint); + } + + mca_rcache_base_module_destroy(ep->rcache); + OBJ_RELEASE(endpoint); +} + +void *mca_smsc_accelerator_map_peer_region(mca_smsc_endpoint_t *endpoint, uint64_t flags, + void *remote_ptr, size_t size, void **local_ptr) +{ + void* result = NULL; + mca_smsc_accelerator_endpoint_t *ep = (mca_smsc_accelerator_endpoint_t *)endpoint; + + if (NULL != mca_smsc_accelerator_module.prev_smsc && + (mca_smsc_accelerator_module.prev_smsc->features & MCA_SMSC_FEATURE_CAN_MAP)) { + result = mca_smsc_accelerator_module.prev_smsc->map_peer_region(ep->prev_endpoint, + flags, remote_ptr, size, local_ptr); + } + return result; +} + +void mca_smsc_accelerator_unmap_peer_region(void *ctx) +{ + if (NULL != mca_smsc_accelerator_module.prev_smsc && + (mca_smsc_accelerator_module.prev_smsc->features & MCA_SMSC_FEATURE_CAN_MAP)) { + mca_smsc_accelerator_module.prev_smsc->unmap_peer_region(ctx); + } +} + +static int mca_smsc_accelerator_copy (mca_smsc_endpoint_t *endpoint, void *local_address, void *remote_address, + size_t size, void *reg_handle, bool is_remote_write) +{ + mca_smsc_accelerator_endpoint_t *ep = (mca_smsc_accelerator_endpoint_t *)endpoint; + mca_smsc_accelerator_registration_data_t *reg = (mca_smsc_accelerator_registration_data_t *)reg_handle; + int ret = OPAL_SUCCESS; + void *remote_memory_address; + mca_opal_gpu_reg_t rget_reg; + mca_opal_gpu_reg_t *reg_ptr = &rget_reg; + size_t offset; + + memset(&rget_reg, 0, sizeof(rget_reg)); + memcpy(&rget_reg.data.ipcHandle.handle, reg->handle.accelerator, + SMSC_ACCELERATOR_HANDLE_SIZE); + ret = ep->rcache->rcache_register(ep->rcache, remote_address, size, + /*ep->peer_smp_rank for debugging only */ 0, + MCA_RCACHE_ACCESS_LOCAL_WRITE, + (mca_rcache_base_registration_t **) ®_ptr); + if (OPAL_SUCCESS != ret) { + opal_output(0, "mca_smsc_accelerator_copy: Failed to register remote memory, ret=%d", ret); + return ret; + } + + offset = (size_t)((intptr_t) remote_address - (intptr_t) reg->base_addr); + remote_memory_address = (unsigned char *) reg_ptr->base.alloc_base + offset; + + if (is_remote_write) { + ret = opal_accelerator.mem_copy(MCA_ACCELERATOR_NO_DEVICE_ID, mca_smsc_accelerator_module.device_id, + remote_memory_address, local_address, size, + MCA_ACCELERATOR_TRANSFER_DTOD); + } else { + ret = opal_accelerator.mem_copy(mca_smsc_accelerator_module.device_id, MCA_ACCELERATOR_NO_DEVICE_ID, + local_address, remote_memory_address, size, + MCA_ACCELERATOR_TRANSFER_DTOD); + } + if (OPAL_SUCCESS != ret) { + opal_output(0, "mca_smsc_accelerator_copy: accelerator mem_copy failed, ret=%d", ret); + } + + return ret; +} + +int mca_smsc_accelerator_copy_to(mca_smsc_endpoint_t *endpoint, void *local_address, void *remote_address, + size_t size, void *reg_handle) +{ + mca_smsc_accelerator_endpoint_t *ep = (mca_smsc_accelerator_endpoint_t *)endpoint; + mca_smsc_accelerator_registration_data_t *reg = (mca_smsc_accelerator_registration_data_t *)reg_handle; + int ret = OPAL_SUCCESS; + + if ((NULL != reg) && (0 != reg->base_addr)) { + ret = mca_smsc_accelerator_copy (endpoint, local_address, remote_address, size, reg_handle, true); + } + else if (NULL != mca_smsc_accelerator_module.prev_smsc) { + ret = mca_smsc_accelerator_module.prev_smsc->copy_to(ep->prev_endpoint, local_address, + remote_address, size, reg_handle); + } + + return ret; +} + +int mca_smsc_accelerator_copy_from(mca_smsc_endpoint_t *endpoint, void *local_address, + void *remote_address, size_t size, void *reg_handle) +{ + mca_smsc_accelerator_endpoint_t *ep = (mca_smsc_accelerator_endpoint_t *)endpoint; + mca_smsc_accelerator_registration_data_t *reg = (mca_smsc_accelerator_registration_data_t *)reg_handle; + int ret = OPAL_SUCCESS; + + if ((NULL != reg) && (0 != reg->base_addr)) { + ret = mca_smsc_accelerator_copy (endpoint, local_address, remote_address, size, reg_handle, false); + } + else if (NULL != mca_smsc_accelerator_module.prev_smsc) { + ret = mca_smsc_accelerator_module.prev_smsc->copy_from(ep->prev_endpoint, local_address, + remote_address, size, reg_handle); + } + + return ret; +} + +void *mca_smsc_accelerator_register_region(void *local_address, size_t size) +{ + int dev_id, ret; + mca_smsc_accelerator_registration_handle_t *reg; + uint64_t flags; + + if (opal_accelerator.check_addr(local_address, &dev_id, &flags) > 0) { + ret = mca_smsc_accelerator_module.rcache->rcache_register(mca_smsc_accelerator_module.rcache, + local_address, size, + MCA_RCACHE_FLAGS_ACCELERATOR_MEM, MCA_RCACHE_ACCESS_ANY, + (mca_rcache_base_registration_t **) ®); + if (OPAL_UNLIKELY(OPAL_SUCCESS != ret)) { + opal_output_verbose(MCA_BASE_VERBOSE_WARN, opal_smsc_base_framework.framework_output, + "mca_smsc_accelerator_register_mem: failed to register memory for single-copy"); + return NULL; + } + reg->data.base_addr = (uint64_t) reg->base.base; + } + else { + reg = (mca_smsc_accelerator_registration_handle_t *)malloc (sizeof(mca_smsc_accelerator_registration_handle_t)); + if (NULL == reg) { + opal_output(0, "mca_smsc_accelerator_register_mem: failed to allocate memory"); + return NULL; + } + + reg->data.handle.host = NULL; + if ( (NULL != mca_smsc_accelerator_module.prev_smsc) && + (mca_smsc_accelerator_module.prev_smsc->features & MCA_SMSC_FEATURE_REQUIRE_REGISTRATION)) { + reg->data.handle.host = mca_smsc_accelerator_module.prev_smsc->register_region(local_address, size); + } + reg->data.base_addr = 0; + } + + return &(reg->data); +} + +void mca_smsc_accelerator_deregister_region(void *reg_data) +{ + if (NULL == reg_data) { + return; + } + + mca_smsc_accelerator_registration_data_t *reg = (mca_smsc_accelerator_registration_data_t *)reg_data; + mca_smsc_accelerator_registration_handle_t *reg_handle = MCA_SMSC_ACCELERATOR_REG_DATA_TO_HANDLE(reg); + if (0 != reg->base_addr) { + mca_smsc_accelerator_module.rcache->rcache_deregister(mca_smsc_accelerator_module.rcache, + ®_handle->base); + } + else { + if ((NULL != mca_smsc_accelerator_module.prev_smsc) && + (mca_smsc_accelerator_module.prev_smsc->features & MCA_SMSC_FEATURE_REQUIRE_REGISTRATION) && + (NULL != reg->handle.host)) { + mca_smsc_accelerator_module.prev_smsc->deregister_region(reg_data); + } + free(reg_handle); + } +} + +mca_smsc_accelerator_module_t mca_smsc_accelerator_module = { + .super = { + .registration_data_size = sizeof(mca_smsc_accelerator_registration_data_t), + .features = MCA_SMSC_FEATURE_REQUIRE_REGISTRATION | MCA_SMSC_FEATURE_ACCELERATOR, // also modified in component_open + .get_endpoint = mca_smsc_accelerator_get_endpoint, + .return_endpoint = mca_smsc_accelerator_return_endpoint, + .copy_to = mca_smsc_accelerator_copy_to, + .copy_from = mca_smsc_accelerator_copy_from, + .map_peer_region = mca_smsc_accelerator_map_peer_region, + .unmap_peer_region = mca_smsc_accelerator_unmap_peer_region, + .register_region = mca_smsc_accelerator_register_region, + .deregister_region = mca_smsc_accelerator_deregister_region, + }, +}; diff --git a/opal/mca/smsc/base/base.h b/opal/mca/smsc/base/base.h index e328374417a..6869e0a1580 100644 --- a/opal/mca/smsc/base/base.h +++ b/opal/mca/smsc/base/base.h @@ -12,10 +12,19 @@ #ifndef OPAL_MCA_SMSC_BASE_BASE_H #define OPAL_MCA_SMSC_BASE_BASE_H +#include "ompi_config.h" + #include "opal/mca/smsc/smsc.h" extern mca_base_framework_t opal_smsc_base_framework; +struct mca_smsc_base_component_t { + opal_list_item_t super; + mca_smsc_component_t *smsc_component; +}; +typedef struct mca_smsc_base_component_t mca_smsc_base_component_t; +OMPI_DECLSPEC OBJ_CLASS_DECLARATION(mca_smsc_base_component_t); + int mca_smsc_base_select(void); void mca_smsc_base_register_default_params(mca_smsc_component_t *component, int default_priority); diff --git a/opal/mca/smsc/base/smsc_base_frame.c b/opal/mca/smsc/base/smsc_base_frame.c index ea41b63f05a..405d3545998 100644 --- a/opal/mca/smsc/base/smsc_base_frame.c +++ b/opal/mca/smsc/base/smsc_base_frame.c @@ -1,3 +1,4 @@ +/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ /* * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana * University Research and Technology @@ -11,6 +12,7 @@ * All rights reserved. * Copyright (c) 2021 Google, LLC. All rights reserved. * Copyright (c) 2022 IBM Corporation. All rights reserved. + * Copyright (c) 2024 Advanced Micro Devices, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -39,6 +41,8 @@ static mca_smsc_component_t *selected_component = NULL; mca_smsc_module_t *mca_smsc = NULL; +OBJ_CLASS_INSTANCE(mca_smsc_base_component_t, opal_list_item_t, NULL, NULL); + /* * Global variables */ @@ -47,9 +51,9 @@ MCA_BASE_FRAMEWORK_DECLARE(opal, smsc, NULL, NULL, NULL, NULL, mca_smsc_base_sta static int mca_smsc_compare_components(opal_list_item_t **a, opal_list_item_t **b) { mca_smsc_component_t *componenta - = (mca_smsc_component_t *) ((mca_base_component_list_item_t *) *a)->cli_component; + = (mca_smsc_component_t *) ((mca_smsc_base_component_t *) *a)->smsc_component; mca_smsc_component_t *componentb - = (mca_smsc_component_t *) ((mca_base_component_list_item_t *) *b)->cli_component; + = (mca_smsc_component_t *) ((mca_smsc_base_component_t *) *b)->smsc_component; return (componenta->priority > componentb->priority) ? -1 @@ -59,6 +63,13 @@ static int mca_smsc_compare_components(opal_list_item_t **a, opal_list_item_t ** int mca_smsc_base_select(void) { mca_base_component_list_item_t *cli, *next; + mca_smsc_base_component_t *first=NULL, *second=NULL; + opal_list_t *selectable; + mca_smsc_component_t *second_component=NULL; + mca_smsc_base_component_t *avail; + + /* Make a list of the components that query successfully */ + selectable = OBJ_NEW(opal_list_t); OPAL_LIST_FOREACH_SAFE (cli, next, &opal_smsc_base_framework.framework_components, mca_base_component_list_item_t) { @@ -81,30 +92,49 @@ int mca_smsc_base_select(void) opal_smsc_base_framework.framework_output); continue; } + avail = OBJ_NEW(mca_smsc_base_component_t); + avail->smsc_component = component; + + opal_list_append(selectable, &avail->super); + opal_output_verbose(MCA_BASE_VERBOSE_COMPONENT, opal_smsc_base_framework.framework_output, "mca_smsc_base_select: component %s priority=%d", component->smsc_version.mca_component_name, component->priority); } - opal_list_sort(&opal_smsc_base_framework.framework_components, mca_smsc_compare_components); - - if (opal_list_get_size(&opal_smsc_base_framework.framework_components) > 0) { - cli = (mca_base_component_list_item_t *) opal_list_get_first( - &opal_smsc_base_framework.framework_components); + opal_list_sort(selectable, mca_smsc_compare_components); + + if (opal_list_get_size(selectable) > 0) { + first = (mca_smsc_base_component_t *) opal_list_remove_first(selectable); + if (opal_list_get_size(selectable) > 0) { + /* enable second component first. Allows for the component + * with the highest priority to store it as a pass-through + * component */ + second = (mca_smsc_base_component_t *) opal_list_remove_first(selectable); + second_component = (mca_smsc_component_t *) second->smsc_component; + mca_smsc = second_component->enable(); + } - selected_component = (mca_smsc_component_t *) cli->cli_component; + selected_component = (mca_smsc_component_t *) first->smsc_component; mca_smsc = selected_component->enable(); - opal_output_verbose( - MCA_BASE_VERBOSE_COMPONENT, opal_smsc_base_framework.framework_output, - "mca_smsc_base_select: selected shared-memory single-copy component: %s", - selected_component->smsc_version.mca_component_name); + opal_output_verbose(MCA_BASE_VERBOSE_COMPONENT, opal_smsc_base_framework.framework_output, + "mca_smsc_base_select: selected shared-memory single-copy component: %s", + selected_component->smsc_version.mca_component_name); + if (NULL != second_component) { + opal_output_verbose(MCA_BASE_VERBOSE_COMPONENT, + opal_smsc_base_framework.framework_output, + "mca_smsc_base_select: selected %s as pass-through component for host memory", + second_component->smsc_version.mca_component_name); + } } else { opal_output_verbose( - MCA_BASE_VERBOSE_COMPONENT, opal_smsc_base_framework.framework_output, - "mca_smsc_base_select: no shared-memory single-copy component available for selection"); + MCA_BASE_VERBOSE_COMPONENT, opal_smsc_base_framework.framework_output, + "mca_smsc_base_select: no shared-memory single-copy component available for selection"); } + OBJ_RELEASE(selectable); + return OPAL_SUCCESS; } diff --git a/opal/mca/smsc/smsc.h b/opal/mca/smsc/smsc.h index 9e415740326..ddbf5402672 100644 --- a/opal/mca/smsc/smsc.h +++ b/opal/mca/smsc/smsc.h @@ -136,6 +136,8 @@ enum { MCA_SMSC_FEATURE_REQUIRE_REGISTRATION = 1, /** Module can map peer memory into the local processes' address space. */ MCA_SMSC_FEATURE_CAN_MAP = 2, + /** Module can handle accelerator memory types */ + MCA_SMSC_FEATURE_ACCELERATOR = 4, }; struct mca_smsc_module_t {