Skip to content

Commit

Permalink
Merge pull request #17561 from boegel/20230318125117_new_pr_OpenMPI50…
Browse files Browse the repository at this point in the history
…0rc10

{mpi}[GCC/13.3.0] OpenMPI v5.0.3, PMIx v5.0.2
  • Loading branch information
bartoldeman authored May 29, 2024
2 parents 846d685 + 4fb223d commit c7b7d1b
Show file tree
Hide file tree
Showing 3 changed files with 221 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
Allow building Open MPI with an internal CUDA header and stub library via
--with-cuda=%(start_dir)s/opal/mca/cuda
by providing an internal minimal cuda.h header file, and function stubs.
This eliminates the CUDA (build)dependency; as long as the runtime CUDA version is 8.0+,
the system's libcuda.so will be used successfully by dynamically loaded plugins in
$EBROOTOPENMPI/lib/openmpi, not by the main libmpi.so.

Author: Bart Oldeman <[email protected]>
diff -urN openmpi-5.0.2.orig/opal/mca/cuda/cuda.c openmpi-5.0.2/opal/mca/cuda/cuda.c
--- openmpi-5.0.2.orig/opal/mca/cuda/lib/cuda.c 1970-01-01 00:00:00.000000000 +0000
+++ openmpi-5.0.2/opal/mca/cuda/lib/cuda.c 2024-02-15 01:39:24.969142045 +0000
@@ -0,0 +1,28 @@
+#include "cuda.h"
+
+CUresult cuPointerGetAttribute(void *, CUpointer_attribute, CUdeviceptr) { return CUDA_ERROR_UNKNOWN; }
+CUresult cuMemcpyAsync(CUdeviceptr, CUdeviceptr, size_t, CUstream) { return CUDA_ERROR_UNKNOWN; }
+CUresult cuMemAlloc(CUdeviceptr *, size_t) { return CUDA_ERROR_UNKNOWN; }
+CUresult cuMemFree(CUdeviceptr buf) { return CUDA_ERROR_UNKNOWN; }
+CUresult cuCtxGetCurrent(void *cuContext) { return CUDA_ERROR_UNKNOWN; }
+CUresult cuStreamCreate(CUstream *, int) { return CUDA_ERROR_UNKNOWN; }
+CUresult cuEventCreate(CUevent *, int) { return CUDA_ERROR_UNKNOWN; }
+CUresult cuEventRecord(CUevent, CUstream) { return CUDA_ERROR_UNKNOWN; }
+CUresult cuEventQuery(CUevent) { return CUDA_ERROR_UNKNOWN; }
+CUresult cuEventDestroy(CUevent) { return CUDA_ERROR_UNKNOWN; }
+CUresult cuMemHostRegister(void *, size_t, unsigned int) { return CUDA_ERROR_UNKNOWN; }
+CUresult cuMemHostUnregister(void *) { return CUDA_ERROR_UNKNOWN; }
+CUresult cuMemGetAddressRange(CUdeviceptr *, size_t *, CUdeviceptr) { return CUDA_ERROR_UNKNOWN; }
+CUresult cuIpcGetEventHandle(CUipcEventHandle *, CUevent) { return CUDA_ERROR_UNKNOWN; }
+CUresult cuIpcOpenEventHandle(CUevent *, CUipcEventHandle) { return CUDA_ERROR_UNKNOWN; }
+CUresult cuIpcOpenMemHandle(CUdeviceptr *, CUipcMemHandle, unsigned int) { return CUDA_ERROR_UNKNOWN; }
+CUresult cuIpcCloseMemHandle(CUdeviceptr) { return CUDA_ERROR_UNKNOWN; }
+CUresult cuIpcGetMemHandle(CUipcMemHandle *, CUdeviceptr) { return CUDA_ERROR_UNKNOWN; }
+CUresult cuCtxGetDevice(CUdevice *) { return CUDA_ERROR_UNKNOWN; }
+CUresult cuDeviceCanAccessPeer(int *, CUdevice, CUdevice) { return CUDA_ERROR_UNKNOWN; }
+CUresult cuCtxSetCurrent(CUcontext) { return CUDA_ERROR_UNKNOWN; }
+CUresult cuStreamSynchronize(CUstream) { return CUDA_ERROR_UNKNOWN; }
+CUresult cuStreamDestroy(CUstream) { return CUDA_ERROR_UNKNOWN; }
+CUresult cuPointerSetAttribute(const void *, CUpointer_attribute, CUdeviceptr) { return CUDA_ERROR_UNKNOWN; }
+CUresult cuDeviceGetPCIBusId(char*, int, CUdevice) { return CUDA_ERROR_UNKNOWN; }
+CUresult cuPointerGetAttributes(unsigned int, CUpointer_attribute *, void **, CUdeviceptr) { return CUDA_ERROR_UNKNOWN; }
diff -urN openmpi-5.0.2.orig/opal/mca/cuda/include/cuda.h openmpi-5.0.2/opal/mca/cuda/include/cuda.h
--- openmpi-5.0.2.orig/opal/mca/cuda/include/cuda.h 1970-01-01 00:00:00.000000000 +0000
+++ openmpi-5.0.2/opal/mca/cuda/include/cuda.h 2024-02-15 03:07:26.480531383 +0000
@@ -0,0 +1,95 @@
+/* This header provides minimal parts of the CUDA Driver API, without having to
+ rely on the proprietary CUDA toolkit.
+
+ References (to avoid copying from NVidia's proprietary cuda.h):
+ https://github.com/gcc-mirror/gcc/blob/master/include/cuda/cuda.h
+ https://github.com/Theano/libgpuarray/blob/master/src/loaders/libcuda.h
+ https://github.com/CPFL/gdev/blob/master/cuda/driver/cuda.h
+ https://github.com/CudaWrangler/cuew/blob/master/include/cuew.h
+*/
+
+#ifndef OMPI_CUDA_H
+#define OMPI_CUDA_H
+
+#include <stddef.h>
+
+#define CUDA_VERSION 8000
+
+typedef void *CUcontext;
+typedef int CUdevice;
+#if defined(__LP64__) || defined(_WIN64)
+typedef unsigned long long CUdeviceptr;
+#else
+typedef unsigned CUdeviceptr;
+#endif
+typedef void *CUevent;
+typedef void *CUstream;
+
+typedef enum {
+ CUDA_SUCCESS = 0,
+ CUDA_ERROR_INVALID_VALUE = 1,
+ CUDA_ERROR_NOT_INITIALIZED = 3,
+ CUDA_ERROR_DEINITIALIZED = 4,
+ CUDA_ERROR_ALREADY_MAPPED = 208,
+ CUDA_ERROR_NOT_READY = 600,
+ CUDA_ERROR_UNKNOWN = 999,
+} CUresult;
+
+enum {
+ CU_EVENT_DISABLE_TIMING = 0x2,
+ CU_EVENT_INTERPROCESS = 0x4,
+};
+
+enum {
+ CU_IPC_MEM_LAZY_ENABLE_PEER_ACCESS = 0x1,
+};
+
+typedef enum {
+ CU_POINTER_ATTRIBUTE_CONTEXT = 1,
+ CU_POINTER_ATTRIBUTE_MEMORY_TYPE = 2,
+ CU_POINTER_ATTRIBUTE_SYNC_MEMOPS = 6,
+ CU_POINTER_ATTRIBUTE_BUFFER_ID = 7,
+ CU_POINTER_ATTRIBUTE_IS_MANAGED = 8,
+} CUpointer_attribute;
+
+typedef enum {
+ CU_MEMORYTYPE_HOST = 0x01,
+} CUmemorytype;
+
+#define CU_IPC_HANDLE_SIZE 64
+typedef struct CUipcEventHandle_st {
+ char reserved[CU_IPC_HANDLE_SIZE];
+} CUipcEventHandle;
+
+typedef struct CUipcMemHandle_st {
+ char reserved[CU_IPC_HANDLE_SIZE];
+} CUipcMemHandle;
+
+CUresult cuPointerGetAttribute(void *, CUpointer_attribute, CUdeviceptr);
+CUresult cuMemcpyAsync(CUdeviceptr, CUdeviceptr, size_t, CUstream);
+CUresult cuMemAlloc(CUdeviceptr *, size_t);
+CUresult cuMemFree(CUdeviceptr buf);
+CUresult cuCtxGetCurrent(void *cuContext);
+CUresult cuStreamCreate(CUstream *, int);
+CUresult cuEventCreate(CUevent *, int);
+CUresult cuEventRecord(CUevent, CUstream);
+CUresult cuEventQuery(CUevent);
+CUresult cuEventDestroy(CUevent);
+CUresult cuMemHostRegister(void *, size_t, unsigned int);
+CUresult cuMemHostUnregister(void *);
+CUresult cuMemGetAddressRange(CUdeviceptr *, size_t *, CUdeviceptr);
+CUresult cuIpcGetEventHandle(CUipcEventHandle *, CUevent);
+CUresult cuIpcOpenEventHandle(CUevent *, CUipcEventHandle);
+CUresult cuIpcOpenMemHandle(CUdeviceptr *, CUipcMemHandle, unsigned int);
+CUresult cuIpcCloseMemHandle(CUdeviceptr);
+CUresult cuIpcGetMemHandle(CUipcMemHandle *, CUdeviceptr);
+CUresult cuCtxGetDevice(CUdevice *);
+CUresult cuDeviceCanAccessPeer(int *, CUdevice, CUdevice);
+CUresult cuCtxSetCurrent(CUcontext);
+CUresult cuStreamSynchronize(CUstream);
+CUresult cuStreamDestroy(CUstream);
+CUresult cuPointerSetAttribute(const void *, CUpointer_attribute, CUdeviceptr);
+CUresult cuDeviceGetPCIBusId(char*, int, CUdevice);
+CUresult cuPointerGetAttributes(unsigned int, CUpointer_attribute *, void **, CUdeviceptr);
+
+#endif
37 changes: 37 additions & 0 deletions easybuild/easyconfigs/o/OpenMPI/OpenMPI-5.0.3-GCC-13.3.0.eb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name = 'OpenMPI'
version = '5.0.3'

