#![cfg_attr(test, allow(clippy::unwrap_used))]
#![no_std]
#![deny(unsafe_op_in_unsafe_fn)]
pub mod ffi {
#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
}
#[allow(clippy::cast_possible_truncation)]
pub const NVTX_VERSION: i16 = ffi::NVTX_VERSION as i16;
pub type RangeId = ffi::nvtxRangeId_t;
pub type EventAttributes = ffi::nvtxEventAttributes_t;
pub const NVTX_EVENT_ATTRIBUTES_SIZE: usize = core::mem::size_of::<EventAttributes>();
pub type ResourceAttributes = ffi::nvtxResourceAttributes_t;
pub const NVTX_RESOURCE_ATTRIBUTES_SIZE: usize = core::mem::size_of::<ResourceAttributes>();
pub type SyncUserAttributes = ffi::nvtxSyncUserAttributes_t;
pub const NVTX_SYNC_USER_ATTRIBUTES_SIZE: usize = core::mem::size_of::<SyncUserAttributes>();
pub type ResourceAttributesIdentifier = ffi::nvtxResourceAttributes_v0_identifier_t;
pub type ColorType = ffi::nvtxColorType_t;
pub type MessageType = ffi::nvtxMessageType_t;
pub type MessageValue = ffi::nvtxMessageValue_t;
pub type PayloadType = ffi::nvtxPayloadType_t;
pub type PayloadValue = ffi::nvtxEventAttributes_v2_payload_t;
macro_rules! impl_from_repr_u32_enum_for_i32 {
($($ty:ty),+ $(,)?) => {
$(
impl ::core::convert::From<$ty> for i32 {
fn from(value: $ty) -> Self {
value as i32
}
}
)+
};
}
impl_from_repr_u32_enum_for_i32!(ColorType, MessageType, PayloadType);
#[cfg(test)]
mod tests {
use super::*;
fn assert_fits_nvtx_i32_field<T>(name: &str, value: T)
where
T: Into<i32>,
{
assert!(
value.into() >= 0,
"{name} must fit in NVTX's signed 32-bit type fields"
);
}
#[test]
fn enum_type_values_fit_nvtx_i32_fields() {
assert_fits_nvtx_i32_field("NVTX_COLOR_UNKNOWN", ColorType::NVTX_COLOR_UNKNOWN);
assert_fits_nvtx_i32_field("NVTX_COLOR_ARGB", ColorType::NVTX_COLOR_ARGB);
assert_fits_nvtx_i32_field("NVTX_MESSAGE_UNKNOWN", MessageType::NVTX_MESSAGE_UNKNOWN);
assert_fits_nvtx_i32_field(
"NVTX_MESSAGE_TYPE_ASCII",
MessageType::NVTX_MESSAGE_TYPE_ASCII,
);
assert_fits_nvtx_i32_field(
"NVTX_MESSAGE_TYPE_UNICODE",
MessageType::NVTX_MESSAGE_TYPE_UNICODE,
);
assert_fits_nvtx_i32_field(
"NVTX_MESSAGE_TYPE_REGISTERED",
MessageType::NVTX_MESSAGE_TYPE_REGISTERED,
);
assert_fits_nvtx_i32_field("NVTX_PAYLOAD_UNKNOWN", PayloadType::NVTX_PAYLOAD_UNKNOWN);
assert_fits_nvtx_i32_field(
"NVTX_PAYLOAD_TYPE_UNSIGNED_INT64",
PayloadType::NVTX_PAYLOAD_TYPE_UNSIGNED_INT64,
);
assert_fits_nvtx_i32_field(
"NVTX_PAYLOAD_TYPE_INT64",
PayloadType::NVTX_PAYLOAD_TYPE_INT64,
);
assert_fits_nvtx_i32_field(
"NVTX_PAYLOAD_TYPE_DOUBLE",
PayloadType::NVTX_PAYLOAD_TYPE_DOUBLE,
);
assert_fits_nvtx_i32_field(
"NVTX_PAYLOAD_TYPE_UNSIGNED_INT32",
PayloadType::NVTX_PAYLOAD_TYPE_UNSIGNED_INT32,
);
assert_fits_nvtx_i32_field(
"NVTX_PAYLOAD_TYPE_INT32",
PayloadType::NVTX_PAYLOAD_TYPE_INT32,
);
assert_fits_nvtx_i32_field(
"NVTX_PAYLOAD_TYPE_FLOAT",
PayloadType::NVTX_PAYLOAD_TYPE_FLOAT,
);
}
}
#[derive(Debug, Clone, Copy)]
pub struct DomainHandle {
handle: ffi::nvtxDomainHandle_t,
}
unsafe impl Send for DomainHandle {}
unsafe impl Sync for DomainHandle {}
#[derive(Clone, Copy, PartialEq, Eq)]
pub struct ResourceHandle {
handle: ffi::nvtxResourceHandle_t,
}
unsafe impl Send for ResourceHandle {}
unsafe impl Sync for ResourceHandle {}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct StringHandle {
handle: ffi::nvtxStringHandle_t,
}
impl From<StringHandle> for ffi::nvtxStringHandle_t {
fn from(value: StringHandle) -> Self {
value.handle
}
}
unsafe impl Send for StringHandle {}
unsafe impl Sync for StringHandle {}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct SyncUserHandle {
handle: ffi::nvtxSyncUser_t,
}
unsafe impl Send for SyncUserHandle {}
unsafe impl Sync for SyncUserHandle {}
#[cfg(feature = "cuda_runtime")]
pub type CudaEvent = ffi::cudaEvent_t;
#[cfg(feature = "cuda_runtime")]
pub type CudaStream = ffi::cudaStream_t;
#[cfg(feature = "cuda")]
pub type CuContext = ffi::CUcontext;
#[cfg(feature = "cuda")]
pub type CuDevice = ffi::CUdevice;
#[cfg(feature = "cuda")]
pub type CuEvent = ffi::CUevent;
#[cfg(feature = "cuda")]
pub type CuStream = ffi::CUstream;
pub mod resource_type {
#![allow(clippy::wildcard_imports)]
#![allow(clippy::unnecessary_cast)]
use crate::ffi::nvtxResourceGenericType_t::*;
pub const UNKNOWN: u32 = NVTX_RESOURCE_TYPE_UNKNOWN as u32;
pub const GENERIC_HANDLE: u32 = NVTX_RESOURCE_TYPE_GENERIC_HANDLE as u32;
pub const GENERIC_POINTER: u32 = NVTX_RESOURCE_TYPE_GENERIC_POINTER as u32;
pub const GENERIC_THREAD_NATIVE: u32 = NVTX_RESOURCE_TYPE_GENERIC_THREAD_NATIVE as u32;
pub const GENERIC_THREAD_POSIX: u32 = NVTX_RESOURCE_TYPE_GENERIC_THREAD_POSIX as u32;
#[cfg(feature = "cuda")]
mod cuda {
use crate::ffi::nvtxResourceCUDAType_t::*;
pub const CUDA_DEVICE: u32 = NVTX_RESOURCE_TYPE_CUDA_DEVICE as u32;
pub const CUDA_CONTEXT: u32 = NVTX_RESOURCE_TYPE_CUDA_CONTEXT as u32;
pub const CUDA_STREAM: u32 = NVTX_RESOURCE_TYPE_CUDA_STREAM as u32;
pub const CUDA_EVENT: u32 = NVTX_RESOURCE_TYPE_CUDA_EVENT as u32;
}
#[cfg(feature = "cuda")]
pub use cuda::*;
#[cfg(feature = "cuda_runtime")]
mod cuda_runtime {
use crate::ffi::nvtxResourceCUDARTType_t::*;
pub const CUDART_DEVICE: u32 = NVTX_RESOURCE_TYPE_CUDART_DEVICE as u32;
pub const CUDART_STREAM: u32 = NVTX_RESOURCE_TYPE_CUDART_STREAM as u32;
pub const CUDART_EVENT: u32 = NVTX_RESOURCE_TYPE_CUDART_EVENT as u32;
}
#[cfg(feature = "cuda_runtime")]
pub use cuda_runtime::*;
#[cfg(target_family = "unix")]
mod pthread {
use crate::ffi::nvtxResourceSyncPosixThreadType_t::*;
pub const PTHREAD_MUTEX: u32 = NVTX_RESOURCE_TYPE_SYNC_PTHREAD_MUTEX as u32;
pub const PTHREAD_CONDITION: u32 = NVTX_RESOURCE_TYPE_SYNC_PTHREAD_CONDITION as u32;
pub const PTHREAD_RWLOCK: u32 = NVTX_RESOURCE_TYPE_SYNC_PTHREAD_RWLOCK as u32;
pub const PTHREAD_BARRIER: u32 = NVTX_RESOURCE_TYPE_SYNC_PTHREAD_BARRIER as u32;
pub const PTHREAD_SPINLOCK: u32 = NVTX_RESOURCE_TYPE_SYNC_PTHREAD_SPINLOCK as u32;
pub const PTHREAD_ONCE: u32 = NVTX_RESOURCE_TYPE_SYNC_PTHREAD_ONCE as u32;
}
#[cfg(target_family = "unix")]
pub use pthread::*;
}
use core::ffi::CStr;
use widestring::WideCStr;
pub fn domain_mark_ex(domain: DomainHandle, event_attrib: &EventAttributes) {
unsafe { crate::ffi::nvtxDomainMarkEx(domain.handle, event_attrib) }
}
pub fn mark_ex(event_attrib: &EventAttributes) {
unsafe { crate::ffi::nvtxMarkEx(event_attrib) }
}
pub fn mark_ascii(message: &CStr) {
unsafe { crate::ffi::nvtxMarkA(message.as_ptr()) }
}
pub fn mark_unicode(message: &WideCStr) {
unsafe { crate::ffi::nvtxMarkW(message.as_ptr().cast()) }
}
#[must_use]
pub fn domain_range_start_ex(domain: DomainHandle, event_attrib: &EventAttributes) -> RangeId {
unsafe { crate::ffi::nvtxDomainRangeStartEx(domain.handle, event_attrib) }
}
#[must_use]
pub fn range_start_ex(event_attrib: &EventAttributes) -> RangeId {
unsafe { crate::ffi::nvtxRangeStartEx(event_attrib) }
}
#[must_use]
pub fn range_start_ascii(message: &CStr) -> RangeId {
unsafe { crate::ffi::nvtxRangeStartA(message.as_ptr()) }
}
#[must_use]
pub fn range_start_unicode(message: &WideCStr) -> RangeId {
unsafe { crate::ffi::nvtxRangeStartW(message.as_ptr().cast()) }
}
pub fn domain_range_end(domain: DomainHandle, id: RangeId) {
unsafe { crate::ffi::nvtxDomainRangeEnd(domain.handle, id) }
}
pub fn range_end(id: RangeId) {
unsafe { crate::ffi::nvtxRangeEnd(id) }
}
#[allow(clippy::must_use_candidate)]
pub fn domain_range_push_ex(domain: DomainHandle, event_attrib: &EventAttributes) -> i32 {
unsafe { crate::ffi::nvtxDomainRangePushEx(domain.handle, event_attrib) }
}
#[allow(clippy::must_use_candidate)]
pub fn range_push_ex(event_attrib: &EventAttributes) -> i32 {
unsafe { crate::ffi::nvtxRangePushEx(event_attrib) }
}
#[allow(clippy::must_use_candidate)]
pub fn range_push_ascii(message: &CStr) -> i32 {
unsafe { crate::ffi::nvtxRangePushA(message.as_ptr()) }
}
#[allow(clippy::must_use_candidate)]
pub fn range_push_unicode(message: &WideCStr) -> i32 {
unsafe { crate::ffi::nvtxRangePushW(message.as_ptr().cast()) }
}
#[allow(clippy::must_use_candidate)]
pub fn domain_range_pop(domain: DomainHandle) -> i32 {
unsafe { crate::ffi::nvtxDomainRangePop(domain.handle) }
}
#[allow(clippy::must_use_candidate)]
pub fn range_pop() -> i32 {
unsafe { crate::ffi::nvtxRangePop() }
}
#[must_use]
pub fn domain_resource_create(domain: DomainHandle, attribs: ResourceAttributes) -> ResourceHandle {
ResourceHandle {
handle: unsafe {
crate::ffi::nvtxDomainResourceCreate(
domain.handle,
core::ptr::addr_of!(attribs).cast_mut(),
)
},
}
}
pub fn domain_resource_destroy(resource: ResourceHandle) {
unsafe { crate::ffi::nvtxDomainResourceDestroy(resource.handle) }
}
pub fn domain_name_category_ascii(domain: DomainHandle, category: u32, name: &CStr) {
unsafe { crate::ffi::nvtxDomainNameCategoryA(domain.handle, category, name.as_ptr()) }
}
pub fn domain_name_category_unicode(domain: DomainHandle, category: u32, name: &WideCStr) {
unsafe { crate::ffi::nvtxDomainNameCategoryW(domain.handle, category, name.as_ptr().cast()) }
}
pub fn name_category_ascii(category: u32, name: &CStr) {
unsafe { crate::ffi::nvtxNameCategoryA(category, name.as_ptr()) }
}
pub fn name_category_unicode(category: u32, name: &WideCStr) {
unsafe { crate::ffi::nvtxNameCategoryW(category, name.as_ptr().cast()) }
}
pub fn name_os_thread_ascii(thread_id: u32, name: &CStr) {
unsafe { crate::ffi::nvtxNameOsThreadA(thread_id, name.as_ptr()) }
}
pub fn name_os_thread_unicode(thread_id: u32, name: &WideCStr) {
unsafe { crate::ffi::nvtxNameOsThreadW(thread_id, name.as_ptr().cast()) }
}
#[must_use]
pub fn domain_register_string_ascii(domain: DomainHandle, string: &CStr) -> StringHandle {
StringHandle {
handle: unsafe { crate::ffi::nvtxDomainRegisterStringA(domain.handle, string.as_ptr()) },
}
}
#[must_use]
pub fn domain_register_string_unicode(domain: DomainHandle, string: &WideCStr) -> StringHandle {
StringHandle {
handle: unsafe {
crate::ffi::nvtxDomainRegisterStringW(domain.handle, string.as_ptr().cast())
},
}
}
#[must_use]
pub fn domain_create_ascii(name: &CStr) -> DomainHandle {
DomainHandle {
handle: unsafe { crate::ffi::nvtxDomainCreateA(name.as_ptr()) },
}
}
#[must_use]
pub fn domain_create_unicode(name: &WideCStr) -> DomainHandle {
DomainHandle {
handle: unsafe { crate::ffi::nvtxDomainCreateW(name.as_ptr().cast()) },
}
}
pub fn domain_destroy(domain: DomainHandle) {
unsafe { crate::ffi::nvtxDomainDestroy(domain.handle) }
}
#[cfg(feature = "cuda")]
pub fn name_cudevice_ascii(device: CuDevice, name: &CStr) {
unsafe { crate::ffi::nvtxNameCuDeviceA(device, name.as_ptr()) }
}
#[cfg(feature = "cuda")]
pub fn name_cudevice_unicode(device: CuDevice, name: &WideCStr) {
unsafe { crate::ffi::nvtxNameCuDeviceW(device, name.as_ptr().cast()) }
}
#[cfg(feature = "cuda")]
pub unsafe fn name_cucontext_ascii(context: CuContext, name: &CStr) {
unsafe { crate::ffi::nvtxNameCuContextA(context, name.as_ptr()) }
}
#[cfg(feature = "cuda")]
pub unsafe fn name_cucontext_unicode(context: CuContext, name: &WideCStr) {
unsafe { crate::ffi::nvtxNameCuContextW(context, name.as_ptr().cast()) }
}
#[cfg(feature = "cuda")]
pub unsafe fn name_custream_ascii(stream: CuStream, name: &CStr) {
unsafe { crate::ffi::nvtxNameCuStreamA(stream, name.as_ptr()) }
}
#[cfg(feature = "cuda")]
pub unsafe fn name_custream_unicode(stream: CuStream, name: &WideCStr) {
unsafe { crate::ffi::nvtxNameCuStreamW(stream, name.as_ptr().cast()) }
}
#[cfg(feature = "cuda")]
pub unsafe fn name_cuevent_ascii(event: CuEvent, name: &CStr) {
unsafe { crate::ffi::nvtxNameCuEventA(event, name.as_ptr()) }
}
#[cfg(feature = "cuda")]
pub unsafe fn name_cuevent_unicode(event: CuEvent, name: &WideCStr) {
unsafe { crate::ffi::nvtxNameCuEventW(event, name.as_ptr().cast()) }
}
#[cfg(feature = "cuda_runtime")]
pub fn name_cuda_device_ascii(device: i32, name: &CStr) {
unsafe { crate::ffi::nvtxNameCudaDeviceA(device, name.as_ptr()) }
}
#[cfg(feature = "cuda_runtime")]
pub fn name_cuda_device_unicode(device: i32, name: &WideCStr) {
unsafe { crate::ffi::nvtxNameCudaDeviceW(device, name.as_ptr().cast()) }
}
#[cfg(feature = "cuda_runtime")]
pub unsafe fn name_cuda_stream_ascii(stream: CudaStream, name: &CStr) {
unsafe { crate::ffi::nvtxNameCudaStreamA(stream, name.as_ptr()) }
}
#[cfg(feature = "cuda_runtime")]
pub unsafe fn name_cuda_stream_unicode(stream: CudaStream, name: &WideCStr) {
unsafe { crate::ffi::nvtxNameCudaStreamW(stream, name.as_ptr().cast()) }
}
#[cfg(feature = "cuda_runtime")]
pub unsafe fn name_cuda_event_ascii(event: CudaEvent, name: &CStr) {
unsafe { crate::ffi::nvtxNameCudaEventA(event, name.as_ptr()) }
}
#[cfg(feature = "cuda_runtime")]
pub unsafe fn name_cuda_event_unicode(event: CudaEvent, name: &WideCStr) {
unsafe { crate::ffi::nvtxNameCudaEventW(event, name.as_ptr().cast()) }
}
#[must_use]
pub fn domain_syncuser_create(domain: DomainHandle, attribs: SyncUserAttributes) -> SyncUserHandle {
SyncUserHandle {
handle: unsafe {
crate::ffi::nvtxDomainSyncUserCreate(
domain.handle,
core::ptr::addr_of!(attribs).cast_mut(),
)
},
}
}
pub fn domain_syncuser_destroy(handle: SyncUserHandle) {
unsafe { crate::ffi::nvtxDomainSyncUserDestroy(handle.handle) }
}
pub fn domain_syncuser_acquire_start(handle: SyncUserHandle) {
unsafe { crate::ffi::nvtxDomainSyncUserAcquireStart(handle.handle) }
}
pub fn domain_syncuser_acquire_failed(handle: SyncUserHandle) {
unsafe { crate::ffi::nvtxDomainSyncUserAcquireFailed(handle.handle) }
}
pub fn domain_syncuser_acquire_success(handle: SyncUserHandle) {
unsafe { crate::ffi::nvtxDomainSyncUserAcquireSuccess(handle.handle) }
}
pub fn domain_syncuser_acquire_releasing(handle: SyncUserHandle) {
unsafe { crate::ffi::nvtxDomainSyncUserReleasing(handle.handle) }
}