/* automatically generated by rust-bindgen 0.72.1 */

pub const NCCL_MAJOR: u32 = 2;
pub const NCCL_MINOR: u32 = 28;
pub const NCCL_PATCH: u32 = 7;
pub const NCCL_SUFFIX: &[u8; 1] = b"\0";
pub const NCCL_VERSION_CODE: u32 = 22807;
pub const NCCL_UNIQUE_ID_BYTES: u32 = 128;
pub const NCCL_SPLIT_NOCOLOR: i32 = -1;
pub const NCCL_UNDEF_FLOAT: f64 = -1.0;
/// Register buffer into NCCL window with default behavior. The default behavior allows users to
/// pass any offset to the buffer head address as the input of NCCL collective operations. However,
/// this behavior can cause suboptimal performance in NCCL due to the asymmetric buffer usage.
pub const NCCL_WIN_DEFAULT: u32 = 0;
/// Register buffer into NCCL window, and users need to guarantee the offset to the buffer head address
/// from all ranks must be equal when calling NCCL collective operations. It allows NCCL to operate
/// buffer in a symmetric way and provide the best performance.
pub const NCCL_WIN_COLL_SYMMETRIC: u32 = 1;
pub const NCCL_WIN_REQUIRED_ALIGNMENT: u32 = 4096;
/// Use the default CTA policy for NCCL communicator. In this policy, NCCL will automatically adjust resource usage and achieve
/// maximal performance. This policy is suitable for most applications.
pub const NCCL_CTA_POLICY_DEFAULT: u32 = 0;
/// Use the CTA efficiency policy for NCCL communicator. In this policy, NCCL will optimize CTA usage and use minimal
/// number of CTAs to achieve the decent performance when possible. This policy is suitable for applications which require
/// better compute and communication overlap.
pub const NCCL_CTA_POLICY_EFFICIENCY: u32 = 1;
/// Use the Zero-CTA policy for NCCL communicator. In this policy, NCCL will use zero CTA whenever it can, even when that choice
/// may sacrifice some performance. Select this mode when your application must preserve the maximum number of CTAs for compute kernels.
pub const NCCL_CTA_POLICY_ZERO: u32 = 2;
/// These flags modify the behavior of the [`ncclCommShrink`] operation.
///
/// Default behavior. Shrink the parent communicator without affecting ongoing operations.
/// Value: `0x00`.
pub const NCCL_SHRINK_DEFAULT: u32 = 0;
/// First, terminate ongoing parent communicator operations, and then proceed with shrinking the communicator.
/// This is used for error recovery scenarios where the parent communicator might be in a hung state.
/// Resources of parent comm are still not freed, users should decide whether to call ncclCommAbort on the parent communicator after shrink.
/// Value: `0x01`.
pub const NCCL_SHRINK_ABORT: u32 = 1;
pub const NCCL_REVOKE_DEFAULT: u32 = 0;
pub type size_t = ::core::ffi::c_ulong;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct ncclComm {
    _unused: [u8; 0],
}
/// NCCL communicator. Points to an opaque structure inside NCCL.
pub type ncclComm_t = *mut ncclComm;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct ncclWindow_vidmem {
    _unused: [u8; 0],
}
/// NCCL window object for window registration and deregistration.
pub type ncclWindow_t = *mut ncclWindow_vidmem;
#[repr(C)]
#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
pub struct ncclUniqueId {
    pub internal: [::core::ffi::c_char; 128usize],
}
impl Default for ncclUniqueId {
    fn default() -> Self {
        let mut s = ::core::mem::MaybeUninit::<Self>::uninit();
        unsafe {
            ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
            s.assume_init()
        }
    }
}
/// Return values for all NCCL functions. Possible values are.
#[repr(u32)]
#[derive(
    Debug,
    Copy,
    Clone,
    Hash,
    PartialOrd,
    Ord,
    PartialEq,
    Eq,
    TryFromPrimitive,
    IntoPrimitive,
)]
pub enum ncclResult_t {
    /// (`0`)
    /// Function succeeded.
    ncclSuccess = 0,
    /// (`1`)
    /// A call to a CUDA function failed.
    ncclUnhandledCudaError = 1,
    /// (`2`)
    /// A call to the system failed.
    ncclSystemError = 2,
    /// (`3`)
    /// An internal check failed. This is due to either a bug in NCCL or a memory corruption.
    ncclInternalError = 3,
    /// (`4`)
    /// An argument has an invalid value.
    ncclInvalidArgument = 4,
    /// (`5`)
    /// The call to NCCL is incorrect. This is usually reflecting a programming error.
    ncclInvalidUsage = 5,
    /// (`6`)
    /// A call failed possibly due to a network error or a remote process exiting prematurely.
    ncclRemoteError = 6,
    /// (`7`)
    /// A NCCL operation on the communicator is being enqueued and is being progressed in the background.
    ///
    /// Whenever a function returns an error (neither ncclSuccess nor ncclInProgress), NCCL should print a more detailed message when the environment variable [NCCL_DEBUG](env.md#nccl-debug) is set to “WARN”.
    ncclInProgress = 7,
    ncclNumResults = 8,
}
#[repr(C)]
#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
pub struct ncclConfig_v22800 {
    pub size: size_t,
    pub magic: ::core::ffi::c_uint,
    pub version: ::core::ffi::c_uint,
    pub blocking: ::core::ffi::c_int,
    pub cgaClusterSize: ::core::ffi::c_int,
    pub minCTAs: ::core::ffi::c_int,
    pub maxCTAs: ::core::ffi::c_int,
    pub netName: *const ::core::ffi::c_char,
    pub splitShare: ::core::ffi::c_int,
    pub trafficClass: ::core::ffi::c_int,
    pub commName: *const ::core::ffi::c_char,
    pub collnetEnable: ::core::ffi::c_int,
    pub CTAPolicy: ::core::ffi::c_int,
    pub shrinkShare: ::core::ffi::c_int,
    pub nvlsCTAs: ::core::ffi::c_int,
    pub nChannelsPerNetPeer: ::core::ffi::c_int,
    pub nvlinkCentricSched: ::core::ffi::c_int,
}
impl Default for ncclConfig_v22800 {
    fn default() -> Self {
        let mut s = ::core::mem::MaybeUninit::<Self>::uninit();
        unsafe {
            ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
            s.assume_init()
        }
    }
}
/// A structure-based configuration users can set to initialize a communicator; a
/// newly created configuration must be initialized by [`ncclConfig_t::NCCL_CONFIG_INITIALIZER`].
pub type ncclConfig_t = ncclConfig_v22800;
#[repr(C)]
#[derive(Debug, Default, Copy, Clone, PartialOrd, PartialEq)]
pub struct ncclSimInfo_v22200 {
    pub size: size_t,
    pub magic: ::core::ffi::c_uint,
    pub version: ::core::ffi::c_uint,
    pub estimatedTime: f32,
}
/// This struct will be used by ncclGroupSimulateEnd() to return information about the calls.
pub type ncclSimInfo_t = ncclSimInfo_v22200;
unsafe extern "C" {
    /// Allocate a GPU buffer with *size*. Allocated buffer head address will be returned by *ptr*,
    /// and the actual allocated size can be larger than requested because of the buffer granularity
    /// requirements from all types of NCCL optimizations.
    pub fn ncclMemAlloc(
        ptr: *mut *mut ::core::ffi::c_void,
        size: size_t,
    ) -> ncclResult_t;
}
unsafe extern "C" {
    /// Free memory allocated by *ncclMemAlloc()*.
    pub fn ncclMemFree(ptr: *mut ::core::ffi::c_void) -> ncclResult_t;
}
unsafe extern "C" {
    /// The ncclGetVersion function returns the version number of the currently linked NCCL library.
    /// The NCCL version number is returned in *version* and encoded as an integer which includes the
    /// [`NCCL_MAJOR`], [`NCCL_MINOR`] and [`NCCL_PATCH`] levels.
    /// The version number returned will be the same as the [`NCCL_VERSION_CODE`] defined in *nccl.h*.
    /// NCCL version numbers can be compared using the supplied macro `NCCL_VERSION` as `NCCL_VERSION(MAJOR,MINOR,PATCH)`.
    pub fn ncclGetVersion(version: *mut ::core::ffi::c_int) -> ncclResult_t;
}
unsafe extern "C" {
    /// Generates an Id to be used in ncclCommInitRank. ncclGetUniqueId should be
    /// called once when creating a communicator and the Id should be distributed to all ranks in the
    /// communicator before calling ncclCommInitRank. *uniqueId* should point to a ncclUniqueId object allocated by the user.
    pub fn ncclGetUniqueId(uniqueId: *mut ncclUniqueId) -> ncclResult_t;
}
unsafe extern "C" {
    /// This function works the same way as *ncclCommInitRank* but accepts a configuration argument of extra attributes for
    /// the communicator. If config is passed as NULL, the communicator will have the default behavior, as if ncclCommInitRank
    /// was called.
    ///
    /// See the [Creating a communicator with options](usage-communicators.md#init-rank-config) section for details on configuration options.
    pub fn ncclCommInitRankConfig(
        comm: *mut ncclComm_t,
        nranks: ::core::ffi::c_int,
        commId: ncclUniqueId,
        rank: ::core::ffi::c_int,
        config: *mut ncclConfig_t,
    ) -> ncclResult_t;
}
unsafe extern "C" {
    /// Creates a new communicator (multi thread/process version).
    /// *rank* must be between 0 and *nranks*-1 and unique within a communicator clique.
    /// Each rank is associated to a CUDA device, which has to be set before calling
    /// ncclCommInitRank.
    /// ncclCommInitRank implicitly synchronizes with other ranks, hence it must be
    /// called by different threads/processes or used within ncclGroupStart/ncclGroupEnd.
    pub fn ncclCommInitRank(
        comm: *mut ncclComm_t,
        nranks: ::core::ffi::c_int,
        commId: ncclUniqueId,
        rank: ::core::ffi::c_int,
    ) -> ncclResult_t;
}
unsafe extern "C" {
    /// Creates a clique of communicators (single process version) in a blocking way.
    /// This is a convenience function to create a single-process communicator clique.
    /// Returns an array of *ndev* newly initialized communicators in *comms*.
    /// *comms* should be pre-allocated with size at least ndev\*sizeof([[`ncclComm_t`]](api-types.md#c.ncclComm_t "ncclComm_t")).
    /// *devlist* defines the CUDA devices associated with each rank. If *devlist* is NULL,
    /// the first *ndev* CUDA devices are used, in order.
    pub fn ncclCommInitAll(
        comm: *mut ncclComm_t,
        ndev: ::core::ffi::c_int,
        devlist: *const ::core::ffi::c_int,
    ) -> ncclResult_t;
}
unsafe extern "C" {
    /// Finalize a communicator object *comm*. When the communicator is marked as nonblocking, *ncclCommFinalize* is a
    /// nonblocking function. Successful return from it will set communicator state as *ncclInProgress* and indicates
    /// the communicator is under finalization where all uncompleted operations and the network-related resources are
    /// being flushed and freed.
    /// Once all NCCL operations are complete, the communicator will transition to the *ncclSuccess* state. Users
    /// can query that state with *ncclCommGetAsyncError*.
    pub fn ncclCommFinalize(comm: ncclComm_t) -> ncclResult_t;
}
unsafe extern "C" {
    /// Destroy a communicator object *comm*. If *ncclCommFinalize* is called by users, users should guarantee that the state
    /// of the communicator becomes *ncclSuccess* before calling *ncclCommDestroy*. In all cases, the communicator should no
    /// longer be accessed after *ncclCommDestroy* returns. It is recommended that users call *ncclCommFinalize* and then
    /// *ncclCommDestroy*.
    ///
    /// *ncclCommDestroy* will call *ncclCommFinalize* internally, unless *ncclCommFinalize* was previously called on the
    /// communicator. If *ncclCommFinalize* was previously called on the communicator object *comm*, then *ncclCommDestroy* is a
    /// purely local operation.
    ///
    /// This function is an intra-node collective call, which all ranks on the same node should call to avoid a hang.
    pub fn ncclCommDestroy(comm: ncclComm_t) -> ncclResult_t;
}
unsafe extern "C" {
    /// *ncclCommAbort* frees resources that are allocated to a communicator object *comm* and aborts any uncompleted
    /// operations before destroying the communicator. All active ranks are required to call this function in order to
    /// abort the NCCL communicator successfully. For more use cases, please check [Fault Tolerance](usage-communicators.md#ft).
    pub fn ncclCommAbort(comm: ncclComm_t) -> ncclResult_t;
}
unsafe extern "C" {
    /// Revokes in-flight operations on a communicator without destroying resources. Successful return may be *ncclInProgress* (non-blocking) while revocation completes asynchronously; applications can query *ncclCommGetAsyncError* until it returns *ncclSuccess*.
    ///
    /// *revokeFlags* must be set to *NCCL_REVOKE_DEFAULT* (0). Other values are reserved for future use.
    ///
    /// After revoke completes, the communicator is quiesced and safe for destroy, split, and shrink. Launching new collectives on a revoked communicator returns *ncclInvalidUsage*. Calling *ncclCommFinalize* after revoke is not supported. Resource sharing via *splitShare*/*shrinkShare* is disabled when the parent communicator is revoked.
    pub fn ncclCommRevoke(
        comm: ncclComm_t,
        revokeFlags: ::core::ffi::c_int,
    ) -> ncclResult_t;
}
unsafe extern "C" {
    /// The *ncclCommSplit* is a collective function and creates a set of new communicators from an existing one. Ranks which
    /// pass the same *color* value will be part of the same group; color must be a non-negative value. If it is
    /// passed as *NCCL_SPLIT_NOCOLOR*, it means that the rank will not be part of any group, therefore returning NULL
    /// as newcomm.
    /// The value of key will determine the rank order, and the smaller key means the smaller rank in new communicator.
    /// If keys are equal between ranks, then the rank in the original communicator will be used to order ranks.
    /// If the new communicator needs to have a special configuration, it can be passed as *config*, otherwise setting
    /// config to NULL will make the new communicator inherit the original communicator’s configuration.
    /// When split, there should not be any outstanding NCCL operations on the *comm*. Otherwise, it might cause
    /// a deadlock.
    pub fn ncclCommSplit(
        comm: ncclComm_t,
        color: ::core::ffi::c_int,
        key: ::core::ffi::c_int,
        newcomm: *mut ncclComm_t,
        config: *mut ncclConfig_t,
    ) -> ncclResult_t;
}
unsafe extern "C" {
    /// The *ncclCommShrink* function creates a new communicator by removing specified ranks from an existing communicator.
    /// It is a collective function that must be called by all participating ranks in the newly created communicator.
    /// Ranks that are part of *excludeRanksList* should not call this function.
    /// The original ranks listed in *excludeRanksList* (of size *excludeRanksCount*) will be excluded from the new communicator.
    /// Within the new communicator, ranks will be updated to maintain a contiguous set of ids.
    /// If the new communicator needs a special configuration, it can be passed as *config*; otherwise, setting config to NULL will make the new communicator inherit the configuration of the parent communicator.
    ///
    /// The *shrinkFlags* parameter controls the behavior of the operation. Use *NCCL_SHRINK_DEFAULT* (or *0*) for normal operation, or *NCCL_SHRINK_ABORT* when shrinking after an error on the parent communicator.
    /// Specifically, when using *NCCL_SHRINK_DEFAULT*, there should not be any outstanding NCCL operations on the *comm* to avoid potential deadlocks. Further, if the parent communicator has the flag config.shrinkShare set to 1, NCCL will reuse the parent communicator resources.
    /// On the other hand, when using *NCCL_SHRINK_ABORT*, NCCL will automatically abort any outstanding operations on the parent communicator, and no resources will be shared between the parent and the newly created communicator.
    pub fn ncclCommShrink(
        comm: ncclComm_t,
        excludeRanksList: *mut ::core::ffi::c_int,
        excludeRanksCount: ::core::ffi::c_int,
        newcomm: *mut ncclComm_t,
        config: *mut ncclConfig_t,
        shrinkFlags: ::core::ffi::c_int,
    ) -> ncclResult_t;
}
unsafe extern "C" {
    /// This function works the same way as *ncclCommInitRankConfig* but accepts a list of ncclUniqueIds instead of a single one.
    /// If only one ncclUniqueId is passed, the communicator will be initialized as if ncclCommInitRankConfig was called.
    /// The provided ncclUniqueIds will all be used to initialize the single communicator given in argument.
    ///
    /// See the [Creating a communicator with options](usage-communicators.md#init-rank-config) section for details on how to create and distribute the list of ncclUniqueIds.
    pub fn ncclCommInitRankScalable(
        newcomm: *mut ncclComm_t,
        nranks: ::core::ffi::c_int,
        myrank: ::core::ffi::c_int,
        nId: ::core::ffi::c_int,
        commIds: *mut ncclUniqueId,
        config: *mut ncclConfig_t,
    ) -> ncclResult_t;
}
unsafe extern "C" {
    /// Returns a human-readable string corresponding to the passed error code.
    pub fn ncclGetErrorString(result: ncclResult_t) -> *const ::core::ffi::c_char;
}
unsafe extern "C" {
    /// Returns a human-readable string corresponding to the last error that occurred in NCCL.
    /// Note: The error is not cleared by calling this function.
    /// Please note that the string returned by ncclGetLastError could be unrelated to the current call
    /// and can be a result of previously launched asynchronous operations, if any.
    pub fn ncclGetLastError(comm: ncclComm_t) -> *const ::core::ffi::c_char;
}
unsafe extern "C" {
    pub fn ncclResetDebugInit();
}
unsafe extern "C" {
    /// Queries the progress and potential errors of asynchronous NCCL operations.
    /// Operations which do not require a stream argument (e.g. ncclCommFinalize) can be considered complete as soon
    /// as the function returns *ncclSuccess*; operations with a stream argument (e.g. ncclAllReduce) will return
    /// *ncclSuccess* as soon as the operation is posted on the stream but may also report errors through
    /// ncclCommGetAsyncError() until they are completed. If the return code of any NCCL function is *ncclInProgress*,
    /// it means the operation is in the process of being enqueued in the background, and users must query the states
    /// of the communicators until all the states become *ncclSuccess* before calling another NCCL function. Before the
    /// states change into *ncclSuccess*, users are not allowed to issue CUDA kernel to the streams being used by NCCL.
    /// If there has been an error on the communicator, user should destroy the communicator with [`ncclCommAbort`].
    /// If an error occurs on the communicator, nothing can be assumed about the completion or correctness of operations
    /// enqueued on that communicator.
    pub fn ncclCommGetAsyncError(
        comm: ncclComm_t,
        asyncError: *mut ncclResult_t,
    ) -> ncclResult_t;
}
unsafe extern "C" {
    /// Returns in *count* the number of ranks in the NCCL communicator *comm*.
    pub fn ncclCommCount(
        comm: ncclComm_t,
        count: *mut ::core::ffi::c_int,
    ) -> ncclResult_t;
}
unsafe extern "C" {
    /// Returns in *device* the CUDA device associated with the NCCL communicator *comm*.
    pub fn ncclCommCuDevice(
        comm: ncclComm_t,
        device: *mut ::core::ffi::c_int,
    ) -> ncclResult_t;
}
unsafe extern "C" {
    /// Returns in *rank* the rank of the caller in the NCCL communicator *comm*.
    pub fn ncclCommUserRank(
        comm: ncclComm_t,
        rank: *mut ::core::ffi::c_int,
    ) -> ncclResult_t;
}
unsafe extern "C" {
    /// Registers the buffer *buff* with *size* under communicator *comm* for zero-copy communication; *handle* is
    /// returned for future deregistration. See *buff* and *size* requirements and more instructions in [User Buffer Registration](usage-bufferreg.md#user-buffer-reg).
    pub fn ncclCommRegister(
        comm: ncclComm_t,
        buff: *mut ::core::ffi::c_void,
        size: size_t,
        handle: *mut *mut ::core::ffi::c_void,
    ) -> ncclResult_t;
}
unsafe extern "C" {
    /// Deregister buffer represented by *handle* under communicator *comm*.
    pub fn ncclCommDeregister(
        comm: ncclComm_t,
        handle: *mut ::core::ffi::c_void,
    ) -> ncclResult_t;
}
unsafe extern "C" {
    /// Collectively register local buffer *buff* with *size* under communicator *comm* into NCCL window. Since this is a collective call,
    /// every rank in the communicator needs to participate in the registration, and *size* by default needs to be equal among the ranks. *win* is
    /// returned for future deregistration (if called within a group, the value may not be filled in until ncclGroupEnd() has completed).
    /// See *buff* requirement and more instructions in [User Buffer Registration](usage-bufferreg.md#user-buffer-reg). User can also pass
    /// different win flags to control the registration behavior. For more win flags information, please refer to [Window Registration Flags](api-flags.md#win-flags).
    pub fn ncclCommWindowRegister(
        comm: ncclComm_t,
        buff: *mut ::core::ffi::c_void,
        size: size_t,
        win: *mut ncclWindow_t,
        winFlags: ::core::ffi::c_int,
    ) -> ncclResult_t;
}
unsafe extern "C" {
    /// Deregister NCCL window represented by *win* under communicator *comm*. Deregistration is local to the rank, and
    /// caller needs to make sure the corresponding buffer within the window is not being accessed by any NCCL operation.
    pub fn ncclCommWindowDeregister(comm: ncclComm_t, win: ncclWindow_t) -> ncclResult_t;
}
#[repr(u32)]
#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
pub enum ncclRedOp_dummy_t {
    ncclNumOps_dummy = 5,
}
/// Defines the reduction operation.
#[repr(u32)]
#[derive(
    Debug,
    Copy,
    Clone,
    Hash,
    PartialOrd,
    Ord,
    PartialEq,
    Eq,
    TryFromPrimitive,
    IntoPrimitive,
)]
pub enum ncclRedOp_t {
    /// Perform a sum (+) operation.
    ncclSum = 0,
    /// Perform a product (\*) operation.
    ncclProd = 1,
    /// Perform a max operation.
    ncclMax = 2,
    /// Perform a min operation.
    ncclMin = 3,
    /// Perform an average operation, i.e. a sum across all ranks, divided by the number of ranks.
    ncclAvg = 4,
    ncclNumOps = 5,
    ncclMaxRedOp = 2147483647,
}
impl ncclDataType_t {
    pub const ncclChar: ncclDataType_t = ncclDataType_t::ncclInt8;
}
impl ncclDataType_t {
    pub const ncclInt: ncclDataType_t = ncclDataType_t::ncclInt32;
}
impl ncclDataType_t {
    pub const ncclHalf: ncclDataType_t = ncclDataType_t::ncclFloat16;
}
impl ncclDataType_t {
    pub const ncclFloat: ncclDataType_t = ncclDataType_t::ncclFloat32;
}
impl ncclDataType_t {
    pub const ncclDouble: ncclDataType_t = ncclDataType_t::ncclFloat64;
}
/// NCCL defines the following integral and floating data-types.
#[repr(u32)]
#[derive(
    Debug,
    Copy,
    Clone,
    Hash,
    PartialOrd,
    Ord,
    PartialEq,
    Eq,
    TryFromPrimitive,
    IntoPrimitive,
)]
pub enum ncclDataType_t {
    /// Signed 8-bits integer.
    ncclInt8 = 0,
    /// Unsigned 8-bits integer.
    ncclUint8 = 1,
    /// Signed 32-bits integer.
    ncclInt32 = 2,
    /// Unsigned 32-bits integer.
    ncclUint32 = 3,
    /// Signed 64-bits integer.
    ncclInt64 = 4,
    /// Unsigned 64-bits integer.
    ncclUint64 = 5,
    /// 16-bits floating point number (half precision).
    ncclFloat16 = 6,
    /// 32-bits floating point number (single precision).
    ncclFloat32 = 7,
    /// 64-bits floating point number (double precision).
    ncclFloat64 = 8,
    /// 16-bits floating point number (truncated precision in bfloat16 format, CUDA 11 or later).
    ncclBfloat16 = 9,
    /// 8-bits floating point number, 4 exponent bits, 3 mantissa bits (CUDA >= 11.8 and SM >= 90).
    ncclFloat8e4m3 = 10,
    /// 8-bits floating point number, 5 exponent bits, 2 mantissa bits (CUDA >= 11.8 and SM >= 90).
    ncclFloat8e5m2 = 11,
    ncclNumTypes = 12,
}
/// Indicates where (memory space) scalar arguments reside and when they can be
/// dereferenced.
#[repr(u32)]
#[derive(
    Debug,
    Copy,
    Clone,
    Hash,
    PartialOrd,
    Ord,
    PartialEq,
    Eq,
    TryFromPrimitive,
    IntoPrimitive,
)]
pub enum ncclScalarResidence_t {
    /// The scalar resides on device visible memory and should be dereferenced once
    /// needed.
    ncclScalarDevice = 0,
    /// The scalar resides in host memory and should be dereferenced in the most immediate
    /// way.
    ncclScalarHostImmediate = 1,
}
unsafe extern "C" {
    /// Creates a new reduction operator which pre-multiplies input values by a given
    /// scalar locally before reducing them with peer values via summation. Both the
    /// input values and the scalar are of type *datatype*. For use
    /// only with collectives launched against *comm* and *datatype*. The
    /// *residence* argument indicates whether the memory pointed to by *scalar* should be
    /// dereferenced immediately by the host before this function returns
    /// (ncclScalarHostImmediate), or by the device during execution of the reduction
    /// collective (ncclScalarDevice). Upon return, the newly created operator’s handle
    /// is stored in *op*.
    pub fn ncclRedOpCreatePreMulSum(
        op: *mut ncclRedOp_t,
        scalar: *mut ::core::ffi::c_void,
        datatype: ncclDataType_t,
        residence: ncclScalarResidence_t,
        comm: ncclComm_t,
    ) -> ncclResult_t;
}
unsafe extern "C" {
    /// Destroys the reduction operator *op*. The operator must have been created by
    /// ncclRedOpCreatePreMul with the matching communicator *comm*. An operator may be
    /// destroyed as soon as the last NCCL function which is given that operator returns.
    pub fn ncclRedOpDestroy(op: ncclRedOp_t, comm: ncclComm_t) -> ncclResult_t;
}
unsafe extern "C" {
    /// Reduce data arrays of length `count` in `sendbuff` into `recvbuff` on the `root` rank using the `op` operation.
    /// `recvbuff` is only used on rank `root` and ignored for other ranks.
    ///
    /// In-place operation will happen if `sendbuff == recvbuff`.
    ///
    /// Related links: [Reduce](usage-collectives.md#reduce).
    pub fn ncclReduce(
        sendbuff: *const ::core::ffi::c_void,
        recvbuff: *mut ::core::ffi::c_void,
        count: size_t,
        datatype: ncclDataType_t,
        op: ncclRedOp_t,
        root: ::core::ffi::c_int,
        comm: ncclComm_t,
        stream: cudaStream_t,
    ) -> ncclResult_t;
}
unsafe extern "C" {
    /// Legacy in-place version of [`ncclBroadcast`] in a similar fashion to MPI_Bcast. A call to
    ///
    /// ```text
    /// ncclBcast(buff, count, datatype, root, comm, stream)
    /// ```
    ///
    /// is equivalent to
    ///
    /// ```text
    /// ncclBroadcast(buff, buff, count, datatype, root, comm, stream)
    /// ```
    ///
    /// Related links: [Broadcast](usage-collectives.md#broadcast).
    pub fn ncclBcast(
        buff: *mut ::core::ffi::c_void,
        count: size_t,
        datatype: ncclDataType_t,
        root: ::core::ffi::c_int,
        comm: ncclComm_t,
        stream: cudaStream_t,
    ) -> ncclResult_t;
}
unsafe extern "C" {
    /// Copies `count` elements from `sendbuff` on the `root` rank to all ranks’ `recvbuff`.
    /// `sendbuff` is only used on rank `root` and ignored for other ranks.
    ///
    /// In-place operation will happen if `sendbuff == recvbuff`.
    pub fn ncclBroadcast(
        sendbuff: *const ::core::ffi::c_void,
        recvbuff: *mut ::core::ffi::c_void,
        count: size_t,
        datatype: ncclDataType_t,
        root: ::core::ffi::c_int,
        comm: ncclComm_t,
        stream: cudaStream_t,
    ) -> ncclResult_t;
}
unsafe extern "C" {
    /// Reduces data arrays of length `count` in `sendbuff` using the `op` operation and leaves identical copies of the result in each `recvbuff`.
    ///
    /// In-place operation will happen if `sendbuff == recvbuff`.
    ///
    /// Related links: [AllReduce](usage-collectives.md#allreduce).
    pub fn ncclAllReduce(
        sendbuff: *const ::core::ffi::c_void,
        recvbuff: *mut ::core::ffi::c_void,
        count: size_t,
        datatype: ncclDataType_t,
        op: ncclRedOp_t,
        comm: ncclComm_t,
        stream: cudaStream_t,
    ) -> ncclResult_t;
}
unsafe extern "C" {
    /// Reduce data in `sendbuff` from all GPUs using the `op` operation and leave the reduced result scattered over the devices so that the `recvbuff` on
    /// rank `i` will contain the i-th block of the result.
    ///
    /// Note: This assumes the send count is equal to `nranks*recvcount`, which means that `sendbuff` should have a size of at least `nranks*recvcount` elements.
    ///
    /// In-place operation will happen if `recvbuff == sendbuff + rank * recvcount`.
    ///
    /// Related links: [ReduceScatter](usage-collectives.md#reducescatter), [In-place Operations](usage-inplace.md#in-place-operations).
    pub fn ncclReduceScatter(
        sendbuff: *const ::core::ffi::c_void,
        recvbuff: *mut ::core::ffi::c_void,
        recvcount: size_t,
        datatype: ncclDataType_t,
        op: ncclRedOp_t,
        comm: ncclComm_t,
        stream: cudaStream_t,
    ) -> ncclResult_t;
}
unsafe extern "C" {
    /// Gathers `sendcount` values from all GPUs and leaves identical copies of the result in each `recvbuff`, receiving data from rank `i` at offset `i*sendcount`.
    ///
    /// Note: This assumes the receive count is equal to `nranks*sendcount`, which means that `recvbuff` should have a size of at least `nranks*sendcount` elements.
    ///
    /// In-place operation will happen if `sendbuff == recvbuff + rank * sendcount`.
    ///
    /// Related links: [AllGather](usage-collectives.md#allgather), [In-place Operations](usage-inplace.md#in-place-operations).
    pub fn ncclAllGather(
        sendbuff: *const ::core::ffi::c_void,
        recvbuff: *mut ::core::ffi::c_void,
        sendcount: size_t,
        datatype: ncclDataType_t,
        comm: ncclComm_t,
        stream: cudaStream_t,
    ) -> ncclResult_t;
}
unsafe extern "C" {
    /// Each rank sends `count` values to all other ranks and receives `count` values from all other ranks. Data to send to destination rank `j` is taken from `sendbuff+j*count` and data received from source rank `i` is placed at `recvbuff+i*count`.
    ///
    /// Note: This assumes both the total send and receive count is equal to `nranks*count`, which means that `sendbuff` and `recvbuff` should have a size of at least `nranks*count` elements.
    ///
    /// In-place operation is currently not supported.
    ///
    /// Related links: [AlltoAll](usage-collectives.md#alltoall).
    pub fn ncclAlltoAll(
        sendbuff: *const ::core::ffi::c_void,
        recvbuff: *mut ::core::ffi::c_void,
        count: size_t,
        datatype: ncclDataType_t,
        comm: ncclComm_t,
        stream: cudaStream_t,
    ) -> ncclResult_t;
}
unsafe extern "C" {
    /// Each rank sends `count` elements from `sendbuff` to the `root` rank. On the `root` rank, data from rank `i` is placed at `recvbuff + i*count`. On non-root ranks, `recvbuff` is not used.
    ///
    /// Note: This assumes the receive count is equal to `nranks*count`, which means that `recvbuff` should have a size of at least `nranks*count` elements.
    ///
    /// In-place operation will happen if `sendbuff == recvbuff + root * count`.
    ///
    /// Related links: [Gather](usage-collectives.md#gather).
    pub fn ncclGather(
        sendbuff: *const ::core::ffi::c_void,
        recvbuff: *mut ::core::ffi::c_void,
        count: size_t,
        datatype: ncclDataType_t,
        root: ::core::ffi::c_int,
        comm: ncclComm_t,
        stream: cudaStream_t,
    ) -> ncclResult_t;
}
unsafe extern "C" {
    /// Each rank receives `count` elements from the `root` rank. On the `root` rank, `count` elements from `sendbuff + i*count` are sent to rank `i`. On non-root ranks, `sendbuff` is not used.
    ///
    /// Note: This assumes the send count is equal to `nranks*count`, which means that `sendbuff` should have a size of at least `nranks*count` elements.
    ///
    /// In-place operation will happen if `recvbuff == sendbuff + root * count`.
    ///
    /// Related links: [Scatter](usage-collectives.md#scatter).
    pub fn ncclScatter(
        sendbuff: *const ::core::ffi::c_void,
        recvbuff: *mut ::core::ffi::c_void,
        count: size_t,
        datatype: ncclDataType_t,
        root: ::core::ffi::c_int,
        comm: ncclComm_t,
        stream: cudaStream_t,
    ) -> ncclResult_t;
}
unsafe extern "C" {
    /// Send data from `sendbuff` to rank `peer`.
    ///
    /// Rank `peer` needs to call ncclRecv with the same `datatype` and the same `count` as this rank.
    ///
    /// This operation is blocking for the GPU. If multiple [`ncclSend`] and [`ncclRecv`] operations
    /// need to progress concurrently to complete, they must be fused within a [[`ncclGroupStart`]](api-group.md#c.ncclGroupStart "ncclGroupStart")/
    /// [[`ncclGroupEnd`]](api-group.md#c.ncclGroupEnd "ncclGroupEnd") section.
    ///
    /// Related links: [Point-to-point communication](api-p2p.md#point-to-point).
    pub fn ncclSend(
        sendbuff: *const ::core::ffi::c_void,
        count: size_t,
        datatype: ncclDataType_t,
        peer: ::core::ffi::c_int,
        comm: ncclComm_t,
        stream: cudaStream_t,
    ) -> ncclResult_t;
}
unsafe extern "C" {
    /// Receive data from rank `peer` into `recvbuff`.
    ///
    /// Rank `peer` needs to call ncclSend with the same `datatype` and the same `count` as this rank.
    ///
    /// This operation is blocking for the GPU. If multiple [`ncclSend`] and [`ncclRecv`] operations
    /// need to progress concurrently to complete, they must be fused within a [[`ncclGroupStart`]](api-group.md#c.ncclGroupStart "ncclGroupStart")/
    /// [[`ncclGroupEnd`]](api-group.md#c.ncclGroupEnd "ncclGroupEnd") section.
    ///
    /// Related links: [Point-to-point communication](api-p2p.md#point-to-point).
    pub fn ncclRecv(
        recvbuff: *mut ::core::ffi::c_void,
        count: size_t,
        datatype: ncclDataType_t,
        peer: ::core::ffi::c_int,
        comm: ncclComm_t,
        stream: cudaStream_t,
    ) -> ncclResult_t;
}
unsafe extern "C" {
    /// Start a group call.
    ///
    /// All subsequent calls to NCCL until ncclGroupEnd will not block due to inter-CPU synchronization.
    pub fn ncclGroupStart() -> ncclResult_t;
}
unsafe extern "C" {
    /// End a group call.
    ///
    /// Returns when all operations since ncclGroupStart have been processed. This means the communication primitives
    /// have been enqueued to the provided streams, but are not necessarily complete.
    ///
    /// When used with the ncclCommInitRank call, the ncclGroupEnd call waits for all communicators to be initialized.
    pub fn ncclGroupEnd() -> ncclResult_t;
}
unsafe extern "C" {
    /// Simulate a ncclGroupEnd() call and return NCCL’s simulation info in a structure passed as an argument.
    pub fn ncclGroupSimulateEnd(simInfo: *mut ncclSimInfo_t) -> ncclResult_t;
}