homepage = 'https://www.open-mpi.org/'
description = """The Open MPI Project is an open source MPI-3 implementation."""

toolchain = {'name': 'GCC', 'version': '13.3.0'}

source_urls = ['https://www.open-mpi.org/software/ompi/v%(version_major_minor)s/downloads']
sources = [SOURCELOWER_TAR_BZ2]
patches = [('OpenMPI-5.0.2_build-with-internal-cuda-header.patch', 1)]
checksums = [
{'openmpi-5.0.3.tar.bz2': '990582f206b3ab32e938aa31bbf07c639368e4405dca196fabe7f0f76eeda90b'},
{'OpenMPI-5.0.2_build-with-internal-cuda-header.patch':
'f52dc470543f35efef10d651dd159c771ae25f8f76a420d20d87abf4dc769ed7'},
]

builddependencies = [
('pkgconf', '2.2.0'),
('Autotools', '20231222'),
]

dependencies = [
('zlib', '1.3.1'),
('hwloc', '2.10.0'),
('libevent', '2.1.12'),
('UCX', '1.16.0'),
('libfabric', '1.21.0'),
('PMIx', '5.0.2'),
('UCC', '1.3.0'),
]

# CUDA related patches and custom configure option can be removed if CUDA support isn't wanted.
preconfigopts = 'gcc -Iopal/mca/cuda/include -shared opal/mca/cuda/lib/cuda.c -o opal/mca/cuda/lib/libcuda.so && '
configopts = '--with-cuda=%(start_dir)s/opal/mca/cuda --with-show-load-errors=no '

