From 55c576fb7d8fef5e960ee98397277dd4301dcb54 Mon Sep 17 00:00:00 2001 From: Sergey Oblomov Date: Wed, 16 Mar 2022 20:20:43 +0200 Subject: [PATCH] BUILD/STATIC: backport of static build - use single constructor/destructor entry to initialize UCS, UCM - added khash static initializer - implemented single constructor entries for SM modules: posix, sysv, xpmem, cma, knem - added separate module to handle signal and sigaction calls - fixed missing and incorrect include config.h - added static/dynamic lib detection - in static lib disabled module loading - suppress linker warning when building static application: warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking - in static build mode exclude dlopen stuff by compiler preprocessor - used single constructor entry for SELF and TCP transports - added direct call for posix/sysv transports - added static build mode support: in case if library is built statically and symbol to patch could not be found then patch statically linked function - re-design of IB initialization: used single constructor entry to initialize IB module - fixed ordering-sensitive constructor's ordering hang: in case of "incorrect" constructor call sequence ucm spin-lock may be used prior to initialized - added INIT_ONCE section to destructor to eliminate cleanup if initialization is not happened - added static libs to RPM build of devel package --- .gitignore | 4 +- buildlib/check_tls.sh | 29 ++++ buildlib/pr/io_demo/io-demo.yml | 55 ++++++++ buildlib/pr/main.yml | 2 +- config/m4/ucs.m4 | 1 + config/module-pkg-config.am | 9 ++ configure.ac | 9 +- src/ucm/Makefile.am | 4 + src/ucm/api/ucm.h | 6 +- src/ucm/bistro/bistro_aarch64.c | 9 +- src/ucm/bistro/bistro_aarch64.h | 10 +- src/ucm/bistro/bistro_ppc64.c | 19 ++- src/ucm/bistro/bistro_ppc64.h | 14 +- src/ucm/bistro/bistro_x86_64.c | 12 +- src/ucm/bistro/bistro_x86_64.h | 10 +- src/ucm/configure.m4 | 3 +- src/ucm/event/event.c | 40 +++--- src/ucm/malloc/malloc_hook.c | 6 +- src/ucm/malloc/malloc_hook.h | 2 +- src/ucm/mmap/install.c | 44 ++++-- src/ucm/ucx-ucm.pc.in | 18 +++ src/ucm/util/log.c | 3 +- src/ucm/util/log.h | 2 + src/ucm/util/reloc.c | 2 - src/ucm/util/sys.c | 11 ++ src/ucp/core/ucp_context.c | 51 ++++++- src/ucp/core/ucp_context.h | 37 +++-- src/ucp/core/ucp_types.h | 3 +- src/ucp/core/ucp_worker.c | 34 +++-- src/ucp/rma/amo_sw.c | 6 +- src/ucp/rma/rma_sw.c | 11 +- src/ucp/stream/stream_recv.c | 6 +- src/ucp/tag/eager_rcv.c | 36 ++--- src/ucp/tag/rndv.c | 26 ++-- src/ucs/Makefile.am | 5 + src/ucs/config/global_opts.c | 11 +- src/ucs/config/global_opts.h | 1 + src/ucs/config/parser.h | 11 +- src/ucs/config/ucm_opts.c | 17 ++- src/ucs/config/ucm_opts.h | 19 +++ src/ucs/configure.m4 | 7 + src/ucs/datastruct/khash.h | 2 + src/ucs/debug/debug.c | 93 +------------ src/ucs/sys/init.c | 6 +- src/ucs/sys/module.c | 8 ++ src/ucs/sys/preprocessor.h | 3 + src/ucs/sys/sys.c | 9 ++ src/ucs/sys/sys.h | 9 +- src/ucs/type/init_once.h | 19 +++ src/ucs/ucx-ucs.pc.in | 19 +++ src/uct/Makefile.am | 4 + src/uct/base/uct_component.c | 41 ++++++ src/uct/base/uct_component.h | 11 +- src/uct/base/uct_iface.c | 12 ++ src/uct/base/uct_iface.h | 88 ++++++++++++ src/uct/configure.m4 | 3 +- src/uct/ib/Makefile.am | 3 + src/uct/ib/base/ib_md.c | 81 +++++++++-- src/uct/ib/base/ib_md.h | 24 +--- src/uct/ib/cm/cm_iface.c | 7 +- src/uct/ib/cm/configure.m4 | 3 +- src/uct/ib/cm/ucx-cm.pc.in | 16 +++ src/uct/ib/configure.m4 | 4 +- src/uct/ib/dc/dc_mlx5.c | 6 +- src/uct/ib/mlx5/dv/ib_mlx5dv_md.c | 4 +- src/uct/ib/mlx5/exp/ib_exp_md.c | 2 +- src/uct/ib/rc/accel/rc_mlx5_iface.c | 6 +- src/uct/ib/rc/verbs/rc_verbs_iface.c | 7 +- src/uct/ib/rdmacm/Makefile.am | 3 + src/uct/ib/rdmacm/configure.m4 | 3 +- src/uct/ib/rdmacm/rdmacm_iface.c | 8 +- src/uct/ib/rdmacm/rdmacm_md.c | 1 - src/uct/ib/rdmacm/ucx-rdmacm.pc.in | 16 +++ src/uct/ib/ucx-ib.pc.in | 16 +++ src/uct/ib/ud/accel/ud_mlx5.c | 6 +- src/uct/ib/ud/verbs/ud_verbs.c | 6 +- src/uct/sm/mm/base/mm_iface.h | 18 +-- src/uct/sm/mm/base/mm_md.h | 11 +- src/uct/sm/mm/posix/mm_posix.c | 11 +- src/uct/sm/mm/sysv/mm_sysv.c | 11 +- src/uct/sm/mm/xpmem/Makefile.am | 3 + src/uct/sm/mm/xpmem/configure.m4 | 3 +- src/uct/sm/mm/xpmem/mm_xpmem.c | 57 ++++---- src/uct/sm/mm/xpmem/ucx-xpmem.pc.in | 16 +++ src/uct/sm/scopy/cma/Makefile.am | 3 + src/uct/sm/scopy/cma/cma_iface.c | 8 +- src/uct/sm/scopy/cma/cma_md.c | 1 - src/uct/sm/scopy/cma/configure.m4 | 3 +- src/uct/sm/scopy/cma/ucx-cma.pc.in | 15 ++ src/uct/sm/scopy/knem/Makefile.am | 3 + src/uct/sm/scopy/knem/configure.m4 | 3 +- src/uct/sm/scopy/knem/knem_iface.c | 8 +- src/uct/sm/scopy/knem/knem_md.c | 1 - src/uct/sm/scopy/knem/ucx-knem.pc.in | 15 ++ src/uct/sm/self/self.c | 10 +- src/uct/tcp/sockcm/sockcm_iface.c | 8 +- src/uct/tcp/sockcm/sockcm_md.c | 1 - src/uct/tcp/tcp_iface.c | 8 +- src/uct/tcp/tcp_md.c | 1 - src/uct/tcp/tcp_net.c | 4 +- src/uct/ucx-uct.pc.in | 19 +++ test/apps/uct_info/Makefile.in | 27 ++++ test/apps/uct_info/configure.m4 | 7 + test/apps/uct_info/uct_info.c | 196 +++++++++++++++++++++++++++ test/gtest/Makefile.am | 1 + test/gtest/ucm/malloc_hook.cc | 11 +- test/gtest/ucs/test_khash.cc | 27 ++++ test/mpi/test_memhooks.c | 4 +- ucx.pc.in | 16 ++- ucx.spec.in | 35 ++++- 110 files changed, 1316 insertions(+), 403 deletions(-) create mode 100755 buildlib/check_tls.sh create mode 100644 config/module-pkg-config.am create mode 100644 src/ucm/ucx-ucm.pc.in create mode 100644 src/ucs/config/ucm_opts.h create mode 100644 src/ucs/configure.m4 create mode 100644 src/ucs/ucx-ucs.pc.in create mode 100644 src/uct/ib/cm/ucx-cm.pc.in create mode 100644 src/uct/ib/rdmacm/ucx-rdmacm.pc.in create mode 100644 src/uct/ib/ucx-ib.pc.in create mode 100644 src/uct/sm/mm/xpmem/ucx-xpmem.pc.in create mode 100644 src/uct/sm/scopy/cma/ucx-cma.pc.in create mode 100644 src/uct/sm/scopy/knem/ucx-knem.pc.in create mode 100644 src/uct/ucx-uct.pc.in create mode 100644 test/apps/uct_info/Makefile.in create mode 100644 test/apps/uct_info/configure.m4 create mode 100644 test/apps/uct_info/uct_info.c create mode 100644 test/gtest/ucs/test_khash.cc diff --git a/.gitignore b/.gitignore index 857a1de599a..9b93f1fc6b9 100644 --- a/.gitignore +++ b/.gitignore @@ -52,6 +52,8 @@ test/apps/test_link_map test/apps/test_ucp_dlopen test/apps/test_ucs_dlopen test/apps/sockaddr/sa +test/apps/test_init_mt +test/apps/test_memtrack_limit test/examples/ucp_client_server test/examples/ucp_hello_world test/examples/uct_hello_world @@ -63,7 +65,7 @@ debian/control debian/rules debian/ucx.postinst ucx.spec -ucx.pc +ucx*.pc doc/doxygen-doc doc/uml/uct.pdf doc/doxygen/header.tex diff --git a/buildlib/check_tls.sh b/buildlib/check_tls.sh new file mode 100755 index 00000000000..e505454f86e --- /dev/null +++ b/buildlib/check_tls.sh @@ -0,0 +1,29 @@ +#!/bin/sh +# +# Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# +# See file LICENSE for terms. +# + +# check_tls.sh [extra-tls-to-check] + +res=true; +for run in ./uct_info_static ./uct_info; do + echo Check for $run; + output=`$run`; + for i in tcp self sysv posix $@; do + if `echo $output | grep -q "Transport: $i"`; then + echo $i... ok; + else + res=false; + echo $i... fail; + fi; + done; + if test $res = false; then + echo failed to check tl in $run; + break; + fi; +done; +$res + +# done diff --git a/buildlib/pr/io_demo/io-demo.yml b/buildlib/pr/io_demo/io-demo.yml index 6a86f784161..0055f9a239a 100644 --- a/buildlib/pr/io_demo/io-demo.yml +++ b/buildlib/pr/io_demo/io-demo.yml @@ -58,6 +58,14 @@ jobs: ./contrib/configure-devel --prefix=$(Build.Repository.LocalPath)/install make -j`nproc` make install + # build static modules + source ./buildlib/az-helpers.sh + az_init_modules + module load dev/libnl + module load dev/numactl + PKG_CONFIG_PATH=$(Build.Repository.LocalPath)/install/lib/pkgconfig:$PKG_CONFIG_PATH make -C test/apps/uct_info EXTRA_MODULES="ucx-ib ucx-cma ucx-rdmacm" + module unload dev/numactl + module unload dev/libnl displayName: Build name: build - task: CopyFiles@2 @@ -66,8 +74,10 @@ jobs: contents: | buildlib/az-helpers.sh buildlib/az-network-corrupter.sh + buildlib/check_tls.sh install/** test/apps/iodemo/run_io_demo.sh + test/apps/uct_info/* targetFolder: '$(Build.ArtifactStagingDirectory)' - task: PublishBuildArtifacts@1 inputs: @@ -122,3 +132,48 @@ jobs: initial_delay: $(initial_delay) ${{ if eq(variables['Build.Reason'], 'PullRequest') }}: analyzer_allow_list_args: '--allow_list $(System.PullRequest.TargetBranch)' + + - job: test_static + dependsOn: io_build + workspace: + clean: all + + pool: + name: MLNX + demands: ${{ parameters.demands }} + + variables: + workspace: drop_$(Build.BuildId) + EXECUTOR_NUMBER: $(Build.BuildId) + + displayName: "Test static" + steps: + - checkout: none + clean: true + - task: DownloadBuildArtifacts@0 + displayName: 'Download Build Artifacts' + inputs: + artifactName: drop_$(Build.BuildId) + downloadPath: $(System.DefaultWorkingDirectory) + - bash: chmod u+rwx $(workspace) -R + - bash: | + set -eEx + cd $(workspace)/test/apps/uct_info + LD_LIBRARY_PATH=$(System.DefaultWorkingDirectory)/$(workspace)/install/lib:$LD_LIBRARY_PATH \ + $(System.DefaultWorkingDirectory)/$(workspace)/buildlib/check_tls.sh \ + dc_mlx5 rc_mlx5 ud_mlx5 rc_verbs ud_verbs cma + # Set port number for hello_world applications + server_port=$((10000 + (EXECUTOR_NUMBER % 1000))) + server_port_arg="-p $server_port" + + for tls in ib rc rc_x; do + echo UCX_TLS=$tls + UCX_TLS=$tls ./ucp_hello_world_static ${server_port_arg} & + # allow server to start + sleep 3 + UCX_TLS=$tls ./ucp_hello_world_static ${server_port_arg} -n localhost + # allow server to complete + sleep 3 + done + + cd - diff --git a/buildlib/pr/main.yml b/buildlib/pr/main.yml index 47b8e5937fb..2fe007e3294 100644 --- a/buildlib/pr/main.yml +++ b/buildlib/pr/main.yml @@ -1,7 +1,7 @@ resources: containers: - container: centos7 - image: rdmz-harbor.rdmz.labs.mlnx/ucx/centos7:3 + image: rdmz-harbor.rdmz.labs.mlnx/ucx/centos7:5 options: -v /hpc/local:/hpc/local -v /auto/sw_tools:/auto/sw_tools stages: diff --git a/config/m4/ucs.m4 b/config/m4/ucs.m4 index a65bcac5890..e24c8ac9465 100644 --- a/config/m4/ucs.m4 +++ b/config/m4/ucs.m4 @@ -68,6 +68,7 @@ AS_IF([test "x$enable_backtrace_detail" = xyes], if test "x$BT" = "x1"; then AC_CHECK_FUNCS([cplus_demangle]) + AC_SUBST([BFD_LDFLAGS], ["-lbfd -liberty -lz"]) AC_DEFINE([HAVE_DETAILED_BACKTRACE], 1, [Enable detailed backtrace]) case ${host} in aarch64*) CFLAGS="$CFLAGS -funwind-tables" ;; diff --git a/config/module-pkg-config.am b/config/module-pkg-config.am new file mode 100644 index 00000000000..e42109a10df --- /dev/null +++ b/config/module-pkg-config.am @@ -0,0 +1,9 @@ +# +# Copyright (C) 2022 Nvidia Corporation. All Rights Reserved. +# See file LICENSE for terms. +# + +EXTRA_DIST = ucx-$(PKG_CONFIG_NAME).pc.in +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = ucx-$(PKG_CONFIG_NAME).pc + diff --git a/configure.ac b/configure.ac index 82a89db328e..8eb6050fcbd 100644 --- a/configure.ac +++ b/configure.ac @@ -85,6 +85,12 @@ AC_FUNC_STRERROR_R AC_PATH_TOOL([PKG_CONFIG], [pkg-config], [pkg-config]) +# +# Define SHARED_LIB preprocessor macro when building a shared library +# +lt_prog_compiler_pic="$lt_prog_compiler_pic -DUCX_SHARED_LIB" + + # # Force link_all_deplibs=yes for libtool, otherwise it will not # link against dependency libs @@ -222,9 +228,11 @@ AS_IF([test "x$with_docs_only" = xyes], m4_include([config/m4/rocm.m4]) m4_include([config/m4/gdrcopy.m4]) m4_include([src/ucm/configure.m4]) + m4_include([src/ucs/configure.m4]) m4_include([src/uct/configure.m4]) m4_include([src/tools/perf/configure.m4]) m4_include([test/gtest/configure.m4]) + m4_include([test/apps/uct_info/configure.m4]) # @@ -356,7 +364,6 @@ AC_CONFIG_FILES([ debian/rules debian/control debian/changelog - src/ucs/Makefile src/ucp/Makefile src/ucp/api/ucp_version.h src/ucp/core/ucp_version.c diff --git a/src/ucm/Makefile.am b/src/ucm/Makefile.am index e53a30a4691..7158021d9bf 100644 --- a/src/ucm/Makefile.am +++ b/src/ucm/Makefile.am @@ -57,3 +57,7 @@ libucm_la_SOURCES += \ noinst_HEADERS += \ ptmalloc286/malloc-2.8.6.h endif + +PKG_CONFIG_NAME=ucm + +include $(top_srcdir)/config/module-pkg-config.am diff --git a/src/ucm/api/ucm.h b/src/ucm/api/ucm.h index bba7422828c..fbfda4db7f5 100644 --- a/src/ucm/api/ucm.h +++ b/src/ucm/api/ucm.h @@ -210,7 +210,7 @@ typedef struct ucm_global_config { /* * Global UCM configuration to be set externally. - * @deprecated replaced by @ref ucm_library_init. + * @deprecated replaced by @ref ucm_set_global_opts. */ extern ucm_global_config_t ucm_global_opts; @@ -254,14 +254,14 @@ typedef void (*ucm_event_callback_t)(ucm_event_type_t event_type, /** - * Initialize UCM library and set its configuration. + * Set UCM library configuration. * * @param [in] ucm_opts UCM library global configuration. If NULL, default * configuration is applied. * * @note Calling this function more than once in the same process has no effect. */ -void ucm_library_init(const ucm_global_config_t *ucm_opts); +void ucm_set_global_opts(const ucm_global_config_t *ucm_opts); /** diff --git a/src/ucm/bistro/bistro_aarch64.c b/src/ucm/bistro/bistro_aarch64.c index e161292f9ae..071f15bac72 100644 --- a/src/ucm/bistro/bistro_aarch64.c +++ b/src/ucm/bistro/bistro_aarch64.c @@ -59,10 +59,9 @@ */ #define BR(_reg) ((0xd61f << 16) + ((_reg) << 5)) -ucs_status_t ucm_bistro_patch(const char *symbol, void *hook, +ucs_status_t ucm_bistro_patch(void *func_ptr, void *hook, ucm_bistro_restore_point_t **rp) { - void *func; ucs_status_t status; ucm_bistro_patch_t patch = { @@ -73,14 +72,12 @@ ucs_status_t ucm_bistro_patch(const char *symbol, void *hook, .br = BR(R15) }; - UCM_LOOKUP_SYMBOL(func, symbol); - - status = ucm_bistro_create_restore_point(func, sizeof(patch), rp); + status = ucm_bistro_create_restore_point(func_ptr, sizeof(patch), rp); if (UCS_STATUS_IS_ERR(status)) { return status; } - return ucm_bistro_apply_patch(func, &patch, sizeof(patch)); + return ucm_bistro_apply_patch(func_ptr, &patch, sizeof(patch)); } #endif diff --git a/src/ucm/bistro/bistro_aarch64.h b/src/ucm/bistro/bistro_aarch64.h index 487aa923d08..b80258ba9bb 100644 --- a/src/ucm/bistro/bistro_aarch64.h +++ b/src/ucm/bistro/bistro_aarch64.h @@ -28,14 +28,14 @@ typedef struct ucm_bistro_patch { * Set library function call hook using Binary Instrumentation * method (BISTRO): replace function body by user defined call * - * @param symbol function name to replace - * @param hook user-defined function-replacer - * @param rp restore point used to restore original function, - * optional, may be NULL + * @param symbol_ptr function pointer to replace + * @param hook user-defined function-replacer + * @param rp restore point used to restore original function, + * optional, may be NULL * * @return Error code as defined by @ref ucs_status_t */ -ucs_status_t ucm_bistro_patch(const char *symbol, void *hook, +ucs_status_t ucm_bistro_patch(void *func_ptr, void *hook, ucm_bistro_restore_point_t **rp); #endif diff --git a/src/ucm/bistro/bistro_ppc64.c b/src/ucm/bistro/bistro_ppc64.c index 8a08655b365..fa93cdb5176 100644 --- a/src/ucm/bistro/bistro_ppc64.c +++ b/src/ucm/bistro/bistro_ppc64.c @@ -134,20 +134,17 @@ static void *ucm_bistro_get_text_addr(void *addr) #endif } -ucs_status_t ucm_bistro_patch_toc(const char *symbol, void *hook, +ucs_status_t ucm_bistro_patch_toc(void *func_ptr, void *hook, ucm_bistro_restore_point_t **rp, uint64_t toc) { ucs_status_t status; - void *func; ucm_bistro_restore_point_t restore; ucm_bistro_patch_t patch; - UCM_LOOKUP_SYMBOL(func, symbol); + restore.entry = func_ptr; - restore.entry = func; - - func = ucm_bistro_get_text_addr(func); + func_ptr = ucm_bistro_get_text_addr(func_ptr); hook = ucm_bistro_get_text_addr(hook); status = ucm_bistro_patch_hook(hook, &restore, toc); @@ -156,16 +153,16 @@ ucs_status_t ucm_bistro_patch_toc(const char *symbol, void *hook, } #if defined(_CALL_ELF) && (_CALL_ELF == 2) - func += 8; - hook += 8; + func_ptr += 8; + hook += 8; #endif ucm_bistro_fill_patch(&patch, R11, (uintptr_t)hook); - restore.func = func; - restore.func_patch = *(ucm_bistro_patch_t*)func; + restore.func = func_ptr; + restore.func_patch = *(ucm_bistro_patch_t*)func_ptr; - status = ucm_bistro_apply_patch(func, &patch, sizeof(patch)); + status = ucm_bistro_apply_patch(func_ptr, &patch, sizeof(patch)); if (UCS_STATUS_IS_ERR(status)) { return status; } diff --git a/src/ucm/bistro/bistro_ppc64.h b/src/ucm/bistro/bistro_ppc64.h index 7b5c3b46e7e..2513f56efc9 100644 --- a/src/ucm/bistro/bistro_ppc64.h +++ b/src/ucm/bistro/bistro_ppc64.h @@ -26,26 +26,26 @@ * Set library function call hook using Binary Instrumentation * method (BISTRO): replace function body by user defined call * - * @param symbol function name to replace - * @param hook user-defined function-replacer - * @param rp restore point used to restore original function, - * optional, may be NULL + * @param func_ptr function pointer to replace + * @param hook user-defined function-replacer + * @param rp restore point used to restore original function, + * optional, may be NULL * * @return Error code as defined by @ref ucs_status_t */ /* we have to use inline proxy call to save TOC register * value - PPC is very sensible to this register value */ -ucs_status_t ucm_bistro_patch_toc(const char *symbol, void *hook, +ucs_status_t ucm_bistro_patch_toc(void *func_ptr, void *hook, ucm_bistro_restore_point_t **rp, uint64_t toc); static inline -ucs_status_t ucm_bistro_patch(const char *symbol, void *hook, +ucs_status_t ucm_bistro_patch(void *func_ptr, void *hook, ucm_bistro_restore_point_t **rp) { uint64_t toc; asm volatile ("std 2, %0" : "=m" (toc)); - return ucm_bistro_patch_toc(symbol, hook, rp, toc); + return ucm_bistro_patch_toc(func_ptr, hook, rp, toc); } #endif diff --git a/src/ucm/bistro/bistro_x86_64.c b/src/ucm/bistro/bistro_x86_64.c index da67dbc517f..a9f046a811d 100644 --- a/src/ucm/bistro/bistro_x86_64.c +++ b/src/ucm/bistro/bistro_x86_64.c @@ -26,7 +26,7 @@ #include -ucs_status_t ucm_bistro_patch(const char *symbol, void *hook, +ucs_status_t ucm_bistro_patch(void *func_ptr, void *hook, ucm_bistro_restore_point_t **rp) { ucm_bistro_jmp_r11_patch_t patch_jmp_r11 = { @@ -36,14 +36,12 @@ ucs_status_t ucm_bistro_patch(const char *symbol, void *hook, ucm_bistro_jmp_near_patch_t patch_jmp_near = { .jmp_rel = 0xe9 }; - void *func, *patch, *jmp_base; + void *patch, *jmp_base; ucs_status_t status; ptrdiff_t jmp_disp; size_t patch_len; - UCM_LOOKUP_SYMBOL(func, symbol); - - jmp_base = UCS_PTR_BYTE_OFFSET(func, sizeof(patch_jmp_near)); + jmp_base = UCS_PTR_BYTE_OFFSET(func_ptr, sizeof(patch_jmp_near)); jmp_disp = UCS_PTR_BYTE_DIFF(jmp_base, hook); if (labs(jmp_disp) < INT32_MAX) { /* if 32-bit near jump is possible, use it, since it's a short 5-byte @@ -58,11 +56,11 @@ ucs_status_t ucm_bistro_patch(const char *symbol, void *hook, patch_len = sizeof(patch_jmp_r11); } - status = ucm_bistro_create_restore_point(func, patch_len, rp); + status = ucm_bistro_create_restore_point(func_ptr, patch_len, rp); if (UCS_STATUS_IS_ERR(status)) { return status; } - return ucm_bistro_apply_patch(func, patch, patch_len); + return ucm_bistro_apply_patch(func_ptr, patch, patch_len); } #endif diff --git a/src/ucm/bistro/bistro_x86_64.h b/src/ucm/bistro/bistro_x86_64.h index 04f09b87415..84670005263 100644 --- a/src/ucm/bistro/bistro_x86_64.h +++ b/src/ucm/bistro/bistro_x86_64.h @@ -35,14 +35,14 @@ typedef struct ucm_bistro_jmp_near_patch { * Set library function call hook using Binary Instrumentation * method (BISTRO): replace function body by user defined call * - * @param symbol function name to replace - * @param hook user-defined function-replacer - * @param rp restore point used to restore original function, - * optional, may be NULL + * @param func_ptr function pointer to replace + * @param hook user-defined function-replacer + * @param rp restore point used to restore original function, + * optional, may be NULL * * @return Error code as defined by @ref ucs_status_t */ -ucs_status_t ucm_bistro_patch(const char *symbol, void *hook, +ucs_status_t ucm_bistro_patch(void *func_ptr, void *hook, ucm_bistro_restore_point_t **rp); #endif diff --git a/src/ucm/configure.m4 b/src/ucm/configure.m4 index 2a752b680f1..b808061855f 100644 --- a/src/ucm/configure.m4 +++ b/src/ucm/configure.m4 @@ -12,4 +12,5 @@ m4_include([src/ucm/cuda/configure.m4]) m4_include([src/ucm/rocm/configure.m4]) AC_DEFINE_UNQUOTED([ucm_MODULES], ["${ucm_modules}"], [UCM loadable modules]) -AC_CONFIG_FILES([src/ucm/Makefile]) +AC_CONFIG_FILES([src/ucm/Makefile + src/ucm/ucx-ucm.pc]) diff --git a/src/ucm/event/event.c b/src/ucm/event/event.c index bf94cf10296..a3ebb372ef4 100644 --- a/src/ucm/event/event.c +++ b/src/ucm/event/event.c @@ -35,7 +35,8 @@ static ucs_recursive_spinlock_t ucm_kh_lock; #define ucm_ptr_hash(_ptr) kh_int64_hash_func((uintptr_t)(_ptr)) KHASH_INIT(ucm_ptr_size, const void*, size_t, 1, ucm_ptr_hash, kh_int64_hash_equal) -static pthread_rwlock_t ucm_event_lock = PTHREAD_RWLOCK_INITIALIZER; +static pthread_rwlock_t ucm_event_lock = PTHREAD_RWLOCK_INITIALIZER; +static ucs_init_once_t ucm_library_init_once = UCS_INIT_ONCE_INITIALIZER; static ucs_list_link_t ucm_event_handlers; static int ucm_external_events = 0; static khash_t(ucm_ptr_size) ucm_shmat_ptrs; @@ -444,18 +445,21 @@ int ucm_madvise(void *addr, size_t length, int advice) return event.madvise.result; } -void ucm_library_init(const ucm_global_config_t *ucm_opts) +void ucm_library_init() { - static ucs_init_once_t init_once = UCS_INIT_ONCE_INITIALIZER; - - UCS_INIT_ONCE(&init_once) { - if (ucm_opts != NULL) { - ucm_global_opts = *ucm_opts; - } + UCS_INIT_ONCE(&ucm_library_init_once) { + ucs_recursive_spinlock_init(&ucm_kh_lock, 0); + kh_init_inplace(ucm_ptr_size, &ucm_shmat_ptrs); ucm_mmap_init(); } } +void ucm_set_global_opts(const ucm_global_config_t *ucm_opts) + { + ucm_global_opts = *ucm_opts; + ucm_library_init(); + } + void ucm_event_handler_add(ucm_event_handler_t *handler) { ucm_event_handler_t *elem; @@ -565,7 +569,7 @@ ucs_status_t ucm_set_event_handler(int events, int priority, return UCS_ERR_UNSUPPORTED; } - ucm_library_init(NULL); + ucm_library_init(); /* separate event flags from real events */ flags = events & (UCM_EVENT_FLAG_NO_INSTALL | @@ -641,22 +645,18 @@ void ucm_unset_event_handler(int events, ucm_event_callback_t cb, void *arg) ucs_status_t ucm_test_events(int events) { - ucm_library_init(NULL); + ucm_library_init(); return ucm_mmap_test_installed_events(ucm_events_to_native_events(events)); } -UCS_STATIC_INIT { - ucs_recursive_spinlock_init(&ucm_kh_lock, 0); - kh_init_inplace(ucm_ptr_size, &ucm_shmat_ptrs); -} - UCS_STATIC_CLEANUP { ucs_status_t status; - kh_destroy_inplace(ucm_ptr_size, &ucm_shmat_ptrs); - - status = ucs_recursive_spinlock_destroy(&ucm_kh_lock); - if (status != UCS_OK) { - ucm_warn("ucs_recursive_spinlock_destroy() failed (%d)", status); + UCS_CLEANUP_ONCE(&ucm_library_init_once) { + kh_destroy_inplace(ucm_ptr_size, &ucm_shmat_ptrs); + status = ucs_recursive_spinlock_destroy(&ucm_kh_lock); + if (status != UCS_OK) { + ucm_warn("ucs_recursive_spinlock_destroy() failed (%d)", status); + } } } diff --git a/src/ucm/malloc/malloc_hook.c b/src/ucm/malloc/malloc_hook.c index 7b8bac5163c..df56f54bf04 100644 --- a/src/ucm/malloc/malloc_hook.c +++ b/src/ucm/malloc/malloc_hook.c @@ -131,7 +131,7 @@ static ucm_malloc_hook_state_t ucm_malloc_hook_state = { .free = NULL, .heap_start = (void*)-1, .heap_end = (void*)-1, - .ptrs = {0}, + .ptrs = KHASH_STATIC_INITIALIZER, .env_lock = PTHREAD_MUTEX_INITIALIZER, .env_strs = NULL, .num_env_strs = 0 @@ -905,7 +905,7 @@ void ucm_malloc_state_reset(int default_mmap_thresh, int default_trim_thresh) ucm_malloc_set_env_mallopt(); } -UCS_STATIC_INIT { +void ucm_init_malloc_hook() +{ ucs_recursive_spinlock_init(&ucm_malloc_hook_state.lock, 0); - kh_init_inplace(mmap_ptrs, &ucm_malloc_hook_state.ptrs); } diff --git a/src/ucm/malloc/malloc_hook.h b/src/ucm/malloc/malloc_hook.h index e35fd0eda19..02365d09a67 100644 --- a/src/ucm/malloc/malloc_hook.h +++ b/src/ucm/malloc/malloc_hook.h @@ -10,7 +10,7 @@ #include ucs_status_t ucm_malloc_install(int events); - +void ucm_init_malloc_hook(); void ucm_malloc_state_reset(int default_mmap_thresh, int default_trim_thresh); #endif diff --git a/src/ucm/mmap/install.c b/src/ucm/mmap/install.c index 8d78b065b2e..74ba713785f 100644 --- a/src/ucm/mmap/install.c +++ b/src/ucm/mmap/install.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -44,7 +45,13 @@ (_data)->out_events &= ~exp_events | (_data)->fired_events; \ } while(0) -extern const char *ucm_mmap_hook_modes[]; +#define UCM_MMAP_RELOC_ENTRY(_name) \ + { \ + .symbol = #_name, \ + .value = ucm_override_##_name, \ + .prev_value = _name \ + } + typedef struct ucm_mmap_func { ucm_reloc_patch_t patch; @@ -58,17 +65,17 @@ typedef struct ucm_mmap_test_events_data { } ucm_mmap_test_events_data_t; static ucm_mmap_func_t ucm_mmap_funcs[] = { - { {"mmap", ucm_override_mmap}, UCM_EVENT_MMAP, UCM_EVENT_NONE}, - { {"munmap", ucm_override_munmap}, UCM_EVENT_MUNMAP, UCM_EVENT_NONE}, + { UCM_MMAP_RELOC_ENTRY(mmap), UCM_EVENT_MMAP, UCM_EVENT_NONE}, + { UCM_MMAP_RELOC_ENTRY(munmap), UCM_EVENT_MUNMAP, UCM_EVENT_NONE}, #if HAVE_MREMAP - { {"mremap", ucm_override_mremap}, UCM_EVENT_MREMAP, UCM_EVENT_NONE}, + { UCM_MMAP_RELOC_ENTRY(mremap), UCM_EVENT_MREMAP, UCM_EVENT_NONE}, #endif - { {"shmat", ucm_override_shmat}, UCM_EVENT_SHMAT, UCM_EVENT_NONE}, - { {"shmdt", ucm_override_shmdt}, UCM_EVENT_SHMDT, UCM_EVENT_SHMAT}, - { {"sbrk", ucm_override_sbrk}, UCM_EVENT_SBRK, UCM_EVENT_NONE}, - { {"brk", ucm_override_brk}, UCM_EVENT_BRK, UCM_EVENT_NONE}, - { {"madvise", ucm_override_madvise}, UCM_EVENT_MADVISE, UCM_EVENT_NONE}, - { {NULL, NULL}, UCM_EVENT_NONE} + { UCM_MMAP_RELOC_ENTRY(shmat), UCM_EVENT_SHMAT, UCM_EVENT_NONE}, + { UCM_MMAP_RELOC_ENTRY(shmdt), UCM_EVENT_SHMDT, UCM_EVENT_SHMAT}, + { UCM_MMAP_RELOC_ENTRY(sbrk), UCM_EVENT_SBRK, UCM_EVENT_NONE}, + { UCM_MMAP_RELOC_ENTRY(brk), UCM_EVENT_BRK, UCM_EVENT_NONE}, + { UCM_MMAP_RELOC_ENTRY(madvise), UCM_EVENT_MADVISE, UCM_EVENT_NONE}, + { {NULL, NULL, NULL}, UCM_EVENT_NONE} }; static pthread_mutex_t ucm_mmap_install_mutex = PTHREAD_MUTEX_INITIALIZER; @@ -242,6 +249,7 @@ static ucs_status_t ucs_mmap_install_reloc(int events) static int installed_events = 0; ucm_mmap_func_t *entry; ucs_status_t status; + void *func_ptr; if (ucm_mmap_hook_mode() == UCM_MMAP_HOOK_NONE) { ucm_debug("installing mmap hooks is disabled by configuration"); @@ -267,8 +275,20 @@ static ucs_status_t ucs_mmap_install_reloc(int events) status = ucm_reloc_modify(&entry->patch); } else { ucm_assert(ucm_mmap_hook_mode() == UCM_MMAP_HOOK_BISTRO); - status = ucm_bistro_patch(entry->patch.symbol, entry->patch.value, - NULL); + func_ptr = ucm_reloc_get_orig(entry->patch.symbol, + entry->patch.value); + if ((func_ptr == NULL) && !ucs_sys_is_dynamic_lib()) { + /* prev_value is used to store pointer to libc function, + * used in library static build when other ways to + * find symbol were not successful */ + func_ptr = entry->patch.prev_value; + } + + if (func_ptr == NULL) { + status = UCS_ERR_NO_ELEM; + } else { + status = ucm_bistro_patch(func_ptr, entry->patch.value, NULL); + } } if (status != UCS_OK) { ucm_warn("failed to install %s hook for '%s'", UCM_HOOK_STR, diff --git a/src/ucm/ucx-ucm.pc.in b/src/ucm/ucx-ucm.pc.in new file mode 100644 index 00000000000..3dbfe84ac01 --- /dev/null +++ b/src/ucm/ucx-ucm.pc.in @@ -0,0 +1,18 @@ +# +# Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# +# See file LICENSE for terms. +# + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +bindir = @exec_prefix@/bin +libdir = @libdir@ +includedir = @includedir@ + +Name: @PACKAGE@-ucm +Description: Unified Communication X Library UCM module +Version: @VERSION@ +Cflags: -I${includedir} +Libs: -L${libdir} -lucm +Libs.private: -Wl,--undefined=ucm_init -ldl diff --git a/src/ucm/util/log.c b/src/ucm/util/log.c index 6fe2742a76c..0e4524ab36e 100644 --- a/src/ucm/util/log.c +++ b/src/ucm/util/log.c @@ -288,6 +288,7 @@ void __ucm_log(const char *file, unsigned line, const char *function, } } -UCS_STATIC_INIT { +void ucm_init_log() +{ gethostname(ucm_log_hostname, sizeof(ucm_log_hostname)); } diff --git a/src/ucm/util/log.h b/src/ucm/util/log.h index f78bf5c693f..7d1ace17520 100644 --- a/src/ucm/util/log.h +++ b/src/ucm/util/log.h @@ -49,6 +49,8 @@ extern const char *ucm_log_level_names[]; +void ucm_init_log(); + void __ucm_log(const char *file, unsigned line, const char *function, ucs_log_level_t level, const char *message, ...) UCS_F_PRINTF(5, 6); diff --git a/src/ucm/util/reloc.c b/src/ucm/util/reloc.c index 0b3d2874315..303f4978188 100644 --- a/src/ucm/util/reloc.c +++ b/src/ucm/util/reloc.c @@ -59,7 +59,6 @@ static UCS_LIST_HEAD(ucm_reloc_patch_list); static ucm_reloc_dlopen_func_t ucm_reloc_orig_dlopen = NULL; static pthread_mutex_t ucm_reloc_patch_list_lock = PTHREAD_MUTEX_INITIALIZER; - static uintptr_t ucm_reloc_get_entry(ElfW(Addr) base, const ElfW(Phdr) *dphdr, ElfW(Sxword) tag) { @@ -515,4 +514,3 @@ ucs_status_t ucm_reloc_modify(ucm_reloc_patch_t *patch) pthread_mutex_unlock(&ucm_reloc_patch_list_lock); return status; } - diff --git a/src/ucm/util/sys.c b/src/ucm/util/sys.c index 325ed103dca..d11c4ad873e 100644 --- a/src/ucm/util/sys.c +++ b/src/ucm/util/sys.c @@ -16,7 +16,9 @@ #include #include +#include #include +#include #include #include #include @@ -284,6 +286,7 @@ void ucm_strerror(int eno, char *buf, size_t max) void ucm_prevent_dl_unload() { +#ifdef UCX_SHARED_LIB static ucs_init_once_t init_once = UCS_INIT_ONCE_INITIALIZER; Dl_info info; void *dl; @@ -314,6 +317,7 @@ void ucm_prevent_dl_unload() /* coverity[overwrite_var] */ dl = NULL; } +#endif /* UCX_SHARED_LIB */ } char *ucm_concat_path(char *buffer, size_t max, const char *dir, const char *file) @@ -367,3 +371,10 @@ pid_t ucm_get_tid() { return syscall(SYS_gettid); } + +void UCS_F_CTOR ucm_init() +{ + ucm_init_log(); + ucm_init_malloc_hook(); +} + diff --git a/src/ucp/core/ucp_context.c b/src/ucp/core/ucp_context.c index ea2a4713e86..4abb0ddb662 100644 --- a/src/ucp/core/ucp_context.c +++ b/src/ucp/core/ucp_context.c @@ -27,7 +27,44 @@ #define UCP_RSC_CONFIG_ALL "all" -ucp_am_handler_t ucp_am_handlers[UCP_AM_ID_LAST] = {{0, NULL, NULL}}; +#define UCP_AM_HANDLER_FOREACH(_macro) \ + _macro(UCP_AM_ID_WIREUP) \ + _macro(UCP_AM_ID_EAGER_ONLY) \ + _macro(UCP_AM_ID_EAGER_FIRST) \ + _macro(UCP_AM_ID_EAGER_MIDDLE) \ + _macro(UCP_AM_ID_EAGER_SYNC_ONLY) \ + _macro(UCP_AM_ID_EAGER_SYNC_FIRST) \ + _macro(UCP_AM_ID_EAGER_SYNC_ACK) \ + _macro(UCP_AM_ID_RNDV_RTS) \ + _macro(UCP_AM_ID_RNDV_ATS) \ + _macro(UCP_AM_ID_RNDV_RTR) \ + _macro(UCP_AM_ID_RNDV_DATA) \ + _macro(UCP_AM_ID_OFFLOAD_SYNC_ACK) \ + _macro(UCP_AM_ID_STREAM_DATA) \ + _macro(UCP_AM_ID_RNDV_ATP) \ + _macro(UCP_AM_ID_PUT) \ + _macro(UCP_AM_ID_GET_REQ) \ + _macro(UCP_AM_ID_GET_REP) \ + _macro(UCP_AM_ID_ATOMIC_REQ) \ + _macro(UCP_AM_ID_ATOMIC_REP) \ + _macro(UCP_AM_ID_CMPL) \ + _macro(UCP_AM_ID_SINGLE) \ + _macro(UCP_AM_ID_MULTI) \ + _macro(UCP_AM_ID_SINGLE_REPLY) \ + _macro(UCP_AM_ID_MULTI_REPLY) + + +#define UCP_AM_HANDLER_DECL(_id) extern ucp_am_handler_t ucp_am_handler_##_id; + +#define UCP_AM_HANDLER_ENTRY(_id) [_id] = &ucp_am_handler_##_id, + + +/* Declare all am handlers */ +UCP_AM_HANDLER_FOREACH(UCP_AM_HANDLER_DECL) + +ucp_am_handler_t *ucp_am_handlers[UCP_AM_ID_LAST] = { + UCP_AM_HANDLER_FOREACH(UCP_AM_HANDLER_ENTRY) +}; static const char *ucp_atomic_modes[] = { [UCP_ATOMIC_MODE_CPU] = "cpu", @@ -288,7 +325,7 @@ static ucs_config_field_t ucp_config_table[] = { {NULL} }; -UCS_CONFIG_REGISTER_TABLE(ucp_config_table, "UCP context", NULL, ucp_config_t) +UCS_CONFIG_DECLARE_TABLE(ucp_config_table, "UCP context", NULL, ucp_config_t) static ucp_tl_alias_t ucp_tl_aliases[] = { @@ -1899,3 +1936,13 @@ uint64_t ucp_context_dev_idx_tl_bitmap(ucp_context_h context, return tl_bitmap; } + +UCS_F_CTOR void ucp_global_init(void) +{ + UCS_CONFIG_ADD_TABLE(ucp_config_table, &ucs_config_global_list); +} + +UCS_F_DTOR static void ucp_global_cleanup(void) +{ + UCS_CONFIG_REMOVE_TABLE(ucp_config_table); +} diff --git a/src/ucp/core/ucp_context.h b/src/ucp/core/ucp_context.h index 0ae3e9f0efa..9234acd6292 100644 --- a/src/ucp/core/ucp_context.h +++ b/src/ucp/core/ucp_context.h @@ -281,23 +281,32 @@ typedef struct ucp_tl_iface_atomic_flags { UCS_BIT(UCT_ATOMIC_OP_CSWAP)) +/* + * Define UCP active message handler helper macro. + */ +#define _UCP_DEFINE_AM(_features, _id, _cb, _tracer, _flags, _proxy) \ + ucp_am_handler_t ucp_am_handler_##_id = { \ + .features = _features, \ + .cb = _cb, \ + .tracer = _tracer, \ + .flags = _flags, \ + .proxy_cb = _proxy \ + } + + /* * Define UCP active message handler. */ #define UCP_DEFINE_AM(_features, _id, _cb, _tracer, _flags) \ - UCS_STATIC_INIT { \ - ucp_am_handlers[_id].features = _features; \ - ucp_am_handlers[_id].cb = _cb; \ - ucp_am_handlers[_id].tracer = _tracer; \ - ucp_am_handlers[_id].flags = _flags; \ - } + _UCP_DEFINE_AM(_features, _id, _cb, _tracer, _flags, NULL) /** - * Defines a proxy handler which counts received messages on ucp_worker_iface_t - * context. It's used to determine if there is activity on a transport interface. + * Defines UCP active message handler with proxy handler which counts received + * messages on ucp_worker_iface_t context. It's used to determine if there is + * activity on a transport interface. */ -#define UCP_DEFINE_AM_PROXY(_id) \ +#define UCP_DEFINE_AM_WITH_PROXY(_features, _id, _cb, _tracer, _flags) \ \ static ucs_status_t \ ucp_am_##_id##_counting_proxy(void *arg, void *data, size_t length, \ @@ -305,12 +314,11 @@ typedef struct ucp_tl_iface_atomic_flags { { \ ucp_worker_iface_t *wiface = arg; \ wiface->proxy_recv_count++; \ - return ucp_am_handlers[_id].cb(wiface->worker, data, length, flags); \ + return _cb(wiface->worker, data, length, flags); \ } \ \ - UCS_STATIC_INIT { \ - ucp_am_handlers[_id].proxy_cb = ucp_am_##_id##_counting_proxy; \ - } + _UCP_DEFINE_AM(_features, _id, _cb, _tracer, _flags, \ + ucp_am_##_id##_counting_proxy) #define UCP_CHECK_PARAM_NON_NULL(_param, _status, _action) \ @@ -348,9 +356,10 @@ typedef struct ucp_tl_iface_atomic_flags { ucs_assert(ucp_memory_type_detect(_context, _buffer, _length) == (_mem_type)) -extern ucp_am_handler_t ucp_am_handlers[]; +extern ucp_am_handler_t *ucp_am_handlers[]; extern const char *ucp_feature_str[]; + void ucp_dump_payload(ucp_context_h context, char *buffer, size_t max, const void *data, size_t length); diff --git a/src/ucp/core/ucp_types.h b/src/ucp/core/ucp_types.h index a5db2d404d4..288b0ef7737 100644 --- a/src/ucp/core/ucp_types.h +++ b/src/ucp/core/ucp_types.h @@ -58,7 +58,8 @@ typedef struct ucp_wireup_sockaddr_data ucp_wireup_sockaddr_data_t; * Active message codes */ enum { - UCP_AM_ID_WIREUP = 1, /* Connection establishment */ + UCP_AM_ID_FIRST = 1, /* First valid AM ID */ + UCP_AM_ID_WIREUP = UCP_AM_ID_FIRST, /* Connection establishment */ UCP_AM_ID_EAGER_ONLY = 2, /* Single packet eager TAG */ UCP_AM_ID_EAGER_FIRST = 3, /* First eager fragment */ diff --git a/src/ucp/core/ucp_worker.c b/src/ucp/core/ucp_worker.c index ffc87a97f0d..cdf4e975521 100644 --- a/src/ucp/core/ucp_worker.c +++ b/src/ucp/core/ucp_worker.c @@ -142,18 +142,22 @@ static void ucp_worker_set_am_handlers(ucp_worker_iface_t *wiface, int is_proxy) ucs_trace_func("iface=%p is_proxy=%d", wiface->iface, is_proxy); - for (am_id = 0; am_id < UCP_AM_ID_LAST; ++am_id) { + for (am_id = UCP_AM_ID_FIRST; am_id < UCP_AM_ID_LAST; ++am_id) { if (!(wiface->attr.cap.flags & (UCT_IFACE_FLAG_AM_SHORT | UCT_IFACE_FLAG_AM_BCOPY | UCT_IFACE_FLAG_AM_ZCOPY))) { continue; } - if (!(context->config.features & ucp_am_handlers[am_id].features)) { + if (ucp_am_handlers[am_id] == NULL) { continue; } - if (!(ucp_am_handlers[am_id].flags & UCT_CB_FLAG_ASYNC) && + if (!(context->config.features & ucp_am_handlers[am_id]->features)) { + continue; + } + + if (!(ucp_am_handlers[am_id]->flags & UCT_CB_FLAG_ASYNC) && !(wiface->attr.cap.flags & UCT_IFACE_FLAG_CB_SYNC)) { /* Do not register a sync callback on interface which does not @@ -163,20 +167,20 @@ static void ucp_worker_set_am_handlers(ucp_worker_iface_t *wiface, int is_proxy) continue; } - if (is_proxy && (ucp_am_handlers[am_id].proxy_cb != NULL)) { + if (is_proxy && (ucp_am_handlers[am_id]->proxy_cb != NULL)) { /* we care only about sync active messages, and this also makes sure * the counter is not accessed from another thread. */ - ucs_assert(!(ucp_am_handlers[am_id].flags & UCT_CB_FLAG_ASYNC)); + ucs_assert(!(ucp_am_handlers[am_id]->flags & UCT_CB_FLAG_ASYNC)); status = uct_iface_set_am_handler(wiface->iface, am_id, - ucp_am_handlers[am_id].proxy_cb, + ucp_am_handlers[am_id]->proxy_cb, wiface, - ucp_am_handlers[am_id].flags); + ucp_am_handlers[am_id]->flags); } else { status = uct_iface_set_am_handler(wiface->iface, am_id, - ucp_am_handlers[am_id].cb, + ucp_am_handlers[am_id]->cb, worker, - ucp_am_handlers[am_id].flags); + ucp_am_handlers[am_id]->flags); } if (status != UCS_OK) { ucs_fatal("failed to set active message handler id %d: %s", am_id, @@ -209,8 +213,12 @@ static void ucp_worker_remove_am_handlers(ucp_worker_h worker) UCT_IFACE_FLAG_AM_ZCOPY))) { continue; } - for (am_id = 0; am_id < UCP_AM_ID_LAST; ++am_id) { - if (context->config.features & ucp_am_handlers[am_id].features) { + for (am_id = UCP_AM_ID_FIRST; am_id < UCP_AM_ID_LAST; ++am_id) { + if (ucp_am_handlers[am_id] == NULL) { + continue; + } + + if (context->config.features & ucp_am_handlers[am_id]->features) { (void)uct_iface_set_am_handler(wiface->iface, am_id, ucp_stub_am_handler, worker, UCT_CB_FLAG_ASYNC); @@ -226,8 +234,8 @@ static void ucp_worker_am_tracer(void *arg, uct_am_trace_type_t type, ucp_worker_h worker = arg; ucp_am_tracer_t tracer; - if (id < UCP_AM_ID_LAST) { - tracer = ucp_am_handlers[id].tracer; + if ((id < UCP_AM_ID_LAST) && (id >= UCP_AM_ID_FIRST)) { + tracer = ucp_am_handlers[id]->tracer; if (tracer != NULL) { tracer(worker, type, id, data, length, buffer, max); } diff --git a/src/ucp/rma/amo_sw.c b/src/ucp/rma/amo_sw.c index 03ef9d2c217..37887a8672f 100644 --- a/src/ucp/rma/amo_sw.c +++ b/src/ucp/rma/amo_sw.c @@ -309,9 +309,7 @@ static void ucp_amo_sw_dump_packet(ucp_worker_h worker, uct_am_trace_type_t type length - header_len); } -UCP_DEFINE_AM(UCP_FEATURE_AMO, UCP_AM_ID_ATOMIC_REQ, ucp_atomic_req_handler, - ucp_amo_sw_dump_packet, 0); +UCP_DEFINE_AM_WITH_PROXY(UCP_FEATURE_AMO, UCP_AM_ID_ATOMIC_REQ, + ucp_atomic_req_handler, ucp_amo_sw_dump_packet, 0); UCP_DEFINE_AM(UCP_FEATURE_AMO, UCP_AM_ID_ATOMIC_REP, ucp_atomic_rep_handler, ucp_amo_sw_dump_packet, 0); - -UCP_DEFINE_AM_PROXY(UCP_AM_ID_ATOMIC_REQ); diff --git a/src/ucp/rma/rma_sw.c b/src/ucp/rma/rma_sw.c index 7246ce0ba12..870568308d0 100644 --- a/src/ucp/rma/rma_sw.c +++ b/src/ucp/rma/rma_sw.c @@ -307,14 +307,11 @@ static void ucp_rma_sw_dump_packet(ucp_worker_h worker, uct_am_trace_type_t type length - header_len); } -UCP_DEFINE_AM(UCP_FEATURE_RMA, UCP_AM_ID_PUT, ucp_put_handler, - ucp_rma_sw_dump_packet, 0); -UCP_DEFINE_AM(UCP_FEATURE_RMA, UCP_AM_ID_GET_REQ, ucp_get_req_handler, - ucp_rma_sw_dump_packet, 0); +UCP_DEFINE_AM_WITH_PROXY(UCP_FEATURE_RMA, UCP_AM_ID_PUT, ucp_put_handler, + ucp_rma_sw_dump_packet, 0); +UCP_DEFINE_AM_WITH_PROXY(UCP_FEATURE_RMA, UCP_AM_ID_GET_REQ, ucp_get_req_handler, + ucp_rma_sw_dump_packet, 0); UCP_DEFINE_AM(UCP_FEATURE_RMA, UCP_AM_ID_GET_REP, ucp_get_rep_handler, ucp_rma_sw_dump_packet, 0); UCP_DEFINE_AM(UCP_FEATURE_RMA|UCP_FEATURE_AMO, UCP_AM_ID_CMPL, ucp_rma_cmpl_handler, ucp_rma_sw_dump_packet, 0); - -UCP_DEFINE_AM_PROXY(UCP_AM_ID_PUT); -UCP_DEFINE_AM_PROXY(UCP_AM_ID_GET_REQ); diff --git a/src/ucp/stream/stream_recv.c b/src/ucp/stream/stream_recv.c index f115db51888..aeb36f3613b 100644 --- a/src/ucp/stream/stream_recv.c +++ b/src/ucp/stream/stream_recv.c @@ -520,7 +520,5 @@ static void ucp_stream_am_dump(ucp_worker_h worker, uct_am_trace_type_t type, UCS_PTR_BYTE_OFFSET(data, hdr_len), length - hdr_len); } -UCP_DEFINE_AM(UCP_FEATURE_STREAM, UCP_AM_ID_STREAM_DATA, ucp_stream_am_handler, - ucp_stream_am_dump, 0); - -UCP_DEFINE_AM_PROXY(UCP_AM_ID_STREAM_DATA); +UCP_DEFINE_AM_WITH_PROXY(UCP_FEATURE_STREAM, UCP_AM_ID_STREAM_DATA, + ucp_stream_am_handler, ucp_stream_am_dump, 0); diff --git a/src/ucp/tag/eager_rcv.c b/src/ucp/tag/eager_rcv.c index f14b3d13ba4..e8a6a46e469 100644 --- a/src/ucp/tag/eager_rcv.c +++ b/src/ucp/tag/eager_rcv.c @@ -520,25 +520,17 @@ static void ucp_eager_dump(ucp_worker_h worker, uct_am_trace_type_t type, UCS_PTR_BYTE_OFFSET(data, header_len), length - header_len); } -UCP_DEFINE_AM(UCP_FEATURE_TAG, UCP_AM_ID_EAGER_ONLY, ucp_eager_only_handler, - ucp_eager_dump, 0); -UCP_DEFINE_AM(UCP_FEATURE_TAG, UCP_AM_ID_EAGER_FIRST, ucp_eager_first_handler, - ucp_eager_dump, 0); -UCP_DEFINE_AM(UCP_FEATURE_TAG, UCP_AM_ID_EAGER_MIDDLE, ucp_eager_middle_handler, - ucp_eager_dump, 0); -UCP_DEFINE_AM(UCP_FEATURE_TAG, UCP_AM_ID_EAGER_SYNC_ONLY, - ucp_eager_sync_only_handler, ucp_eager_dump, 0); -UCP_DEFINE_AM(UCP_FEATURE_TAG, UCP_AM_ID_EAGER_SYNC_FIRST, - ucp_eager_sync_first_handler, ucp_eager_dump, 0); -UCP_DEFINE_AM(UCP_FEATURE_TAG, UCP_AM_ID_EAGER_SYNC_ACK, - ucp_eager_sync_ack_handler, ucp_eager_dump, 0); -UCP_DEFINE_AM(UCP_FEATURE_TAG, UCP_AM_ID_OFFLOAD_SYNC_ACK, - ucp_eager_offload_sync_ack_handler, ucp_eager_dump, 0); - -UCP_DEFINE_AM_PROXY(UCP_AM_ID_EAGER_ONLY); -UCP_DEFINE_AM_PROXY(UCP_AM_ID_EAGER_FIRST); -UCP_DEFINE_AM_PROXY(UCP_AM_ID_EAGER_MIDDLE); -UCP_DEFINE_AM_PROXY(UCP_AM_ID_EAGER_SYNC_ONLY); -UCP_DEFINE_AM_PROXY(UCP_AM_ID_EAGER_SYNC_FIRST); -UCP_DEFINE_AM_PROXY(UCP_AM_ID_EAGER_SYNC_ACK); -UCP_DEFINE_AM_PROXY(UCP_AM_ID_OFFLOAD_SYNC_ACK); +UCP_DEFINE_AM_WITH_PROXY(UCP_FEATURE_TAG, UCP_AM_ID_EAGER_ONLY, + ucp_eager_only_handler, ucp_eager_dump, 0); +UCP_DEFINE_AM_WITH_PROXY(UCP_FEATURE_TAG, UCP_AM_ID_EAGER_FIRST, + ucp_eager_first_handler, ucp_eager_dump, 0); +UCP_DEFINE_AM_WITH_PROXY(UCP_FEATURE_TAG, UCP_AM_ID_EAGER_MIDDLE, + ucp_eager_middle_handler, ucp_eager_dump, 0); +UCP_DEFINE_AM_WITH_PROXY(UCP_FEATURE_TAG, UCP_AM_ID_EAGER_SYNC_ONLY, + ucp_eager_sync_only_handler, ucp_eager_dump, 0); +UCP_DEFINE_AM_WITH_PROXY(UCP_FEATURE_TAG, UCP_AM_ID_EAGER_SYNC_FIRST, + ucp_eager_sync_first_handler, ucp_eager_dump, 0); +UCP_DEFINE_AM_WITH_PROXY(UCP_FEATURE_TAG, UCP_AM_ID_EAGER_SYNC_ACK, + ucp_eager_sync_ack_handler, ucp_eager_dump, 0); +UCP_DEFINE_AM_WITH_PROXY(UCP_FEATURE_TAG, UCP_AM_ID_OFFLOAD_SYNC_ACK, + ucp_eager_offload_sync_ack_handler, ucp_eager_dump, 0); diff --git a/src/ucp/tag/rndv.c b/src/ucp/tag/rndv.c index 6d11621de54..588accf5813 100644 --- a/src/ucp/tag/rndv.c +++ b/src/ucp/tag/rndv.c @@ -2019,19 +2019,13 @@ static void ucp_rndv_dump(ucp_worker_h worker, uct_am_trace_type_t type, } } -UCP_DEFINE_AM(UCP_FEATURE_TAG, UCP_AM_ID_RNDV_RTS, ucp_rndv_rts_handler, - ucp_rndv_dump, 0); -UCP_DEFINE_AM(UCP_FEATURE_TAG, UCP_AM_ID_RNDV_ATS, ucp_rndv_ats_handler, - ucp_rndv_dump, 0); -UCP_DEFINE_AM(UCP_FEATURE_TAG, UCP_AM_ID_RNDV_ATP, ucp_rndv_atp_handler, - ucp_rndv_dump, 0); -UCP_DEFINE_AM(UCP_FEATURE_TAG, UCP_AM_ID_RNDV_RTR, ucp_rndv_rtr_handler, - ucp_rndv_dump, 0); -UCP_DEFINE_AM(UCP_FEATURE_TAG, UCP_AM_ID_RNDV_DATA, ucp_rndv_data_handler, - ucp_rndv_dump, 0); - -UCP_DEFINE_AM_PROXY(UCP_AM_ID_RNDV_RTS); -UCP_DEFINE_AM_PROXY(UCP_AM_ID_RNDV_ATS); -UCP_DEFINE_AM_PROXY(UCP_AM_ID_RNDV_ATP); -UCP_DEFINE_AM_PROXY(UCP_AM_ID_RNDV_RTR); -UCP_DEFINE_AM_PROXY(UCP_AM_ID_RNDV_DATA); +UCP_DEFINE_AM_WITH_PROXY(UCP_FEATURE_TAG, UCP_AM_ID_RNDV_RTS, + ucp_rndv_rts_handler, ucp_rndv_dump, 0); +UCP_DEFINE_AM_WITH_PROXY(UCP_FEATURE_TAG, UCP_AM_ID_RNDV_ATS, + ucp_rndv_ats_handler, ucp_rndv_dump, 0); +UCP_DEFINE_AM_WITH_PROXY(UCP_FEATURE_TAG, UCP_AM_ID_RNDV_ATP, + ucp_rndv_atp_handler, ucp_rndv_dump, 0); +UCP_DEFINE_AM_WITH_PROXY(UCP_FEATURE_TAG, UCP_AM_ID_RNDV_RTR, + ucp_rndv_rtr_handler, ucp_rndv_dump, 0); +UCP_DEFINE_AM_WITH_PROXY(UCP_FEATURE_TAG, UCP_AM_ID_RNDV_DATA, + ucp_rndv_data_handler, ucp_rndv_dump, 0); diff --git a/src/ucs/Makefile.am b/src/ucs/Makefile.am index 3b347689677..446103de9c8 100644 --- a/src/ucs/Makefile.am +++ b/src/ucs/Makefile.am @@ -76,6 +76,7 @@ noinst_HEADERS = \ arch/atomic.h \ arch/bitops.h \ arch/cpu.h \ + config/ucm_opts.h \ datastruct/arbiter.h \ datastruct/frag_list.h \ datastruct/mpmc.h \ @@ -182,5 +183,9 @@ all-local: $(objdir)/$(modulesubdir) $(objdir)/$(modulesubdir): $(lib_LTLIBRARIES) $(AM_V_at)$(LN_RS) -fn $(localmoduledir) $(objdir)/$(modulesubdir) +PKG_CONFIG_NAME=ucs + +include $(top_srcdir)/config/module-pkg-config.am + #TODO stats/stats_dump.c #TODO stats/stats_reader.c diff --git a/src/ucs/config/global_opts.c b/src/ucs/config/global_opts.c index b8dc65ed428..d8c70228929 100644 --- a/src/ucs/config/global_opts.c +++ b/src/ucs/config/global_opts.c @@ -232,14 +232,16 @@ static ucs_config_field_t ucs_global_opts_table[] = { {NULL} }; -UCS_CONFIG_REGISTER_TABLE(ucs_global_opts_table, "UCS global", NULL, - ucs_global_opts_t) +UCS_CONFIG_DECLARE_TABLE(ucs_global_opts_table, "UCS global", NULL, + ucs_global_opts_t) void ucs_global_opts_init() { ucs_status_t status; + UCS_CONFIG_ADD_TABLE(ucs_global_opts_table, &ucs_config_global_list); + status = ucs_config_parser_fill_opts(&ucs_global_opts, ucs_global_opts_table, UCS_DEFAULT_ENV_PREFIX, NULL, 1); if (status != UCS_OK) { @@ -247,6 +249,11 @@ void ucs_global_opts_init() } } +void ucs_global_opts_cleanup() +{ + UCS_CONFIG_REMOVE_TABLE(ucs_global_opts_table); +} + ucs_status_t ucs_global_opts_set_value(const char *name, const char *value) { return ucs_config_parser_set_value(&ucs_global_opts, ucs_global_opts_table, diff --git a/src/ucs/config/global_opts.h b/src/ucs/config/global_opts.h index 52b13f69f6a..9c8a84a3d43 100644 --- a/src/ucs/config/global_opts.h +++ b/src/ucs/config/global_opts.h @@ -129,6 +129,7 @@ typedef struct { extern ucs_global_opts_t ucs_global_opts; void ucs_global_opts_init(); +void ucs_global_opts_cleanup(); ucs_status_t ucs_global_opts_set_value(const char *name, const char *value); ucs_status_t ucs_global_opts_get_value(const char *name, char *value, size_t max); diff --git a/src/ucs/config/parser.h b/src/ucs/config/parser.h index db65c3d1c3d..c0f47fcb492 100644 --- a/src/ucs/config/parser.h +++ b/src/ucs/config/parser.h @@ -117,14 +117,19 @@ typedef struct ucs_config_bw_spec { ucs_list_del(&(_entry)->list); \ } -#define UCS_CONFIG_REGISTER_TABLE(_table, _name, _prefix, _type) \ +#define UCS_CONFIG_DECLARE_TABLE(_table, _name, _prefix, _type) \ static ucs_config_global_list_entry_t _table##_config_entry = { \ .table = _table, \ .name = _name, \ .prefix = _prefix, \ .size = sizeof(_type) \ - }; \ - UCS_CONFIG_REGISTER_TABLE_ENTRY(&_table##_config_entry); + }; + +#define UCS_CONFIG_ADD_TABLE(_table, _list) \ + ucs_list_add_tail(_list, &(_table##_config_entry).list) + +#define UCS_CONFIG_REMOVE_TABLE(_table) \ + ucs_list_del(&(_table##_config_entry).list) extern ucs_list_link_t ucs_config_global_list; diff --git a/src/ucs/config/ucm_opts.c b/src/ucs/config/ucm_opts.c index cb4077724c3..52e3d8d3ed2 100644 --- a/src/ucs/config/ucm_opts.c +++ b/src/ucs/config/ucm_opts.c @@ -83,13 +83,22 @@ static ucs_config_field_t ucm_global_config_table[] = { {NULL} }; -UCS_CONFIG_REGISTER_TABLE(ucm_global_config_table, "UCM", UCM_CONFIG_PREFIX, - ucm_global_config_t) +UCS_CONFIG_DECLARE_TABLE(ucm_global_config_table, "UCM", UCM_CONFIG_PREFIX, + ucm_global_config_t) -UCS_STATIC_INIT { +void ucs_init_ucm_opts() +{ ucm_global_config_t ucm_opts; + + UCS_CONFIG_ADD_TABLE(ucm_global_config_table, &ucs_config_global_list); + (void)ucs_config_parser_fill_opts(&ucm_opts, ucm_global_config_table, UCS_DEFAULT_ENV_PREFIX, UCM_CONFIG_PREFIX, 0); - ucm_library_init(&ucm_opts); + ucm_set_global_opts(&ucm_opts); +} + +void ucs_cleanup_ucm_opts() +{ + UCS_CONFIG_REMOVE_TABLE(ucm_global_config_table); } diff --git a/src/ucs/config/ucm_opts.h b/src/ucs/config/ucm_opts.h new file mode 100644 index 00000000000..670040344de --- /dev/null +++ b/src/ucs/config/ucm_opts.h @@ -0,0 +1,19 @@ +/** + * Copyright (C) 2022 Nvidia Corporation. All Rights Reserved. + * + * See file LICENSE for terms. + */ + + #ifndef UCM_OPTS_H_ + #define UCM_OPTS_H_ + + #include + + BEGIN_C_DECLS + + void ucs_init_ucm_opts(); + void ucs_cleanup_ucm_opts(); + + END_C_DECLS + + #endif diff --git a/src/ucs/configure.m4 b/src/ucs/configure.m4 new file mode 100644 index 00000000000..e37ab995835 --- /dev/null +++ b/src/ucs/configure.m4 @@ -0,0 +1,7 @@ +# +# Copyright (C) 2022 Nvidia Corporation. All Rights Reserved. +# See file LICENSE for terms. +# + +AC_CONFIG_FILES([src/ucs/Makefile + src/ucs/ucx-ucs.pc]) diff --git a/src/ucs/datastruct/khash.h b/src/ucs/datastruct/khash.h index ff6a2590788..7ff33ae78fb 100644 --- a/src/ucs/datastruct/khash.h +++ b/src/ucs/datastruct/khash.h @@ -404,6 +404,8 @@ static const double __ac_HASH_UPPER = 0.77; #define KHASH_IMPL(name, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \ __KHASH_IMPL(name, static kh_inline klib_unused, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) +#define KHASH_STATIC_INITIALIZER {0} + /* --- BEGIN OF HASH FUNCTIONS --- */ /*! @function diff --git a/src/ucs/debug/debug.c b/src/ucs/debug/debug.c index e7365a841a5..e8df3a985e8 100644 --- a/src/ucs/debug/debug.c +++ b/src/ucs/debug/debug.c @@ -185,15 +185,11 @@ static khash_t(ucs_signal_orig_action) ucs_signal_orig_action_map; static ucs_recursive_spinlock_t ucs_kh_lock; -static int ucs_debug_initialized = 0; - #ifdef HAVE_CPLUS_DEMANGLE extern char *cplus_demangle(const char *, int); #endif static int ucs_debug_backtrace_is_excluded(void *address, const char *symbol); -static int orig_sigaction(int signum, const struct sigaction *act, - struct sigaction *oact); static char *ucs_debug_strdup(const char *str) @@ -928,7 +924,7 @@ static void ucs_error_freeze(const char *message) /* restore original SIGINT handler to allow termitate process via Ctrl+C */ sigemptyset(&sigact.sa_mask); - orig_sigaction(SIGINT, &sigact, NULL); + sigaction(SIGINT, &sigact, NULL); ucs_debug_stop_other_threads(); @@ -1114,81 +1110,6 @@ void ucs_handle_error(const char *message) } } -static int ucs_debug_is_error_signal(int signum) -{ - khiter_t hash_it; - int result; - - if (!ucs_global_opts.handle_errors) { - return 0; - } - - /* If this signal is error, but was disabled. */ - ucs_recursive_spin_lock(&ucs_kh_lock); - hash_it = kh_get(ucs_signal_orig_action, &ucs_signal_orig_action_map, signum); - result = (hash_it != kh_end(&ucs_signal_orig_action_map)); - ucs_recursive_spin_unlock(&ucs_kh_lock); - return result; -} - -static void* ucs_debug_get_orig_func(const char *symbol, void *replacement) -{ - void *func_ptr; - - func_ptr = dlsym(RTLD_NEXT, symbol); - if (func_ptr == NULL) { - func_ptr = dlsym(RTLD_DEFAULT, symbol); - } - return func_ptr; -} - -#if !HAVE_SIGHANDLER_T -#if HAVE___SIGHANDLER_T -typedef __sighandler_t *sighandler_t; -#else -#error "Port me" -#endif -#endif -sighandler_t signal(int signum, sighandler_t handler) -{ - typedef sighandler_t (*sighandler_func_t)(int, sighandler_t); - - static sighandler_func_t orig = NULL; - - if (ucs_debug_initialized && ucs_debug_is_error_signal(signum)) { - return SIG_DFL; - } - - if (orig == NULL) { - orig = (sighandler_func_t)ucs_debug_get_orig_func("signal", signal); - } - - return orig(signum, handler); -} - -static int orig_sigaction(int signum, const struct sigaction *act, - struct sigaction *oact) -{ - typedef int (*sigaction_func_t)(int, const struct sigaction*, struct sigaction*); - - static sigaction_func_t orig = NULL; - - if (orig == NULL) { - orig = (sigaction_func_t)ucs_debug_get_orig_func("sigaction", sigaction); - } - - return orig(signum, act, oact); -} - -int sigaction(int signum, const struct sigaction *act, struct sigaction *oact) -{ - if (ucs_debug_initialized && ucs_debug_is_error_signal(signum)) { - return orig_sigaction(signum, NULL, oact); /* Return old, do not set new */ - } - - return orig_sigaction(signum, act, oact); -} - static void ucs_debug_signal_handler(int signo) { ucs_log_flush(); @@ -1267,8 +1188,8 @@ static void ucs_set_signal_handler(void (*handler)(int, siginfo_t*, void *)) sigemptyset(&sigact.sa_mask); for (i = 0; i < ucs_global_opts.error_signals.count; ++i) { - ret = orig_sigaction(ucs_global_opts.error_signals.signals[i], &sigact, - &old_action); + ret = sigaction(ucs_global_opts.error_signals.signals[i], &sigact, + &old_action); if (ret < 0) { ucs_warn("failed to set signal handler for sig %d : %m", ucs_global_opts.error_signals.signals[i]); @@ -1357,15 +1278,13 @@ void ucs_debug_init() memset(&sigact, 0, sizeof(sigact)); memset(&old_action, 0, sizeof(old_action)); sigact.sa_handler = ucs_debug_signal_handler; - orig_sigaction(ucs_global_opts.debug_signo, &sigact, &old_action); + sigaction(ucs_global_opts.debug_signo, &sigact, &old_action); ucs_debug_save_original_sighandler(ucs_global_opts.debug_signo, &old_action); } #ifdef HAVE_DETAILED_BACKTRACE bfd_init(); #endif - - ucs_debug_initialized = 1; } void ucs_debug_cleanup(int on_error) @@ -1375,8 +1294,6 @@ void ucs_debug_cleanup(int on_error) struct sigaction *hndl; ucs_status_t status; - ucs_debug_initialized = 0; - kh_foreach_key(&ucs_signal_orig_action_map, signum, ucs_debug_disable_signal(signum)); @@ -1408,7 +1325,7 @@ static inline void ucs_debug_disable_signal_nolock(int signum) } original_action = kh_val(&ucs_signal_orig_action_map, hash_it); - ret = orig_sigaction(signum, original_action, &ucs_action); + ret = sigaction(signum, original_action, &ucs_action); if (ret < 0) { ucs_warn("failed to set signal handler for sig %d : %m", signum); } diff --git a/src/ucs/sys/init.c b/src/ucs/sys/init.c index 2d8dbf702dc..c5d1ddc45a9 100644 --- a/src/ucs/sys/init.c +++ b/src/ucs/sys/init.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -76,11 +77,12 @@ static UCS_F_NOOPTIMIZE void ucs_check_cpu_flags(void) } } -static void UCS_F_CTOR ucs_init() +void UCS_F_CTOR ucs_init() { ucs_check_cpu_flags(); ucs_log_early_init(); /* Must be called before all others */ ucs_global_opts_init(); + ucs_init_ucm_opts(); ucs_cpu_init(); ucs_log_init(); #ifdef ENABLE_STATS @@ -104,5 +106,7 @@ static void UCS_F_DTOR ucs_cleanup(void) #ifdef ENABLE_STATS ucs_stats_cleanup(); #endif + ucs_cleanup_ucm_opts(); + ucs_global_opts_cleanup(); ucs_log_cleanup(); } diff --git a/src/ucs/sys/module.c b/src/ucs/sys/module.c index f0430b71907..9e822192554 100644 --- a/src/ucs/sys/module.c +++ b/src/ucs/sys/module.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -27,6 +28,8 @@ #include +#ifdef UCX_SHARED_LIB + #define UCS_MODULE_PATH_MEMTRACK_NAME "module_path" #define UCS_MODULE_SRCH_PATH_MAX 2 @@ -236,10 +239,12 @@ static void ucs_module_load_one(const char *framework, const char *module_name, /* coverity[leaked_storage] : a loaded module is never unloaded */ } +#endif /* UCX_SHARED_LIB */ void ucs_load_modules(const char *framework, const char *modules, ucs_init_once_t *init_once, unsigned flags) { +#ifdef UCX_SHARED_LIB char *modules_str; char *saveptr; char *module_name; @@ -247,6 +252,8 @@ void ucs_load_modules(const char *framework, const char *modules, ucs_module_loader_init_paths(); UCS_INIT_ONCE(init_once) { + ucs_assert(ucs_sys_is_dynamic_lib()); + ucs_module_debug("loading modules for %s", framework); modules_str = ucs_strdup(modules, "modules_list"); if (modules_str != NULL) { @@ -261,4 +268,5 @@ void ucs_load_modules(const char *framework, const char *modules, ucs_error("failed to allocate module names list"); } } +#endif /* UCX_SHARED_LIB */ } diff --git a/src/ucs/sys/preprocessor.h b/src/ucs/sys/preprocessor.h index dc734edbc38..4ea003ec372 100644 --- a/src/ucs/sys/preprocessor.h +++ b/src/ucs/sys/preprocessor.h @@ -10,6 +10,9 @@ /* Convert token to string */ #define UCS_PP_QUOTE(x) # x +/* Expand macro token to the macro value */ +#define UCS_PP_EXPAND(x) x + /* Paste two expanded tokens */ #define __UCS_TOKENPASTE_HELPER(x, y) x ## y #define UCS_PP_TOKENPASTE(x, y) __UCS_TOKENPASTE_HELPER(x, y) diff --git a/src/ucs/sys/sys.c b/src/ucs/sys/sys.c index 4b5f7a59cb3..fba2647e394 100644 --- a/src/ucs/sys/sys.c +++ b/src/ucs/sys/sys.c @@ -1246,3 +1246,12 @@ ucs_status_t ucs_sys_get_boot_id(uint64_t *high, uint64_t *low) return status; } + +int ucs_sys_is_dynamic_lib(void) +{ +#ifdef UCX_SHARED_LIB + return 1; +#else + return 0; +#endif +} diff --git a/src/ucs/sys/sys.h b/src/ucs/sys/sys.h index 3d9cb7719e3..7f4e97555cf 100644 --- a/src/ucs/sys/sys.h +++ b/src/ucs/sys/sys.h @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include @@ -458,6 +457,14 @@ int ucs_sys_ns_is_default(ucs_sys_namespace_type_t name); */ ucs_status_t ucs_sys_get_boot_id(uint64_t *high, uint64_t *low); + +/* + * Check if library is built dynamically (.so module) + * + * @return 1 if built dynamically, 0 if statically. + */ +int ucs_sys_is_dynamic_lib(void); + END_C_DECLS #endif diff --git a/src/ucs/type/init_once.h b/src/ucs/type/init_once.h index fc75104f19f..031f55f58c9 100644 --- a/src/ucs/type/init_once.h +++ b/src/ucs/type/init_once.h @@ -54,4 +54,23 @@ unsigned ucs_init_once_mutex_unlock(pthread_mutex_t *lock); !(_once)->initialized || pthread_mutex_unlock(&(_once)->lock); \ (_once)->initialized = 1) +/* + * Start a code block to perform a cleanup step only if initialization has + * already been performed. + * + * @param [in] _once Pointer to @ref ucs_init_once_t synchronization object. + * + * Usage: + * UCS_CLEANUP_ONCE(&once) { + * ... code ... + * } + * + * @note Use the macro in conjunction with @ref UCS_INIT_ONCE macro. + * See @ref UCS_INIT_ONCE description for details. + */ +#define UCS_CLEANUP_ONCE(_once) \ + for (pthread_mutex_lock(&(_once)->lock); \ + (_once)->initialized || pthread_mutex_unlock(&(_once)->lock); \ + (_once)->initialized = 0) + #endif diff --git a/src/ucs/ucx-ucs.pc.in b/src/ucs/ucx-ucs.pc.in new file mode 100644 index 00000000000..5bd7729cebb --- /dev/null +++ b/src/ucs/ucx-ucs.pc.in @@ -0,0 +1,19 @@ +# +# Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# +# See file LICENSE for terms. +# + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +bindir = @exec_prefix@/bin +libdir = @libdir@ +includedir = @includedir@ + +Name: @PACKAGE@-ucs +Description: Unified Communication X Library UCS module +Version: @VERSION@ +Cflags: -I${includedir} +Libs: -L${libdir} -lucs +Libs.private: -Wl,--undefined=ucs_init @BFD_LDFLAGS@ -pthread -lrt -ldl -lm +Requires: @PACKAGE@-ucm diff --git a/src/uct/Makefile.am b/src/uct/Makefile.am index c7633e9b4a3..1d38401056a 100644 --- a/src/uct/Makefile.am +++ b/src/uct/Makefile.am @@ -76,3 +76,7 @@ libuct_la_SOURCES = \ tcp/sockcm/sockcm_iface.c \ tcp/sockcm/sockcm_ep.c \ tcp/sockcm/sockcm_md.c + +PKG_CONFIG_NAME=uct + +include $(top_srcdir)/config/module-pkg-config.am diff --git a/src/uct/base/uct_component.c b/src/uct/base/uct_component.c index f578cd7eec8..d2bc8b507c5 100644 --- a/src/uct/base/uct_component.c +++ b/src/uct/base/uct_component.c @@ -14,12 +14,39 @@ #include #include #include +#include +#include +#include #include #include UCS_LIST_HEAD(uct_components_list); +UCT_TL_DECL(self) +UCT_TL_DECL(tcp) +UCT_TL_DECL(sockcm) +UCT_TL_DECL(posix) +UCT_TL_DECL(sysv) + +void UCS_F_CTOR uct_init() +{ + uct_self_init(); + uct_tcp_init(); + uct_sockcm_init(); + uct_sysv_init(); + uct_posix_init(); +} + +void UCS_F_DTOR uct_cleanup() +{ + uct_posix_cleanup(); + uct_sysv_cleanup(); + uct_sockcm_cleanup(); + uct_tcp_cleanup(); + uct_self_cleanup(); +} + ucs_status_t uct_query_components(uct_component_h **components_p, unsigned *num_components_p) { @@ -138,3 +165,17 @@ ucs_status_t uct_config_read(uct_config_bundle_t **bundle, err: return status; } + +void uct_component_register(uct_component_t *component) +{ + ucs_list_add_tail(&uct_components_list, &component->list); + ucs_list_add_tail(&ucs_config_global_list, &component->md_config.list); + ucs_list_add_tail(&ucs_config_global_list, &component->cm_config.list); +} + +void uct_component_unregister(uct_component_t *component) +{ + /* TODO: add ucs_list_del(uct_components_list) */ + ucs_list_del(&component->md_config.list); + ucs_list_del(&component->cm_config.list); +} diff --git a/src/uct/base/uct_component.h b/src/uct/base/uct_component.h index 7393f7702f5..a1920229467 100644 --- a/src/uct/base/uct_component.h +++ b/src/uct/base/uct_component.h @@ -134,6 +134,9 @@ typedef ucs_status_t (*uct_component_rkey_release_func_t)( uct_component_t *component, uct_rkey_t rkey, void *handle); +extern ucs_list_link_t uct_components_list; + + /** * Defines a UCT component */ @@ -154,6 +157,9 @@ struct uct_component { }; +#define UCT_COMPONENT_NAME(_name) uct_##_name##_component + + /** * Register a component for usage, so it will be returned from * @ref uct_query_components. @@ -161,7 +167,6 @@ struct uct_component { * @param [in] _component Pointer to a global component structure to register. */ #define UCT_COMPONENT_REGISTER(_component) \ - extern ucs_list_link_t uct_components_list; \ UCS_STATIC_INIT { \ ucs_list_add_tail(&uct_components_list, &(_component)->list); \ } \ @@ -181,4 +186,8 @@ ucs_status_t uct_config_read(uct_config_bundle_t **bundle, size_t config_size, const char *env_prefix, const char *cfg_prefix); +void uct_component_register(uct_component_t *component); + +void uct_component_unregister(uct_component_t *component); + #endif diff --git a/src/uct/base/uct_iface.c b/src/uct/base/uct_iface.c index 51e792e172b..fa395d06c20 100644 --- a/src/uct/base/uct_iface.c +++ b/src/uct/base/uct_iface.c @@ -631,3 +631,15 @@ ucs_config_field_t uct_iface_config_table[] = { {NULL} }; + +void uct_tl_register(uct_component_t *component, uct_tl_t *tl) +{ + ucs_list_add_tail(&ucs_config_global_list, &tl->config.list); + ucs_list_add_tail(&component->tl_list, &tl->list); +} + +void uct_tl_unregister(uct_tl_t *tl) +{ + ucs_list_del(&tl->config.list); + /* TODO: add list_del from ucs_config_global_list */ +} diff --git a/src/uct/base/uct_iface.h b/src/uct/base/uct_iface.h index 85d1194c378..4418b749e57 100644 --- a/src/uct/base/uct_iface.h +++ b/src/uct/base/uct_iface.h @@ -309,6 +309,89 @@ typedef struct uct_tl { } +/** + * Declare TL constructor and destructor + * + * @param [in] _name TL name + */ +#define UCT_TL_DECL(_name) \ + void uct_##_name##_init(void); \ + void uct_##_name##_cleanup(void); + + +/* Helper macro to provide ctor/dtor scope */ +#define _UCT_IFACE_CTOR_ +#define _UCT_IFACE_DTOR_ +#define _UCT_IFACE_CTOR_ctor UCS_F_CTOR +#define _UCT_IFACE_DTOR_ctor UCS_F_DTOR + + +/** + * Register/unregister TL + * + * @param [in] _name Component and TL name + * @param [in] _scope Scope for functions, must be ctor or empty + * @param [in] _init_code Initialization code + * @param [in] _cleanup_code Cleanup code + */ +#define UCT_TL_INIT(_component, _name, _scope, _init_code, _cleanup_code) \ + UCS_PP_EXPAND(_UCT_IFACE_CTOR_##_scope) void uct_##_name##_init(void) \ + { \ + _init_code; \ + uct_tl_register(_component, &UCT_TL_NAME(_name)); \ + } \ + UCS_PP_EXPAND(_UCT_IFACE_DTOR_##_scope) void uct_##_name##_cleanup(void) \ + { \ + uct_tl_unregister(&UCT_TL_NAME(_name)); \ + _cleanup_code; \ + } + + +/** + * Register/unregister component and TL + * + * @param [in] _name Component and TL name + * @param [in] _scope Scope for functions, must be ctor or empty + * @param [in] _init_code Initialization code + * @param [in] _cleanup_code Cleanup code + */ +#define UCT_SINGLE_TL_INIT(_component, _name, _scope, _init_code, \ + _cleanup_code) \ + UCT_TL_INIT(_component, _name, _scope, \ + {_init_code; uct_component_register(_component);}, \ + {uct_component_unregister(_component); _cleanup_code;}) + + +#define UCT_TL_NAME(_name) uct_##_name##_tl + + +/** + * Transport registration routines + * + * @param _component Component to add the transport to + * @param _name Name of the transport (should be a token, not a string) + * @param _query_devices Function to query the list of available devices + * @param _iface_class Struct type defining the uct_iface class + * @param _cfg_prefix Prefix for configuration variables + * @param _cfg_table Transport configuration table + * @param _cfg_struct Struct type defining transport configuration + */ +#define UCT_TL_DEFINE_ENTRY(_component, _name, _query_devices, _iface_class, \ + _cfg_prefix, _cfg_table, _cfg_struct) \ + \ + uct_tl_t UCT_TL_NAME(_name) = { \ + .name = #_name, \ + .query_devices = _query_devices, \ + .iface_open = UCS_CLASS_NEW_FUNC_NAME(_iface_class), \ + .config = { \ + .name = #_name" transport", \ + .prefix = _cfg_prefix, \ + .table = _cfg_table, \ + .size = sizeof(_cfg_struct), \ + } \ + }; + + /** * "Base" structure which defines interface configuration options. * Specific transport extend this structure. @@ -686,4 +769,9 @@ void uct_am_short_fill_data(void *buffer, uint64_t header, const void *payload, memcpy(packet->payload, payload, length); } + +void uct_tl_register(uct_component_t *component, uct_tl_t *tl); + +void uct_tl_unregister(uct_tl_t *tl); + #endif diff --git a/src/uct/configure.m4 b/src/uct/configure.m4 index 338b257e2ec..24f63117330 100644 --- a/src/uct/configure.m4 +++ b/src/uct/configure.m4 @@ -12,4 +12,5 @@ m4_include([src/uct/ugni/configure.m4]) AC_DEFINE_UNQUOTED([uct_MODULES], ["${uct_modules}"], [UCT loadable modules]) -AC_CONFIG_FILES([src/uct/Makefile]) +AC_CONFIG_FILES([src/uct/Makefile + src/uct/ucx-uct.pc]) diff --git a/src/uct/ib/Makefile.am b/src/uct/ib/Makefile.am index 61f2cdd08e6..1a2cb749157 100644 --- a/src/uct/ib/Makefile.am +++ b/src/uct/ib/Makefile.am @@ -144,6 +144,9 @@ endif # HAVE_MLX5_HW_UD endif # HAVE_TL_UD +PKG_CONFIG_NAME=ib + include $(top_srcdir)/config/module.am +include $(top_srcdir)/config/module-pkg-config.am endif # HAVE_IB diff --git a/src/uct/ib/base/ib_md.c b/src/uct/ib/base/ib_md.c index d41a80a8b8e..285bb856425 100644 --- a/src/uct/ib/base/ib_md.c +++ b/src/uct/ib/base/ib_md.c @@ -237,7 +237,50 @@ static const uct_ib_md_pci_info_t uct_ib_md_pci_info[] = { .encoding = 128, .decoding = 130, .name = "gen3" - }, + } +}; + + +extern uct_tl_t UCT_TL_NAME(dc_mlx5); +extern uct_tl_t UCT_TL_NAME(rc_verbs); +extern uct_tl_t UCT_TL_NAME(rc_mlx5); +extern uct_tl_t UCT_TL_NAME(ud_verbs); +extern uct_tl_t UCT_TL_NAME(ud_mlx5); + +static uct_tl_t *uct_ib_tls[] = { +#ifdef HAVE_TL_DC + &UCT_TL_NAME(dc_mlx5), +#endif +#ifdef HAVE_TL_RC + &UCT_TL_NAME(rc_verbs), +#endif +#if defined (HAVE_TL_RC) && defined (HAVE_MLX5_HW) + &UCT_TL_NAME(rc_mlx5), +#endif +#ifdef HAVE_TL_UD + &UCT_TL_NAME(ud_verbs), +#endif +#if defined (HAVE_TL_UD) && defined (HAVE_MLX5_HW_UD) + &UCT_TL_NAME(ud_mlx5) +#endif +}; + +extern uct_ib_md_ops_entry_t UCT_IB_MD_OPS_NAME(devx); +extern uct_ib_md_ops_entry_t UCT_IB_MD_OPS_NAME(dv); +extern uct_ib_md_ops_entry_t UCT_IB_MD_OPS_NAME(exp); +static uct_ib_md_ops_entry_t UCT_IB_MD_OPS_NAME(verbs); + +static uct_ib_md_ops_entry_t *uct_ib_ops[] = { +#if defined (HAVE_MLX5_DV) && defined (HAVE_DEVX) + &UCT_IB_MD_OPS_NAME(devx), +#endif +#if defined (HAVE_MLX5_DV) + &UCT_IB_MD_OPS_NAME(dv), +#endif +#if defined (HAVE_MLX5_HW) && defined (HAVE_VERBS_EXP_H) + &UCT_IB_MD_OPS_NAME(exp), +#endif + &UCT_IB_MD_OPS_NAME(verbs) }; UCS_LIST_HEAD(uct_ib_md_ops_list); @@ -1423,7 +1466,6 @@ ucs_status_t uct_ib_md_open(uct_component_t *component, const char *md_name, ucs_status_t status = UCS_ERR_UNSUPPORTED; uct_ib_md_t *md = NULL; struct ibv_device **ib_device_list, *ib_device; - uct_ib_md_ops_entry_t *md_ops_entry; int i, num_devices, ret; ucs_trace("opening IB device %s", md_name); @@ -1473,18 +1515,18 @@ ucs_status_t uct_ib_md_open(uct_component_t *component, const char *md_name, uct_ib_fork_warn_enable(); } - ucs_list_for_each(md_ops_entry, &uct_ib_md_ops_list, list) { - status = md_ops_entry->ops->open(ib_device, md_config, &md); + for (i = 0; i < ucs_static_array_size(uct_ib_ops); i++) { + status = uct_ib_ops[i]->ops->open(ib_device, md_config, &md); if (status == UCS_OK) { ucs_debug("%s: md open by '%s' is successful", md_name, - md_ops_entry->name); - md->ops = md_ops_entry->ops; + uct_ib_ops[i]->name); + md->ops = uct_ib_ops[i]->ops; break; } else if (status != UCS_ERR_UNSUPPORTED) { goto out_free_dev_list; } ucs_debug("%s: md open by '%s' failed, trying next", md_name, - md_ops_entry->name); + uct_ib_ops[i]->name); } if (status != UCS_OK) { @@ -1681,7 +1723,7 @@ static uct_ib_md_ops_t uct_ib_verbs_md_ops = { .mem_prefetch = (uct_ib_md_mem_prefetch_func_t)ucs_empty_function_return_success, }; -UCT_IB_MD_OPS(uct_ib_verbs_md_ops, 0); +static UCT_IB_MD_DEFINE_ENTRY(verbs, uct_ib_verbs_md_ops); uct_component_t uct_ib_component = { .query_md_resources = uct_ib_query_md_resources, @@ -1701,4 +1743,25 @@ uct_component_t uct_ib_component = { .tl_list = UCT_COMPONENT_TL_LIST_INITIALIZER(&uct_ib_component), .flags = 0 }; -UCT_COMPONENT_REGISTER(&uct_ib_component); + +void UCS_F_CTOR uct_ib_init() +{ + int i; + + uct_component_register(&uct_ib_component); + + for (i = 0; i < ucs_static_array_size(uct_ib_tls); i++) { + uct_tl_register(&uct_ib_component, uct_ib_tls[i]); + } +} + +void UCS_F_DTOR uct_ib_cleanup() +{ + int i; + + for (i = ucs_static_array_size(uct_ib_tls) - 1; i >= 0; i--) { + uct_tl_unregister(uct_ib_tls[i]); + } + + uct_component_unregister(&uct_ib_component); +} diff --git a/src/uct/ib/base/ib_md.h b/src/uct/ib/base/ib_md.h index 31fba82ab6e..5feb9d43462 100644 --- a/src/uct/ib/base/ib_md.h +++ b/src/uct/ib/base/ib_md.h @@ -314,27 +314,17 @@ typedef struct uct_ib_rcache_region { * - determine device attributes and flags */ typedef struct uct_ib_md_ops_entry { - ucs_list_link_t list; const char *name; uct_ib_md_ops_t *ops; - int priority; } uct_ib_md_ops_entry_t; -#define UCT_IB_MD_OPS(_md_ops, _priority) \ - extern ucs_list_link_t uct_ib_md_ops_list; \ - UCS_STATIC_INIT { \ - static uct_ib_md_ops_entry_t *p, entry = { \ - .name = UCS_PP_MAKE_STRING(_md_ops), \ - .ops = &_md_ops, \ - .priority = _priority, \ - }; \ - ucs_list_for_each(p, &uct_ib_md_ops_list, list) { \ - if (p->priority < _priority) { \ - ucs_list_insert_before(&p->list, &entry.list); \ - return; \ - } \ - } \ - ucs_list_add_tail(&uct_ib_md_ops_list, &entry.list); \ + +#define UCT_IB_MD_OPS_NAME(_name) uct_ib_md_ops_##_name##_entry + +#define UCT_IB_MD_DEFINE_ENTRY(_name, _md_ops) \ + uct_ib_md_ops_entry_t UCT_IB_MD_OPS_NAME(_name) = { \ + .name = UCS_PP_MAKE_STRING(_md_ops), \ + .ops = &_md_ops, \ } extern uct_component_t uct_ib_component; diff --git a/src/uct/ib/cm/cm_iface.c b/src/uct/ib/cm/cm_iface.c index b8b08527f28..a0787c0260d 100644 --- a/src/uct/ib/cm/cm_iface.c +++ b/src/uct/ib/cm/cm_iface.c @@ -490,5 +490,8 @@ uct_cm_query_tl_devices(uct_md_h md, uct_tl_device_resource_t **tl_devices_p, tl_devices_p, num_tl_devices_p); } -UCT_TL_DEFINE(&uct_ib_component, cm, uct_cm_query_tl_devices, uct_cm_iface_t, - "CM_", uct_cm_iface_config_table, uct_cm_iface_config_t); +UCT_TL_DEFINE_ENTRY(&uct_ib_component, cm, uct_cm_query_tl_devices, + uct_cm_iface_t, "CM_", uct_cm_iface_config_table, + uct_cm_iface_config_t); + +UCT_SINGLE_TL_INIT(&uct_ib_component, cm,,,) diff --git a/src/uct/ib/cm/configure.m4 b/src/uct/ib/cm/configure.m4 index b7bc0416a05..5738fa4406f 100644 --- a/src/uct/ib/cm/configure.m4 +++ b/src/uct/ib/cm/configure.m4 @@ -30,4 +30,5 @@ AS_IF([test "x$with_cm" != xno], LIBS="$save_LIBS"]) AM_CONDITIONAL([HAVE_TL_CM], [test "x$cm_happy" != xno]) -AC_CONFIG_FILES([src/uct/ib/cm/Makefile]) +AC_CONFIG_FILES([src/uct/ib/cm/Makefile + src/uct/ib/cm/ucx-cm.pc]) diff --git a/src/uct/ib/cm/ucx-cm.pc.in b/src/uct/ib/cm/ucx-cm.pc.in new file mode 100644 index 00000000000..f4dafb60840 --- /dev/null +++ b/src/uct/ib/cm/ucx-cm.pc.in @@ -0,0 +1,16 @@ +# +# Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# +# See file LICENSE for terms. +# + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +libdir = @libdir@/ucx + +Name: @PACKAGE@-cm +Description: Unified Communication X Library IB Connection Manager module +Version: @VERSION@ +Libs: +Libs.private: -L${libdir} -luct_cm -Wl,--undefined=uct_cm_init -libcm + diff --git a/src/uct/ib/configure.m4 b/src/uct/ib/configure.m4 index 9931d7b9583..e05ff11dffd 100644 --- a/src/uct/ib/configure.m4 +++ b/src/uct/ib/configure.m4 @@ -196,6 +196,7 @@ AS_IF([test "x$with_ib" = "xyes"], AC_CHECK_HEADERS([infiniband/mlx5dv.h], [with_mlx5_hw=yes with_mlx5_dv=yes + AC_DEFINE([HAVE_MLX5_DV], 1, [MLX5 DV support]) mlx5_include=mlx5dv.h], [], [ ])]) AS_IF([test "x$with_mlx5_dv" = "xyes" -a "x$have_cq_io" = "xyes" ], [ @@ -448,4 +449,5 @@ uct_ib_modules="" m4_include([src/uct/ib/cm/configure.m4]) m4_include([src/uct/ib/rdmacm/configure.m4]) AC_DEFINE_UNQUOTED([uct_ib_MODULES], ["${uct_ib_modules}"], [IB loadable modules]) -AC_CONFIG_FILES([src/uct/ib/Makefile]) +AC_CONFIG_FILES([src/uct/ib/Makefile + src/uct/ib/ucx-ib.pc]) diff --git a/src/uct/ib/dc/dc_mlx5.c b/src/uct/ib/dc/dc_mlx5.c index 69dc15a58dd..ba4d3e44e35 100644 --- a/src/uct/ib/dc/dc_mlx5.c +++ b/src/uct/ib/dc/dc_mlx5.c @@ -1282,6 +1282,6 @@ uct_dc_mlx5_query_tl_devices(uct_md_h md, uct_tl_device_resource_t **tl_devices_ num_tl_devices_p); } -UCT_TL_DEFINE(&uct_ib_component, dc_mlx5, uct_dc_mlx5_query_tl_devices, - uct_dc_mlx5_iface_t, "DC_MLX5_", uct_dc_mlx5_iface_config_table, - uct_dc_mlx5_iface_config_t); +UCT_TL_DEFINE_ENTRY(&uct_ib_component, dc_mlx5, uct_dc_mlx5_query_tl_devices, + uct_dc_mlx5_iface_t, "DC_MLX5_", + uct_dc_mlx5_iface_config_table, uct_dc_mlx5_iface_config_t); diff --git a/src/uct/ib/mlx5/dv/ib_mlx5dv_md.c b/src/uct/ib/mlx5/dv/ib_mlx5dv_md.c index e71c9c5103e..775ffa19cea 100644 --- a/src/uct/ib/mlx5/dv/ib_mlx5dv_md.c +++ b/src/uct/ib/mlx5/dv/ib_mlx5dv_md.c @@ -767,7 +767,7 @@ static uct_ib_md_ops_t uct_ib_mlx5_devx_md_ops = { .mem_prefetch = uct_ib_mlx5_mem_prefetch, }; -UCT_IB_MD_OPS(uct_ib_mlx5_devx_md_ops, 2); +UCT_IB_MD_DEFINE_ENTRY(devx, uct_ib_mlx5_devx_md_ops); #endif @@ -974,5 +974,5 @@ static uct_ib_md_ops_t uct_ib_mlx5_md_ops = { .mem_prefetch = uct_ib_mlx5_mem_prefetch, }; -UCT_IB_MD_OPS(uct_ib_mlx5_md_ops, 1); +UCT_IB_MD_DEFINE_ENTRY(dv, uct_ib_mlx5_md_ops); diff --git a/src/uct/ib/mlx5/exp/ib_exp_md.c b/src/uct/ib/mlx5/exp/ib_exp_md.c index b60c060d156..0c9a45316e4 100644 --- a/src/uct/ib/mlx5/exp/ib_exp_md.c +++ b/src/uct/ib/mlx5/exp/ib_exp_md.c @@ -726,5 +726,5 @@ static uct_ib_md_ops_t uct_ib_mlx5_md_ops = { .mem_prefetch = uct_ib_mlx5_mem_prefetch, }; -UCT_IB_MD_OPS(uct_ib_mlx5_md_ops, 1); +UCT_IB_MD_DEFINE_ENTRY(exp, uct_ib_mlx5_md_ops); diff --git a/src/uct/ib/rc/accel/rc_mlx5_iface.c b/src/uct/ib/rc/accel/rc_mlx5_iface.c index bfec7072532..a502a3ebbd7 100644 --- a/src/uct/ib/rc/accel/rc_mlx5_iface.c +++ b/src/uct/ib/rc/accel/rc_mlx5_iface.c @@ -888,6 +888,6 @@ uct_rc_mlx5_query_tl_devices(uct_md_h md, uct_tl_device_resource_t **tl_devices_ num_tl_devices_p); } -UCT_TL_DEFINE(&uct_ib_component, rc_mlx5, uct_rc_mlx5_query_tl_devices, - uct_rc_mlx5_iface_t, "RC_MLX5_", uct_rc_mlx5_iface_config_table, - uct_rc_mlx5_iface_config_t); +UCT_TL_DEFINE_ENTRY(&uct_ib_component, rc_mlx5, uct_rc_mlx5_query_tl_devices, + uct_rc_mlx5_iface_t, "RC_MLX5_", + uct_rc_mlx5_iface_config_table, uct_rc_mlx5_iface_config_t); diff --git a/src/uct/ib/rc/verbs/rc_verbs_iface.c b/src/uct/ib/rc/verbs/rc_verbs_iface.c index 41a9c79db8c..ac36fede379 100644 --- a/src/uct/ib/rc/verbs/rc_verbs_iface.c +++ b/src/uct/ib/rc/verbs/rc_verbs_iface.c @@ -449,6 +449,7 @@ uct_rc_verbs_query_tl_devices(uct_md_h md, num_tl_devices_p); } -UCT_TL_DEFINE(&uct_ib_component, rc_verbs, uct_rc_verbs_query_tl_devices, - uct_rc_verbs_iface_t, "RC_VERBS_", uct_rc_verbs_iface_config_table, - uct_rc_verbs_iface_config_t); +UCT_TL_DEFINE_ENTRY(&uct_ib_component, rc_verbs, uct_rc_verbs_query_tl_devices, + uct_rc_verbs_iface_t, "RC_VERBS_", + uct_rc_verbs_iface_config_table, + uct_rc_verbs_iface_config_t); diff --git a/src/uct/ib/rdmacm/Makefile.am b/src/uct/ib/rdmacm/Makefile.am index 0e4ad2403d8..51167ed12fe 100644 --- a/src/uct/ib/rdmacm/Makefile.am +++ b/src/uct/ib/rdmacm/Makefile.am @@ -38,6 +38,9 @@ libuct_rdmacm_la_SOURCES += \ rdmacm_cm_ep.c endif # HAVE_RDMACM_QP_LESS +PKG_CONFIG_NAME=rdmacm + include $(top_srcdir)/config/module.am +include $(top_srcdir)/config/module-pkg-config.am endif # HAVE_RDMACM diff --git a/src/uct/ib/rdmacm/configure.m4 b/src/uct/ib/rdmacm/configure.m4 index 35f078f06e7..ea62346e0cd 100644 --- a/src/uct/ib/rdmacm/configure.m4 +++ b/src/uct/ib/rdmacm/configure.m4 @@ -60,4 +60,5 @@ AS_IF([test "x$with_rdmacm" != xno], AM_CONDITIONAL([HAVE_RDMACM], [test "x$rdmacm_happy" != xno]) AM_CONDITIONAL([HAVE_RDMACM_QP_LESS], [test "x$rdmacm_qp_less_happy" != xno]) -AC_CONFIG_FILES([src/uct/ib/rdmacm/Makefile]) +AC_CONFIG_FILES([src/uct/ib/rdmacm/Makefile + src/uct/ib/rdmacm/ucx-rdmacm.pc]) diff --git a/src/uct/ib/rdmacm/rdmacm_iface.c b/src/uct/ib/rdmacm/rdmacm_iface.c index 178f31644f3..d75fa9afda2 100644 --- a/src/uct/ib/rdmacm/rdmacm_iface.c +++ b/src/uct/ib/rdmacm/rdmacm_iface.c @@ -634,6 +634,8 @@ uct_rdmacm_query_tl_devices(uct_md_h md, uct_tl_device_resource_t **tl_devices_p return UCS_OK; } -UCT_TL_DEFINE(&uct_rdmacm_component, rdmacm, uct_rdmacm_query_tl_devices, - uct_rdmacm_iface_t, "RDMACM_", uct_rdmacm_iface_config_table, - uct_rdmacm_iface_config_t); +UCT_TL_DEFINE_ENTRY(&uct_rdmacm_component, rdmacm, uct_rdmacm_query_tl_devices, + uct_rdmacm_iface_t, "RDMACM_", + uct_rdmacm_iface_config_table, uct_rdmacm_iface_config_t); + +UCT_SINGLE_TL_INIT(&uct_rdmacm_component, rdmacm, ctor,,) diff --git a/src/uct/ib/rdmacm/rdmacm_md.c b/src/uct/ib/rdmacm/rdmacm_md.c index 1e8d46322be..66d4a9d8524 100644 --- a/src/uct/ib/rdmacm/rdmacm_md.c +++ b/src/uct/ib/rdmacm/rdmacm_md.c @@ -275,4 +275,3 @@ uct_component_t uct_rdmacm_component = { .flags = 0 #endif }; -UCT_COMPONENT_REGISTER(&uct_rdmacm_component) diff --git a/src/uct/ib/rdmacm/ucx-rdmacm.pc.in b/src/uct/ib/rdmacm/ucx-rdmacm.pc.in new file mode 100644 index 00000000000..523d15532f8 --- /dev/null +++ b/src/uct/ib/rdmacm/ucx-rdmacm.pc.in @@ -0,0 +1,16 @@ +# +# Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# +# See file LICENSE for terms. +# + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +libdir = @libdir@/ucx + +Name: @PACKAGE@-rdmacm +Description: Unified Communication X Library RDMACM module +Version: @VERSION@ +Libs: +Libs.private: -L${libdir} -luct_rdmacm -Wl,--undefined=uct_rdmacm_init @IBVERBS_LDFLAGS@ @RDMACM_LDFLAGS@ +Requires.private: librdmacm diff --git a/src/uct/ib/ucx-ib.pc.in b/src/uct/ib/ucx-ib.pc.in new file mode 100644 index 00000000000..d467cd58c61 --- /dev/null +++ b/src/uct/ib/ucx-ib.pc.in @@ -0,0 +1,16 @@ +# +# Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# +# See file LICENSE for terms. +# + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +libdir = @libdir@/ucx + +Name: @PACKAGE@-ib +Description: Unified Communication X Library IB module +Version: @VERSION@ +Libs: +Libs.private: -L${libdir} -luct_ib -Wl,--undefined=uct_ib_init @IBVERBS_LDFLAGS@ @NUMA_LIBS@ +Requires.private: libibverbs diff --git a/src/uct/ib/ud/accel/ud_mlx5.c b/src/uct/ib/ud/accel/ud_mlx5.c index 31019ee4b3a..3323342b875 100644 --- a/src/uct/ib/ud/accel/ud_mlx5.c +++ b/src/uct/ib/ud/accel/ud_mlx5.c @@ -887,6 +887,6 @@ uct_ud_mlx5_query_tl_devices(uct_md_h md, tl_devices_p, num_tl_devices_p); } -UCT_TL_DEFINE(&uct_ib_component, ud_mlx5, uct_ud_mlx5_query_tl_devices, - uct_ud_mlx5_iface_t, "UD_MLX5_", uct_ud_mlx5_iface_config_table, - uct_ud_mlx5_iface_config_t); +UCT_TL_DEFINE_ENTRY(&uct_ib_component, ud_mlx5, uct_ud_mlx5_query_tl_devices, + uct_ud_mlx5_iface_t, "UD_MLX5_", + uct_ud_mlx5_iface_config_table, uct_ud_mlx5_iface_config_t); diff --git a/src/uct/ib/ud/verbs/ud_verbs.c b/src/uct/ib/ud/verbs/ud_verbs.c index aa73803329d..e7b052e118e 100644 --- a/src/uct/ib/ud/verbs/ud_verbs.c +++ b/src/uct/ib/ud/verbs/ud_verbs.c @@ -735,6 +735,6 @@ uct_ud_verbs_query_tl_devices(uct_md_h md, num_tl_devices_p); } -UCT_TL_DEFINE(&uct_ib_component, ud_verbs, uct_ud_verbs_query_tl_devices, - uct_ud_verbs_iface_t, "UD_VERBS_", - uct_ud_verbs_iface_config_table, uct_ud_iface_config_t); +UCT_TL_DEFINE_ENTRY(&uct_ib_component, ud_verbs, uct_ud_verbs_query_tl_devices, + uct_ud_verbs_iface_t, "UD_VERBS_", + uct_ud_verbs_iface_config_table, uct_ud_iface_config_t); diff --git a/src/uct/sm/mm/base/mm_iface.h b/src/uct/sm/mm/base/mm_iface.h index df9f3ed143a..7a399d7b865 100644 --- a/src/uct/sm/mm/base/mm_iface.h +++ b/src/uct/sm/mm/base/mm_iface.h @@ -211,18 +211,12 @@ typedef struct uct_mm_iface { * @param _cfg_prefix Prefix for configuration variables. */ #define UCT_MM_TL_DEFINE(_name, _md_ops, _rkey_unpack, _rkey_release, \ - _cfg_prefix) \ - \ - UCT_MM_COMPONENT_DEFINE(uct_##_name##_component, _name, _md_ops, \ - _rkey_unpack, _rkey_release, _cfg_prefix) \ - \ - UCT_TL_DEFINE(&(uct_##_name##_component).super, \ - _name, \ - uct_sm_base_query_tl_devices, \ - uct_mm_iface_t, \ - "MM_", \ - uct_mm_iface_config_table, \ - uct_mm_iface_config_t); + _cfg_prefix, _cfg_table) \ + UCT_MM_COMPONENT_DEFINE(_name, _md_ops, _rkey_unpack, _rkey_release, \ + _cfg_prefix) \ + UCT_TL_DEFINE_ENTRY(&UCT_COMPONENT_NAME(_name).super, _name, \ + uct_sm_base_query_tl_devices, uct_mm_iface_t, \ + _cfg_prefix, _cfg_table, uct_mm_iface_config_t) extern ucs_config_field_t uct_mm_iface_config_table[]; diff --git a/src/uct/sm/mm/base/mm_md.h b/src/uct/sm/mm/base/mm_md.h index 4ad97ddf6e2..9f342de523e 100644 --- a/src/uct/sm/mm/base/mm_md.h +++ b/src/uct/sm/mm/base/mm_md.h @@ -149,10 +149,10 @@ typedef struct uct_mm_component { * @param _md_ops Mapper operations, of type uct_mm_mapper_ops_t. * @param _cfg_prefix Prefix for configuration environment vars. */ -#define UCT_MM_COMPONENT_DEFINE(_var, _name, _md_ops, _rkey_unpack, \ - _rkey_release, _cfg_prefix) \ +#define UCT_MM_COMPONENT_DEFINE(_name, _md_ops, _rkey_unpack, _rkey_release, \ + _cfg_prefix) \ \ - static uct_mm_component_t _var = { \ + static uct_mm_component_t UCT_COMPONENT_NAME(_name) = { \ .super = { \ .query_md_resources = uct_mm_query_md_resources, \ .md_open = uct_mm_md_open, \ @@ -169,12 +169,11 @@ typedef struct uct_mm_component { }, \ .cm_config = UCS_CONFIG_EMPTY_GLOBAL_LIST_ENTRY, \ .tl_list = UCT_COMPONENT_TL_LIST_INITIALIZER( \ - &(_var).super), \ + &UCT_COMPONENT_NAME(_name).super), \ .flags = 0, \ }, \ .md_ops = (_md_ops) \ - }; \ - UCT_COMPONENT_REGISTER(&(_var).super); \ + }; extern ucs_config_field_t uct_mm_md_config_table[]; diff --git a/src/uct/sm/mm/posix/mm_posix.c b/src/uct/sm/mm/posix/mm_posix.c index 2dbe8ed686f..f72138b53d9 100644 --- a/src/uct/sm/mm/posix/mm_posix.c +++ b/src/uct/sm/mm/posix/mm_posix.c @@ -77,6 +77,12 @@ static ucs_config_field_t uct_posix_md_config_table[] = { {NULL} }; +static ucs_config_field_t uct_posix_iface_config_table[] = { + {"MM_", "", NULL, 0, UCS_CONFIG_TYPE_TABLE(uct_mm_iface_config_table)}, + + {NULL} +}; + static int uct_posix_use_shm_open(const uct_posix_md_config_t *posix_config) { return !strcmp(posix_config->dir, UCT_POSIX_SHM_OPEN_DIR); @@ -672,4 +678,7 @@ static uct_mm_md_mapper_ops_t uct_posix_md_ops = { }; UCT_MM_TL_DEFINE(posix, &uct_posix_md_ops, uct_posix_rkey_unpack, - uct_posix_rkey_release, "POSIX_") + uct_posix_rkey_release, "POSIX_", + uct_posix_iface_config_table); + +UCT_SINGLE_TL_INIT(&uct_posix_component.super, posix,,,) diff --git a/src/uct/sm/mm/sysv/mm_sysv.c b/src/uct/sm/mm/sysv/mm_sysv.c index bf4361bbe8a..9f122837f10 100644 --- a/src/uct/sm/mm/sysv/mm_sysv.c +++ b/src/uct/sm/mm/sysv/mm_sysv.c @@ -34,6 +34,12 @@ static ucs_config_field_t uct_sysv_md_config_table[] = { {NULL} }; +static ucs_config_field_t uct_sysv_iface_config_table[] = { + {"MM_", "", NULL, 0, UCS_CONFIG_TYPE_TABLE(uct_mm_iface_config_table)}, + + {NULL} +}; + static ucs_status_t uct_sysv_md_query(uct_md_h md, uct_md_attr_t *md_attr) { uct_mm_md_query(md, md_attr, 1); @@ -195,4 +201,7 @@ static uct_mm_md_mapper_ops_t uct_sysv_md_ops = { }; UCT_MM_TL_DEFINE(sysv, &uct_sysv_md_ops, uct_sysv_rkey_unpack, - uct_sysv_rkey_release, "SYSV_") + uct_sysv_rkey_release, "SYSV_", + uct_sysv_iface_config_table); + +UCT_SINGLE_TL_INIT(&uct_sysv_component.super, sysv,,,) diff --git a/src/uct/sm/mm/xpmem/Makefile.am b/src/uct/sm/mm/xpmem/Makefile.am index cb1fa8ee23a..407bc3ab722 100644 --- a/src/uct/sm/mm/xpmem/Makefile.am +++ b/src/uct/sm/mm/xpmem/Makefile.am @@ -14,6 +14,9 @@ libuct_xpmem_la_LIBADD = $(top_builddir)/src/ucs/libucs.la \ libuct_xpmem_la_LDFLAGS = $(XPMEM_LIBS) -version-info $(SOVERSION) libuct_xpmem_la_SOURCES = mm_xpmem.c +PKG_CONFIG_NAME=xpmem + include $(top_srcdir)/config/module.am +include $(top_srcdir)/config/module-pkg-config.am endif diff --git a/src/uct/sm/mm/xpmem/configure.m4 b/src/uct/sm/mm/xpmem/configure.m4 index b5d8f3b52c7..640549e9170 100644 --- a/src/uct/sm/mm/xpmem/configure.m4 +++ b/src/uct/sm/mm/xpmem/configure.m4 @@ -53,4 +53,5 @@ AS_IF([test "x$xpmem_happy" = "xno" -a -d "$with_xpmem"], AS_IF([test "x$xpmem_happy" = "xyes"], [uct_modules="${uct_modules}:xpmem"]) AM_CONDITIONAL([HAVE_XPMEM], [test "x$xpmem_happy" != "xno"]) -AC_CONFIG_FILES([src/uct/sm/mm/xpmem/Makefile]) +AC_CONFIG_FILES([src/uct/sm/mm/xpmem/Makefile + src/uct/sm/mm/xpmem/ucx-xpmem.pc]) diff --git a/src/uct/sm/mm/xpmem/mm_xpmem.c b/src/uct/sm/mm/xpmem/mm_xpmem.c index e56064df439..01a3ef11dd5 100644 --- a/src/uct/sm/mm/xpmem/mm_xpmem.c +++ b/src/uct/sm/mm/xpmem/mm_xpmem.c @@ -59,7 +59,7 @@ static ucs_init_once_t uct_xpmem_global_seg_init_once = UCS_INIT_ONCE_INITIALIZE static xpmem_segid_t uct_xpmem_global_xsegid = -1; /* Hash of remote regions */ -static khash_t(xpmem_remote_mem) uct_xpmem_remote_mem_hash; +static khash_t(xpmem_remote_mem) uct_xpmem_remote_mem_hash = KHASH_STATIC_INITIALIZER; static ucs_recursive_spinlock_t uct_xpmem_remote_mem_lock; static ucs_config_field_t uct_xpmem_md_config_table[] = { @@ -70,28 +70,11 @@ static ucs_config_field_t uct_xpmem_md_config_table[] = { {NULL} }; -UCS_STATIC_INIT { - ucs_recursive_spinlock_init(&uct_xpmem_remote_mem_lock, 0); - kh_init_inplace(xpmem_remote_mem, &uct_xpmem_remote_mem_hash); -} - -UCS_STATIC_CLEANUP { - uct_xpmem_remote_mem_t *rmem; - ucs_status_t status; - - kh_foreach_value(&uct_xpmem_remote_mem_hash, rmem, { - ucs_warn("remote segment id %lx apid %lx is not released, refcount %d", - (unsigned long)rmem->xsegid, (unsigned long)rmem->apid, - rmem->refcount); - }) - kh_destroy_inplace(xpmem_remote_mem, &uct_xpmem_remote_mem_hash); +static ucs_config_field_t uct_xpmem_iface_config_table[] = { + {"MM_", "", NULL, 0, UCS_CONFIG_TYPE_TABLE(uct_mm_iface_config_table)}, - status = ucs_recursive_spinlock_destroy(&uct_xpmem_remote_mem_lock); - if (status != UCS_OK) { - ucs_warn("ucs_recursive_spinlock_destroy() failed: %s", - ucs_status_string(status)); - } -} + {NULL} +}; static ucs_status_t uct_xpmem_query() { @@ -553,5 +536,33 @@ static uct_mm_md_mapper_ops_t uct_xpmem_md_ops = { .is_reachable = (uct_mm_mapper_is_reachable_func_t)ucs_empty_function_return_one }; +static void uct_xpmem_global_init() +{ + ucs_recursive_spinlock_init(&uct_xpmem_remote_mem_lock, 0); +} + +static void uct_xpmem_global_cleanup() +{ + uct_xpmem_remote_mem_t *rmem; + ucs_status_t status; + + kh_foreach_value(&uct_xpmem_remote_mem_hash, rmem, { + ucs_warn("remote segment id %lx apid %lx is not released, refcount %d", + (unsigned long)rmem->xsegid, (unsigned long)rmem->apid, + rmem->refcount); + }) + kh_destroy_inplace(xpmem_remote_mem, &uct_xpmem_remote_mem_hash); + + status = ucs_recursive_spinlock_destroy(&uct_xpmem_remote_mem_lock); + if (status != UCS_OK) { + ucs_warn("ucs_recursive_spinlock_destroy() failed: %s", + ucs_status_string(status)); + } +} + UCT_MM_TL_DEFINE(xpmem, &uct_xpmem_md_ops, uct_xpmem_rkey_unpack, - uct_xpmem_rkey_release, "XPMEM_") + uct_xpmem_rkey_release, "XPMEM_", + uct_xpmem_iface_config_table); + +UCT_SINGLE_TL_INIT(&uct_xpmem_component.super, xpmem, ctor, + uct_xpmem_global_init(), uct_xpmem_global_cleanup()) diff --git a/src/uct/sm/mm/xpmem/ucx-xpmem.pc.in b/src/uct/sm/mm/xpmem/ucx-xpmem.pc.in new file mode 100644 index 00000000000..785a083ceb4 --- /dev/null +++ b/src/uct/sm/mm/xpmem/ucx-xpmem.pc.in @@ -0,0 +1,16 @@ +# +# Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# +# See file LICENSE for terms. +# + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +libdir = @libdir@/ucx + +Name: @PACKAGE@-xpmem +Description: Unified Communication X Library XPMEM module +Version: @VERSION@ +Libs: +Libs.private: -L${libdir} -luct_xpmem -Wl,--undefined=uct_xpmem_init @XPMEM_LIBS@ + diff --git a/src/uct/sm/scopy/cma/Makefile.am b/src/uct/sm/scopy/cma/Makefile.am index fef489520d2..bce72684b10 100644 --- a/src/uct/sm/scopy/cma/Makefile.am +++ b/src/uct/sm/scopy/cma/Makefile.am @@ -22,6 +22,9 @@ libuct_cma_la_SOURCES = \ cma_ep.c \ cma_md.c +PKG_CONFIG_NAME=cma + include $(top_srcdir)/config/module.am +include $(top_srcdir)/config/module-pkg-config.am endif diff --git a/src/uct/sm/scopy/cma/cma_iface.c b/src/uct/sm/scopy/cma/cma_iface.c index ca26a689dd6..c320c2ebc01 100644 --- a/src/uct/sm/scopy/cma/cma_iface.c +++ b/src/uct/sm/scopy/cma/cma_iface.c @@ -132,6 +132,8 @@ static UCS_CLASS_DEFINE_NEW_FUNC(uct_cma_iface_t, uct_iface_t, uct_md_h, const uct_iface_config_t *); static UCS_CLASS_DEFINE_DELETE_FUNC(uct_cma_iface_t, uct_iface_t); -UCT_TL_DEFINE(&uct_cma_component, cma, uct_sm_base_query_tl_devices, - uct_cma_iface_t, "CMA_", uct_cma_iface_config_table, - uct_cma_iface_config_t); +UCT_TL_DEFINE_ENTRY(&uct_cma_component, cma, uct_sm_base_query_tl_devices, + uct_cma_iface_t, "CMA_", uct_cma_iface_config_table, + uct_cma_iface_config_t); + +UCT_SINGLE_TL_INIT(&uct_cma_component, cma, ctor,,) diff --git a/src/uct/sm/scopy/cma/cma_md.c b/src/uct/sm/scopy/cma/cma_md.c index a8548217adf..81b01737f5b 100644 --- a/src/uct/sm/scopy/cma/cma_md.c +++ b/src/uct/sm/scopy/cma/cma_md.c @@ -190,4 +190,3 @@ uct_component_t uct_cma_component = { .tl_list = UCT_COMPONENT_TL_LIST_INITIALIZER(&uct_cma_component), .flags = 0 }; -UCT_COMPONENT_REGISTER(&uct_cma_component); diff --git a/src/uct/sm/scopy/cma/configure.m4 b/src/uct/sm/scopy/cma/configure.m4 index d8772157979..e3b1b8ef807 100644 --- a/src/uct/sm/scopy/cma/configure.m4 +++ b/src/uct/sm/scopy/cma/configure.m4 @@ -22,4 +22,5 @@ AS_IF([test "x$enable_cma" != xno], ) AM_CONDITIONAL([HAVE_CMA], [test "x$cma_happy" != xno]) -AC_CONFIG_FILES([src/uct/sm/scopy/cma/Makefile]) +AC_CONFIG_FILES([src/uct/sm/scopy/cma/Makefile + src/uct/sm/scopy/cma/ucx-cma.pc]) diff --git a/src/uct/sm/scopy/cma/ucx-cma.pc.in b/src/uct/sm/scopy/cma/ucx-cma.pc.in new file mode 100644 index 00000000000..3d90c6fd3c6 --- /dev/null +++ b/src/uct/sm/scopy/cma/ucx-cma.pc.in @@ -0,0 +1,15 @@ +# +# Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# +# See file LICENSE for terms. +# + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +libdir = @libdir@/ucx + +Name: @PACKAGE@-cma +Description: Unified Communication X Library CMA module +Version: @VERSION@ +Libs: +Libs.private: -L${libdir} -luct_cma -Wl,--undefined=uct_cma_init diff --git a/src/uct/sm/scopy/knem/Makefile.am b/src/uct/sm/scopy/knem/Makefile.am index 46029c12596..4a95ab8f0d6 100644 --- a/src/uct/sm/scopy/knem/Makefile.am +++ b/src/uct/sm/scopy/knem/Makefile.am @@ -22,6 +22,9 @@ libuct_knem_la_SOURCES = \ knem_iface.c \ knem_md.c +PKG_CONFIG_NAME=knem + include $(top_srcdir)/config/module.am +include $(top_srcdir)/config/module-pkg-config.am endif diff --git a/src/uct/sm/scopy/knem/configure.m4 b/src/uct/sm/scopy/knem/configure.m4 index f6290b9692e..0cce261a20a 100644 --- a/src/uct/sm/scopy/knem/configure.m4 +++ b/src/uct/sm/scopy/knem/configure.m4 @@ -34,4 +34,5 @@ AS_IF([test "x$with_knem" != xno], ) AM_CONDITIONAL([HAVE_KNEM], [test "x$knem_happy" != xno]) -AC_CONFIG_FILES([src/uct/sm/scopy/knem/Makefile]) +AC_CONFIG_FILES([src/uct/sm/scopy/knem/Makefile + src/uct/sm/scopy/knem/ucx-knem.pc]) diff --git a/src/uct/sm/scopy/knem/knem_iface.c b/src/uct/sm/scopy/knem/knem_iface.c index ffc079fe64d..449144f2435 100644 --- a/src/uct/sm/scopy/knem/knem_iface.c +++ b/src/uct/sm/scopy/knem/knem_iface.c @@ -88,6 +88,8 @@ static UCS_CLASS_DEFINE_NEW_FUNC(uct_knem_iface_t, uct_iface_t, uct_md_h, const uct_iface_config_t *); static UCS_CLASS_DEFINE_DELETE_FUNC(uct_knem_iface_t, uct_iface_t); -UCT_TL_DEFINE(&uct_knem_component, knem, uct_sm_base_query_tl_devices, - uct_knem_iface_t, "KNEM_", uct_knem_iface_config_table, - uct_knem_iface_config_t); +UCT_TL_DEFINE_ENTRY(&uct_knem_component, knem, uct_sm_base_query_tl_devices, + uct_knem_iface_t, "KNEM_", uct_knem_iface_config_table, + uct_knem_iface_config_t); + +UCT_SINGLE_TL_INIT(&uct_knem_component, knem, ctor,,) diff --git a/src/uct/sm/scopy/knem/knem_md.c b/src/uct/sm/scopy/knem/knem_md.c index af9a673cfc6..550719b351f 100644 --- a/src/uct/sm/scopy/knem/knem_md.c +++ b/src/uct/sm/scopy/knem/knem_md.c @@ -401,4 +401,3 @@ uct_component_t uct_knem_component = { .tl_list = UCT_COMPONENT_TL_LIST_INITIALIZER(&uct_knem_component), .flags = 0 }; -UCT_COMPONENT_REGISTER(&uct_knem_component); diff --git a/src/uct/sm/scopy/knem/ucx-knem.pc.in b/src/uct/sm/scopy/knem/ucx-knem.pc.in new file mode 100644 index 00000000000..c22aa2c0a5c --- /dev/null +++ b/src/uct/sm/scopy/knem/ucx-knem.pc.in @@ -0,0 +1,15 @@ +# +# Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# +# See file LICENSE for terms. +# + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +libdir = @libdir@/ucx + +Name: @PACKAGE@-knem +Description: Unified Communication X Library KNEM module +Version: @VERSION@ +Libs: +Libs.private: -L${libdir} -luct_knem -Wl,--undefined=uct_knem_init diff --git a/src/uct/sm/self/self.c b/src/uct/sm/self/self.c index dad83953425..9a85ca07f12 100644 --- a/src/uct/sm/self/self.c +++ b/src/uct/sm/self/self.c @@ -317,9 +317,6 @@ static uct_iface_ops_t uct_self_iface_ops = { .iface_is_reachable = uct_self_iface_is_reachable }; -UCT_TL_DEFINE(&uct_self_component, self, uct_self_query_tl_devices, uct_self_iface_t, - "SELF_", uct_self_iface_config_table, uct_self_iface_config_t); - static ucs_status_t uct_self_md_query(uct_md_h md, uct_md_attr_t *attr) { /* Dummy memory registration provided. No real memory handling exists */ @@ -391,4 +388,9 @@ static uct_component_t uct_self_component = { .tl_list = UCT_COMPONENT_TL_LIST_INITIALIZER(&uct_self_component), .flags = 0 }; -UCT_COMPONENT_REGISTER(&uct_self_component); + +UCT_TL_DEFINE_ENTRY(&uct_self_component, self, uct_self_query_tl_devices, + uct_self_iface_t, "SELF_", uct_self_iface_config_table, + uct_self_iface_config_t); + +UCT_SINGLE_TL_INIT(&uct_self_component, self,,,) diff --git a/src/uct/tcp/sockcm/sockcm_iface.c b/src/uct/tcp/sockcm/sockcm_iface.c index b24e6f7a6db..ddb51e91daa 100644 --- a/src/uct/tcp/sockcm/sockcm_iface.c +++ b/src/uct/tcp/sockcm/sockcm_iface.c @@ -425,6 +425,8 @@ uct_sockcm_query_tl_devices(uct_md_h md, uct_tl_device_resource_t **tl_devices_p return UCS_OK; } -UCT_TL_DEFINE(&uct_sockcm_component, sockcm, uct_sockcm_query_tl_devices, - uct_sockcm_iface_t, "SOCKCM_", uct_sockcm_iface_config_table, - uct_sockcm_iface_config_t); +UCT_TL_DEFINE_ENTRY(&uct_sockcm_component, sockcm, uct_sockcm_query_tl_devices, + uct_sockcm_iface_t, "SOCKCM_", uct_sockcm_iface_config_table, + uct_sockcm_iface_config_t); + +UCT_SINGLE_TL_INIT(&uct_sockcm_component, sockcm,,,) diff --git a/src/uct/tcp/sockcm/sockcm_md.c b/src/uct/tcp/sockcm/sockcm_md.c index 0d1f6be2823..395e7103442 100644 --- a/src/uct/tcp/sockcm/sockcm_md.c +++ b/src/uct/tcp/sockcm/sockcm_md.c @@ -141,4 +141,3 @@ uct_component_t uct_sockcm_component = { .tl_list = UCT_COMPONENT_TL_LIST_INITIALIZER(&uct_sockcm_component), .flags = 0 }; -UCT_COMPONENT_REGISTER(&uct_sockcm_component) diff --git a/src/uct/tcp/tcp_iface.c b/src/uct/tcp/tcp_iface.c index 65935ee54a0..14cb4c35297 100644 --- a/src/uct/tcp/tcp_iface.c +++ b/src/uct/tcp/tcp_iface.c @@ -673,6 +673,8 @@ ucs_status_t uct_tcp_query_devices(uct_md_h md, return status; } -UCT_TL_DEFINE(&uct_tcp_component, tcp, uct_tcp_query_devices, uct_tcp_iface_t, - UCT_TCP_CONFIG_PREFIX, uct_tcp_iface_config_table, - uct_tcp_iface_config_t); +UCT_TL_DEFINE_ENTRY(&uct_tcp_component, tcp, uct_tcp_query_devices, + uct_tcp_iface_t, UCT_TCP_CONFIG_PREFIX, + uct_tcp_iface_config_table, uct_tcp_iface_config_t); + +UCT_SINGLE_TL_INIT(&uct_tcp_component, tcp,,,) diff --git a/src/uct/tcp/tcp_md.c b/src/uct/tcp/tcp_md.c index e2c24f8ccac..26e0925d7e7 100644 --- a/src/uct/tcp/tcp_md.c +++ b/src/uct/tcp/tcp_md.c @@ -89,4 +89,3 @@ uct_component_t uct_tcp_component = { .tl_list = UCT_COMPONENT_TL_LIST_INITIALIZER(&uct_tcp_component), .flags = UCT_COMPONENT_FLAG_CM }; -UCT_COMPONENT_REGISTER(&uct_tcp_component) diff --git a/src/uct/tcp/tcp_net.c b/src/uct/tcp/tcp_net.c index 8daffb25e6c..e40d8dd9a31 100644 --- a/src/uct/tcp/tcp_net.c +++ b/src/uct/tcp/tcp_net.c @@ -4,12 +4,12 @@ * See file LICENSE for terms. */ -#include "tcp.h" - #ifdef HAVE_CONFIG_H # include "config.h" #endif +#include "tcp.h" + #include #include #include diff --git a/src/uct/ucx-uct.pc.in b/src/uct/ucx-uct.pc.in new file mode 100644 index 00000000000..0a967ed6876 --- /dev/null +++ b/src/uct/ucx-uct.pc.in @@ -0,0 +1,19 @@ +# +# Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# +# See file LICENSE for terms. +# + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +bindir = @exec_prefix@/bin +libdir = @libdir@ +includedir = @includedir@ + +Name: @PACKAGE@-uct +Description: Unified Communication X Library UCT module +Version: @VERSION@ +Cflags: -I${includedir} +Libs: -L${libdir} -luct +Libs.private: -Wl,--undefined=uct_init +Requires: @PACKAGE@-ucs, @PACKAGE@-ucm diff --git a/test/apps/uct_info/Makefile.in b/test/apps/uct_info/Makefile.in new file mode 100644 index 00000000000..bd3fd6741b6 --- /dev/null +++ b/test/apps/uct_info/Makefile.in @@ -0,0 +1,27 @@ +# +# Copyright (C) 2022, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED. +# +# See file LICENSE for terms. +# + +all: uct_info uct_info_static ucp_hello_world_static + +clean: + rm -rf uct_info uct_info_static ucp_hello_world_static + +UCX_CFLAGS = $(CFLAGS) $(shell pkg-config ucx --cflags) +UCT_CFLAGS = $(CFLAGS) $(shell pkg-config ucx-uct --cflags) + +UCT_LDFLAGS = $(LDFLAGS) $(shell pkg-config ucx-uct --libs) + +UCX_STATIC_LDFLAGS = -static $(shell pkg-config --libs --static $(EXTRA_MODULES) ucx) +UCT_STATIC_LDFLAGS = -static $(shell pkg-config --libs --static $(EXTRA_MODULES) ucx-uct) + +uct_info: @abs_srcdir@/uct_info.c + $(CC) -o $@ $? $(UCT_CFLAGS) $(UCT_LDFLAGS) + +uct_info_static: @abs_srcdir@/uct_info.c + $(CC) -o $@ $? $(UCT_CFLAGS) $(UCT_STATIC_LDFLAGS) + +ucp_hello_world_static: @abs_top_srcdir@/test/examples/ucp_hello_world.c + $(CC) -o $@ $? $(UCX_CFLAGS) $(UCX_STATIC_LDFLAGS) diff --git a/test/apps/uct_info/configure.m4 b/test/apps/uct_info/configure.m4 new file mode 100644 index 00000000000..56d61dcdc6e --- /dev/null +++ b/test/apps/uct_info/configure.m4 @@ -0,0 +1,7 @@ +# +# Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# +# See file LICENSE for terms. +# + +AC_CONFIG_FILES([test/apps/uct_info/Makefile]) diff --git a/test/apps/uct_info/uct_info.c b/test/apps/uct_info/uct_info.c new file mode 100644 index 00000000000..a30bff5d89e --- /dev/null +++ b/test/apps/uct_info/uct_info.c @@ -0,0 +1,196 @@ +/** +* Copyright (C) 2022, NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED. +* +* See file LICENSE for terms. +*/ + +#include +#include +#include +#include +#include + +#include +#include +#include + + +#define CALL(_action, _err) \ + do { \ + ucs_status_t UCS_V_UNUSED _status; \ + _status = _action; \ + if (_status != UCS_OK) { \ + _err; \ + } \ + } while (0) + + +#define UCT_CALL(_action, _err) \ + CALL(_action, { \ + printf("ERROR: %s failed\n", #_action); \ + _err; \ + }) + + +static ucs_status_t uct_info_iface_info(uct_worker_h worker, uct_md_h md, + uct_tl_resource_desc_t *resource) +{ + uct_iface_params_t iface_params = { + .field_mask = UCT_IFACE_PARAM_FIELD_OPEN_MODE | + UCT_IFACE_PARAM_FIELD_DEVICE, + .open_mode = UCT_IFACE_OPEN_MODE_DEVICE, + .mode.device.tl_name = resource->tl_name, + .mode.device.dev_name = resource->dev_name + }; + ucs_status_t status = UCS_OK; + uct_iface_config_t *iface_config; + uct_iface_h iface; + + UCT_CALL(uct_md_iface_config_read(md, resource->tl_name, NULL, NULL, + &iface_config), + return _status); + + printf("# Transport: %s\n", resource->tl_name); + printf("# Device: %s\n", resource->dev_name); + + UCT_CALL(uct_iface_open(md, worker, &iface_params, iface_config, &iface), { + status = _status; + goto out; + }); + + uct_iface_close(iface); +out: + uct_config_release(iface_config); + printf("#\n"); + return status; +} + +static ucs_status_t uct_info_tl_info(uct_md_h md, + uct_tl_resource_desc_t *resources, + unsigned num_resources) +{ + ucs_status_t status; + ucs_async_context_t *async; + uct_worker_h worker; + unsigned i; + + UCT_CALL(ucs_async_context_create(UCS_ASYNC_MODE_THREAD_SPINLOCK, &async), + return _status); + UCT_CALL(uct_worker_create(async, UCS_THREAD_MODE_SINGLE, &worker), { + status = _status; + goto destroy_async; + }); + + printf("#\n"); + + if (num_resources == 0) { + printf("# (No supported devices found)\n"); + } + + for (i = 0; i < num_resources; ++i) { + CALL(uct_info_iface_info(worker, md, &resources[i]), break); + } + + uct_worker_destroy(worker); + status = UCS_OK; + +destroy_async: + ucs_async_context_destroy(async); + return status; +} + +static ucs_status_t uct_info_md_info(uct_component_h component, + const uct_component_attr_t *component_attr, + const char *md_name) +{ + ucs_status_t status; + uct_tl_resource_desc_t *resources; + unsigned num_resources; + uct_md_config_t *md_config; + uct_md_attr_t md_attr; + uct_md_h md; + + UCT_CALL(uct_md_config_read(component, NULL, NULL, &md_config), + return _status); + UCT_CALL(uct_md_open(component, md_name, md_config, &md), { + status = _status; + goto out_release_config; + }); + UCT_CALL(uct_md_query_tl_resources(md, &resources, &num_resources), { + status = _status; + goto out_close_md; + }); + UCT_CALL(uct_md_query(md, &md_attr), { + status = _status; + goto out_release_resources; + }); + + printf("#\n"); + printf("# Memory domain: %s\n", md_name); + printf("# Component: %s\n", component_attr->name); + + if (num_resources == 0) { + printf("# < no supported devices found >\n"); + goto out_release_resources; + } + + CALL(uct_info_tl_info(md, resources, num_resources), break); + status = UCS_OK; + +out_release_resources: + uct_release_tl_resource_list(resources); +out_close_md: + uct_md_close(md); +out_release_config: + uct_config_release(md_config); + + return status; +} + +static ucs_status_t uct_info_component(uct_component_h component) +{ + uct_component_attr_t component_attr; + unsigned i; + + component_attr.field_mask = UCT_COMPONENT_ATTR_FIELD_NAME | + UCT_COMPONENT_ATTR_FIELD_MD_RESOURCE_COUNT | + UCT_COMPONENT_ATTR_FIELD_FLAGS; + UCT_CALL(uct_component_query(component, &component_attr), return _status); + + component_attr.field_mask = UCT_COMPONENT_ATTR_FIELD_MD_RESOURCES; + component_attr.md_resources = alloca(sizeof(*component_attr.md_resources) * + component_attr.md_resource_count); + UCT_CALL(uct_component_query(component, &component_attr), return _status); + + for (i = 0; i < component_attr.md_resource_count; ++i) { + CALL(uct_info_md_info(component, &component_attr, + component_attr.md_resources[i].md_name), + return _status); + } + + return UCS_OK; +} + +int main(int argc, char **argv) +{ + int res; + uct_component_h *components; + unsigned num_components; + unsigned i; + + UCT_CALL(uct_query_components(&components, &num_components), + return EXIT_FAILURE); + + for (i = 0; i < num_components; i++) { + CALL(uct_info_component(components[i]), { + res = EXIT_FAILURE; + goto out; + }); + } + + res = EXIT_SUCCESS; + +out: + uct_release_component_list(components); + return res; +} diff --git a/test/gtest/Makefile.am b/test/gtest/Makefile.am index 838695b1308..09e55503ad9 100644 --- a/test/gtest/Makefile.am +++ b/test/gtest/Makefile.am @@ -156,6 +156,7 @@ gtest_SOURCES = \ ucs/test_pgtable.cc \ ucs/test_profile.cc \ ucs/test_rcache.cc \ + ucs/test_khash.cc \ ucs/test_memtype_cache.cc \ ucs/test_stats.cc \ ucs/test_strided_alloc.cc \ diff --git a/test/gtest/ucm/malloc_hook.cc b/test/gtest/ucm/malloc_hook.cc index 1471afd143c..27236d26b63 100644 --- a/test/gtest/ucm/malloc_hook.cc +++ b/test/gtest/ucm/malloc_hook.cc @@ -22,6 +22,7 @@ extern "C" { #include #include #include +#include #include #include } @@ -188,8 +189,11 @@ class malloc_hook : public ucs::test { bistro_patch(const char* symbol, void *hook) { ucs_status_t status; - - status = ucm_bistro_patch(symbol, hook, &m_rp); + void *func_ptr = ucm_reloc_get_orig(symbol, hook); + if (func_ptr == NULL) { + UCS_TEST_ABORT("could not find " << symbol); + } + status = ucm_bistro_patch(func_ptr, hook, &m_rp); ASSERT_UCS_OK(status); EXPECT_NE((intptr_t)m_rp, 0); } @@ -998,6 +1002,7 @@ typedef int (munmap_f_t)(void *addr, size_t len); UCS_TEST_SKIP_COND_F(malloc_hook, bistro_patch, RUNNING_ON_VALGRIND) { const char *symbol = "munmap"; ucm_bistro_restore_point_t *rp = NULL; + void *func_ptr = ucm_reloc_get_orig(symbol, (void*)bistro_hook<0>::munmap); ucs_status_t status; munmap_f_t *munmap_f; void *ptr; @@ -1006,7 +1011,7 @@ UCS_TEST_SKIP_COND_F(malloc_hook, bistro_patch, RUNNING_ON_VALGRIND) { uint64_t UCS_V_UNUSED origin; /* set hook to mmap call */ - status = ucm_bistro_patch(symbol, (void*)bistro_hook<0>::munmap, &rp); + status = ucm_bistro_patch(func_ptr, (void*)bistro_hook<0>::munmap, &rp); ASSERT_UCS_OK(status); EXPECT_NE((intptr_t)rp, 0); diff --git a/test/gtest/ucs/test_khash.cc b/test/gtest/ucs/test_khash.cc new file mode 100644 index 00000000000..0baa67121a4 --- /dev/null +++ b/test/gtest/ucs/test_khash.cc @@ -0,0 +1,27 @@ +/** +* Copyright (C) NVIDIA Corporation. 2022. ALL RIGHTS RESERVED. +*/ + +#include +#include +#include + +KHASH_MAP_INIT_INT64(test_khash, size_t) + +class test_khash : public ucs::test { +}; + +UCS_TEST_F(test_khash, init_inplace) { + khash_t(test_khash) kh_static_init = KHASH_STATIC_INITIALIZER; + khash_t(test_khash) kh_init_inplace; + + memset(&kh_init_inplace, -1, sizeof(kh_init_inplace)); + kh_init_inplace(test_khash, &kh_init_inplace); + + ASSERT_EQ(sizeof(kh_static_init), sizeof(kh_init_inplace)); + + /* Check that static initializer produces same result as kh_init_inplace */ + EXPECT_EQ(0, memcmp(&kh_static_init, &kh_init_inplace, + sizeof(kh_static_init))); +} + diff --git a/test/mpi/test_memhooks.c b/test/mpi/test_memhooks.c index becbf5f4414..071ad6fd719 100644 --- a/test/mpi/test_memhooks.c +++ b/test/mpi/test_memhooks.c @@ -102,7 +102,7 @@ static ucs_status_t set_event_handler(void *dl, int events) static ucs_status_t init_ucm_config(void *dl_ucm, int enable_hooks, ucm_mmap_hook_mode_t mmap_mode) { - void (*library_init)(const ucm_global_config_t *ucm_opts); + void (*library_init)(); ucm_global_config_t *ucm_opts; DL_FIND_FUNC(dl_ucm, "ucm_library_init", library_init, @@ -118,7 +118,7 @@ static ucs_status_t init_ucm_config(void *dl_ucm, int enable_hooks, ucm_opts->mmap_hook_mode = UCM_MMAP_HOOK_NONE; } - library_init(NULL); + library_init(); return UCS_OK; } diff --git a/ucx.pc.in b/ucx.pc.in index d3486fc8507..631ecd46d8e 100644 --- a/ucx.pc.in +++ b/ucx.pc.in @@ -1,3 +1,9 @@ +# +# Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# +# See file LICENSE for terms. +# + prefix = @prefix@ exec_prefix = @exec_prefix@ bindir = @exec_prefix@/bin @@ -5,7 +11,9 @@ libdir = @libdir@ includedir = @includedir@ Name: @PACKAGE@ -Description: Unified Communication X Library -Version: @MAJOR_VERSION@.@MINOR_VERSION@ -Cflags: -I${includedir} -Libs: -L${libdir} -lucs -luct -lucp +Description: Unified Communication X Library +Version: @VERSION@ +Cflags: -I${includedir} +Libs: -L${libdir} -lucp +Libs.private: -Wl,--undefined=ucp_global_init +Requires: @PACKAGE@-uct, @PACKAGE@-ucs, @PACKAGE@-ucm diff --git a/ucx.spec.in b/ucx.spec.in index a0e1f7ac8f2..3a710da1e59 100644 --- a/ucx.spec.in +++ b/ucx.spec.in @@ -126,10 +126,8 @@ make %{?_smp_mflags} V=1 %install make DESTDIR=%{buildroot} install rm -f %{buildroot}%{_libdir}/*.la -rm -f %{buildroot}%{_libdir}/*.a rm -f %{buildroot}%{_libdir}/ucx/*.la rm -f %{buildroot}%{_libdir}/ucx/lib*.so -rm -f %{buildroot}%{_libdir}/ucx/lib*.a %files %{_libdir}/lib*.so.* @@ -145,11 +143,44 @@ rm -f %{buildroot}%{_libdir}/ucx/lib*.a %{_includedir}/uc* %{_libdir}/lib*.so %{_libdir}/pkgconfig/ucx.pc +%{_libdir}/pkgconfig/ucx-uct.pc +%{_libdir}/pkgconfig/ucx-ucs.pc +%{_libdir}/pkgconfig/ucx-ucm.pc %{_datadir}/ucx/examples %post -p /sbin/ldconfig %postun -p /sbin/ldconfig +%package static +Requires: %{name}%{?_isa} = %{version}-%{release} +Summary: Static libraries required for developing with UCX +Group: Development/Libraries + +%description static +Provides static libraries required for developing with UCX. + +%files static +%{_libdir}/lib*.a +%{_libdir}/ucx/lib*.a +%if %{with cma} +%{_libdir}/pkgconfig/ucx-cma.pc +%endif +%if %{with knem} +%{_libdir}/pkgconfig/ucx-knem.pc +%endif +%if %{with xpmem} +%{_libdir}/pkgconfig/ucx-xpmem.pc +%endif +%if %{with ib} +%{_libdir}/pkgconfig/ucx-ib.pc +%endif +%if %{with rdmacm} +%{_libdir}/pkgconfig/ucx-rdmacm.pc +%endif +%if %{with vfs} +%{_libdir}/pkgconfig/ucx-fuse.pc +%endif + %if %{with cma} %package cma Requires: %{name}%{?_isa} = %{version}-%{release}