cuStateVec Ex: Communicator#
cuStateVec Ex API has a communicator that abstracts inter-process communication (IPC) for multi-process state vector operations. The communicator has an interface that provides the common data-transfer functions used during state vector simulations, implemented on top of an IPC library.
This page describes the cuStateVec Ex API communicator interface, its lifecycle, and how to use it from an application. See Communicator for the concepts shared with the cuStateVec API, including the communicator types, the built-in communicators and their supported MPI versions, library resolution, and external communicators.
Note
The cuStateVec Ex API communicator interface, defined in custatevecEx_ext.h, is a preliminary version and subject to change.
Communicator workflow#
The following is the example workflow to use communicator. The following example uses the builtin communicator that wraps Open MPI.
// 1. Application-global initialization - initialize communicator library once
// It uses Open MPI. MPI_Init() is internally called.
custatevecExCommunicatorStatus_t commStatus;
custatevecExCommunicatorInitialize(CUSTATEVEC_COMMUNICATOR_TYPE_OPENMPI,
nullptr, // Use default library path
&argc, &argv, // argc, argv
&commStatus);
// 2. Query global rank and size (before creating instance)
int32_t rank, size;
custatevecExCommunicatorGetSizeAndRank(&size, &rank, &commStatus);
// 3. Create communicator instance
custatevecExCommunicatorDescriptor_t communicator;
custatevecExCommunicatorCreate(&communicator);
// Use communicator for multi-process state vector operations
// ... state vector configuration and simulation logic ...
// 4. Clean up communicator instance
custatevecExCommunicatorDestroy(communicator);
// 5. On application shutdown - finalize communicator library once
// MPI_Finalize() is internally called.
custatevecExCommunicatorFinalize(&commStatus);
Application-global initialization
custatevecExCommunicatorInitialize()selects and loads the communicator implementation and initializes the underlying IPC library. ThecommunicatorTypeargument chooses the implementation:CUSTATEVEC_COMMUNICATOR_TYPE_OPENMPI,CUSTATEVEC_COMMUNICATOR_TYPE_MPICH, orCUSTATEVEC_COMMUNICATOR_TYPE_MPI_ABIfor the built-in MPI communicators, orCUSTATEVEC_COMMUNICATOR_TYPE_EXTERNALfor a custom plugin.For the MPI types, the
libraryPathargument names the shared library to load, andNULLor an empty string selects a default name. The rules for resolving the library, including the case where an MPI library is already available in the process, are described in Communicator.The call to
custatevecExCommunicatorInitialize()is an application-global initialization. During the application lifetime, only a single library is used. The first successful call returnsCUSTATEVEC_STATUS_SUCCESS, and subsequent calls returnCUSTATEVEC_STATUS_ALREADY_INITIALIZED.Getting rank and size.
custatevecExCommunicatorGetSizeAndRank()returns the rank and size.Create communicator instance
After the initialization, communicator instance is created by calling
custatevecExCommunicatorCreate(). The instance is used as an input argument to create multi-process state vector.Destroy communicator instance
After using the communicator instance, communicator is destroyed by
custatevecExCommunicatorDestroy().Application-level finalization
On application shutdown,
custatevecExCommunicatorFinalize()is called to finalize the use of the IPC library.
External communicator#
An external communicator plugin, selected with CUSTATEVEC_COMMUNICATOR_TYPE_EXTERNAL, exposes a factory function named custatevecExCommunicatorGetModuleEXT that returns its module function table. The libraryPath argument names the plugin to load, or may be NULL to resolve the factory function from the application binary itself, so that an application can provide its own communicator without a separate shared object. An example implementation is provided in the exMpiCommunicator.c sample.
Custom MPI initialization#
The builtin communicators with Open MPI and MPICH support the MPI_Init() and MPI_Finalize() called from applications.
// Call MPI_Init() here if an application needs the explicit call to MPI_Init(),
// or needing optional arguments to initialize the library.
MPI_Init(&argc, &argv);
// Application-global initialization
// It does not internally call MPI_Init().
custatevecExCommunicatorStatus_t commStatus;
custatevecExCommunicatorInitialize(CUSTATEVEC_COMMUNICATOR_TYPE_OPENMPI,
nullptr, // Use default library path
nullptr, nullptr, // argc, argv
&commStatus);
// Application main...
// On application shutdown - It does not internally call MPI_Finalize()
custatevecExCommunicatorFinalize(&commStatus);
// Finalize MPI library
MPI_Finalize();
Communicator class and interfaces#
In custatevecEx_ext.h, one struct for class and two interfaces are defined.
custatevecExCommunicatorModule_tLibrary-level initialization and finalization
Version management
custatevecExCommunicator_tCommunicator class
custatevecExCommunicatorInterface_tCommunicator interface
The following three functions in custatevecExCommunicatorInterface_t should accept device memory pointer to directly transfer data on devices.
sendAsyncrecvAsyncsendRecvAsync
The setNativeCommunicator function replaces the native communicator that an instance uses for collectives. For the built-in MPI communicators this is an MPI_Comm, for example &MPI_COMM_WORLD. It takes a pointer to a native communicator handle; a NULL pointer resets the instance to the world communicator. It should be called before the state vector is instantiated, and the communicator must not be changed after a state vector instance is created.
Please refer to the exMpiCommunicator.c sample for the communicator implementation.
Use of communicator from application#
Communicator instance can be utilized from user applications. The following is an example to call communicator function.
if (isMultiProcess) {
int rank;
communicator->intf->getRank(communicator, &rank);
if (rank != 0) {
setOutputEnabled(false); // From common.hpp
}
}