moduleclass = 'mpi'
45 changes: 45 additions & 0 deletions easybuild/easyconfigs/p/PMIx/PMIx-5.0.2-GCCcore-13.3.0.eb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
easyblock = 'ConfigureMake'

name = 'PMIx'
version = '5.0.2'

homepage = 'https://pmix.org/'
description = """Process Management for Exascale Environments
PMI Exascale (PMIx) represents an attempt to
provide an extended version of the PMI standard specifically designed
to support clusters up to and including exascale sizes. The overall
objective of the project is not to branch the existing pseudo-standard
definitions - in fact, PMIx fully supports both of the existing PMI-1
and PMI-2 APIs - but rather to (a) augment and extend those APIs to
eliminate some current restrictions that impact scalability, and (b)
provide a reference implementation of the PMI-server that demonstrates
the desired level of scalability.
"""

toolchain = {'name': 'GCCcore', 'version': '13.3.0'}
toolchainopts = {'pic': True}

source_urls = ['https://github.com/openpmix/openpmix/releases/download/v%(version)s']
sources = ['%(namelower)s-%(version)s.tar.bz2']
checksums = ['28227ff2ba925da2c3fece44502f23a91446017de0f5a58f5cea9370c514b83c']

builddependencies = [('binutils', '2.42')]

dependencies = [
('libevent', '2.1.12'),
('zlib', '1.3.1'),
('hwloc', '2.10.0'),
]

configopts = ' --with-libevent=$EBROOTLIBEVENT --with-zlib=$EBROOTZLIB'
configopts += ' --with-hwloc=$EBROOTHWLOC'
configopts += ' --enable-pmix-binaries'

buildopts = 'V=1'

sanity_check_paths = {
'files': ['bin/pevent', 'bin/plookup', 'bin/pmix_info', 'bin/pps'],
'dirs': ['etc', 'include', 'lib', 'share']
}

moduleclass = 'lib'

0 comments on commit c7b7d1b

Please sign in to comment.