實戰GPU編程(python高性能計算)2:環境驗證
2 環境驗證
2.1 安裝
參考:https://developer.nvidia.com/cuda-downloads

然后安裝CuPy,再安裝PyCUDA。
驗證安裝:
# nvidia-smi
Wed Aug 20 11:02:36 2025
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 570.124.06 Driver Version: 570.124.06 CUDA Version: 12.8 |
|-----------------------------------------+------------------------+----------------------+
| GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|=========================================+========================+======================|
| 0 NVIDIA L20 Off | 00000000:02:00.0 Off | 0 |
| N/A 49C P8 26W / 350W | 14MiB / 46068MiB | 0% Default |
| | | N/A |
+-----------------------------------------+------------------------+----------------------+
+-----------------------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=========================================================================================|
| 0 N/A N/A 2990 G /usr/libexec/Xorg 4MiB |
+-----------------------------------------------------------------------------------------+
# nvcc -V
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2025 NVIDIA Corporation
Built on Wed_Jan_15_19:21:50_PST_2025
Cuda compilation tools, release 12.8, V12.8.61
Build cuda_12.8.r12.8/compiler.35404655_0
如果找不到以上命令則需要設置環境變量:
export PATH=/usr/local/cuda/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH
python驗證:
>>> import cupy as cp
... print("CuPy version:", cp.__version__)
... print("CUDA runtime version:", cp.cuda.runtime.runtimeGetVersion())
... print("Our available device:", cp.cuda.runtime.getDeviceProperties(0)['name'])
...
CuPy version: 13.6.0
CUDA runtime version: 12080
Our available device: b'NVIDIA L20'
>>> dir(cp.cuda.runtime)
['CUDARuntimeError', 'CUDA_C_16F', 'CUDA_C_32F', 'CUDA_C_64F', 'CUDA_C_8I', 'CUDA_C_8U', 'CUDA_R_16F', 'CUDA_R_32F', 'CUDA_R_64F', 'CUDA_R_8I', 'CUDA_R_8U', 'MemPoolProps', 'PointerAttributes', '_ThreadLocal', '__builtins__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__pyx_capi__', '__pyx_unpickle_MemPoolProps', '__pyx_unpickle_PointerAttributes', '__pyx_unpickle__ThreadLocal', '__spec__', '__test__', '_deviceEnsurePeerAccess', '_export_enum', '_getCUDAMajorVersion', '_getLocalRuntimeVersion', '_launchHostFuncUnmanaged', '_sys', '_threading', 'check_status', 'createSurfaceObject', 'createTextureObject', 'cudaAddressModeBorder', 'cudaAddressModeClamp', 'cudaAddressModeMirror', 'cudaAddressModeWrap', 'cudaArrayDefault', 'cudaArraySurfaceLoadStore', 'cudaChannelFormatKindFloat', 'cudaChannelFormatKindNone', 'cudaChannelFormatKindSigned', 'cudaChannelFormatKindUnsigned', 'cudaCpuDeviceId', 'cudaDevAttrAsyncEngineCount', 'cudaDevAttrCanFlushRemoteWrites', 'cudaDevAttrCanMapHostMemory', 'cudaDevAttrCanUseHostPointerForRegisteredMem', 'cudaDevAttrClockRate', 'cudaDevAttrComputeMode', 'cudaDevAttrComputePreemptionSupported', 'cudaDevAttrConcurrentKernels', 'cudaDevAttrConcurrentManagedAccess', 'cudaDevAttrCooperativeLaunch', 'cudaDevAttrCooperativeMultiDeviceLaunch', 'cudaDevAttrDirectManagedMemAccessFromHost', 'cudaDevAttrEccEnabled', 'cudaDevAttrGPUDirectRDMAFlushWritesOptions', 'cudaDevAttrGPUDirectRDMASupported', 'cudaDevAttrGPUDirectRDMAWritesOrdering', 'cudaDevAttrGlobalL1CacheSupported', 'cudaDevAttrGlobalMemoryBusWidth', 'cudaDevAttrGpuOverlap', 'cudaDevAttrHostNativeAtomicSupported', 'cudaDevAttrHostRegisterReadOnlySupported', 'cudaDevAttrHostRegisterSupported', 'cudaDevAttrIntegrated', 'cudaDevAttrIsMultiGpuBoard', 'cudaDevAttrKernelExecTimeout', 'cudaDevAttrL2CacheSize', 'cudaDevAttrLocalL1CacheSupported', 'cudaDevAttrManagedMemory', 'cudaDevAttrMaxBlockDimX', 'cudaDevAttrMaxBlockDimY', 'cudaDevAttrMaxBlockDimZ', 'cudaDevAttrMaxBlocksPerMultiprocessor', 'cudaDevAttrMaxGridDimX', 'cudaDevAttrMaxGridDimY', 'cudaDevAttrMaxGridDimZ', 'cudaDevAttrMaxPitch', 'cudaDevAttrMaxRegistersPerBlock', 'cudaDevAttrMaxRegistersPerMultiprocessor', 'cudaDevAttrMaxSharedMemoryPerBlock', 'cudaDevAttrMaxSharedMemoryPerBlockOptin', 'cudaDevAttrMaxSharedMemoryPerMultiprocessor', 'cudaDevAttrMaxSurface1DLayeredLayers', 'cudaDevAttrMaxSurface1DLayeredWidth', 'cudaDevAttrMaxSurface1DWidth', 'cudaDevAttrMaxSurface2DHeight', 'cudaDevAttrMaxSurface2DLayeredHeight', 'cudaDevAttrMaxSurface2DLayeredLayers', 'cudaDevAttrMaxSurface2DLayeredWidth', 'cudaDevAttrMaxSurface2DWidth', 'cudaDevAttrMaxSurface3DDepth', 'cudaDevAttrMaxSurface3DHeight', 'cudaDevAttrMaxSurface3DWidth', 'cudaDevAttrMaxSurfaceCubemapLayeredLayers', 'cudaDevAttrMaxSurfaceCubemapLayeredWidth', 'cudaDevAttrMaxSurfaceCubemapWidth', 'cudaDevAttrMaxTexture1DLayeredLayers', 'cudaDevAttrMaxTexture1DLayeredWidth', 'cudaDevAttrMaxTexture1DLinearWidth', 'cudaDevAttrMaxTexture1DMipmappedWidth', 'cudaDevAttrMaxTexture1DWidth', 'cudaDevAttrMaxTexture2DGatherHeight', 'cudaDevAttrMaxTexture2DGatherWidth', 'cudaDevAttrMaxTexture2DHeight', 'cudaDevAttrMaxTexture2DLayeredHeight', 'cudaDevAttrMaxTexture2DLayeredLayers', 'cudaDevAttrMaxTexture2DLayeredWidth', 'cudaDevAttrMaxTexture2DLinearHeight', 'cudaDevAttrMaxTexture2DLinearPitch', 'cudaDevAttrMaxTexture2DLinearWidth', 'cudaDevAttrMaxTexture2DMipmappedHeight', 'cudaDevAttrMaxTexture2DMipmappedWidth', 'cudaDevAttrMaxTexture2DWidth', 'cudaDevAttrMaxTexture3DDepth', 'cudaDevAttrMaxTexture3DDepthAlt', 'cudaDevAttrMaxTexture3DHeight', 'cudaDevAttrMaxTexture3DHeightAlt', 'cudaDevAttrMaxTexture3DWidth', 'cudaDevAttrMaxTexture3DWidthAlt', 'cudaDevAttrMaxTextureCubemapLayeredLayers', 'cudaDevAttrMaxTextureCubemapLayeredWidth', 'cudaDevAttrMaxTextureCubemapWidth', 'cudaDevAttrMaxThreadsPerBlock', 'cudaDevAttrMaxThreadsPerMultiProcessor', 'cudaDevAttrMaxTimelineSemaphoreInteropSupported', 'cudaDevAttrMemoryClockRate', 'cudaDevAttrMemoryPoolSupportedHandleTypes', 'cudaDevAttrMemoryPoolsSupported', 'cudaDevAttrMultiGpuBoardGroupID', 'cudaDevAttrMultiProcessorCount', 'cudaDevAttrPageableMemoryAccess', 'cudaDevAttrPageableMemoryAccessUsesHostPageTables', 'cudaDevAttrPciBusId', 'cudaDevAttrPciDeviceId', 'cudaDevAttrPciDomainId', 'cudaDevAttrReserved92', 'cudaDevAttrReserved93', 'cudaDevAttrReserved94', 'cudaDevAttrReservedSharedMemoryPerBlock', 'cudaDevAttrSingleToDoublePrecisionPerfRatio', 'cudaDevAttrSparseCudaArraySupported', 'cudaDevAttrStreamPrioritiesSupported', 'cudaDevAttrSurfaceAlignment', 'cudaDevAttrTccDriver', 'cudaDevAttrTextureAlignment', 'cudaDevAttrTexturePitchAlignment', 'cudaDevAttrTotalConstantMemory', 'cudaDevAttrUnifiedAddressing', 'cudaDevAttrWarpSize', 'cudaFilterModeLinear', 'cudaFilterModePoint', 'cudaInvalidDeviceId', 'cudaIpcMemLazyEnablePeerAccess', 'cudaLimitDevRuntimePendingLaunchCount', 'cudaLimitDevRuntimeSyncDepth', 'cudaLimitMallocHeapSize', 'cudaLimitMaxL2FetchGranularity', 'cudaLimitPrintfFifoSize', 'cudaLimitStackSize', 'cudaMemAdviseSetAccessedBy', 'cudaMemAdviseSetPreferredLocation', 'cudaMemAdviseSetReadMostly', 'cudaMemAdviseUnsetAccessedBy', 'cudaMemAdviseUnsetPreferredLocation', 'cudaMemAdviseUnsetReadMostly', 'cudaMemAllocationTypePinned', 'cudaMemAttachGlobal', 'cudaMemAttachHost', 'cudaMemAttachSingle', 'cudaMemHandleTypeNone', 'cudaMemHandleTypePosixFileDescriptor', 'cudaMemLocationTypeDevice', 'cudaMemLocationTypeHost', 'cudaMemLocationTypeHostNuma', 'cudaMemLocationTypeHostNumaCurrent', 'cudaMemLocationTypeInvalid', 'cudaMemPoolAttrReleaseThreshold', 'cudaMemPoolAttrReservedMemCurrent', 'cudaMemPoolAttrReservedMemHigh', 'cudaMemPoolAttrUsedMemCurrent', 'cudaMemPoolAttrUsedMemHigh', 'cudaMemPoolReuseAllowInternalDependencies', 'cudaMemPoolReuseAllowOpportunistic', 'cudaMemPoolReuseFollowEventDependencies', 'cudaMemoryTypeDevice', 'cudaMemoryTypeHost', 'cudaReadModeElementType', 'cudaReadModeNormalizedFloat', 'cudaResourceTypeArray', 'cudaResourceTypeLinear', 'cudaResourceTypeMipmappedArray', 'cudaResourceTypePitch2D', 'destroySurfaceObject', 'destroyTextureObject', 'deviceCanAccessPeer', 'deviceDisablePeerAccess', 'deviceEnablePeerAccess', 'deviceGetAttribute', 'deviceGetByPCIBusId', 'deviceGetDefaultMemPool', 'deviceGetLimit', 'deviceGetMemPool', 'deviceGetPCIBusId', 'deviceSetLimit', 'deviceSetMemPool', 'deviceSynchronize', 'driverGetVersion', 'eventBlockingSync', 'eventCreate', 'eventCreateWithFlags', 'eventDefault', 'eventDestroy', 'eventDisableTiming', 'eventElapsedTime', 'eventInterprocess', 'eventQuery', 'eventRecord', 'eventSynchronize', 'free', 'freeArray', 'freeAsync', 'freeHost', 'getDevice', 'getDeviceCount', 'getDeviceProperties', 'graphDestroy', 'graphExecDestroy', 'graphInstantiate', 'graphLaunch', 'graphUpload', 'hostAlloc', 'hostAllocDefault', 'hostAllocMapped', 'hostAllocPortable', 'hostAllocWriteCombined', 'hostRegister', 'hostUnregister', 'ipcCloseMemHandle', 'ipcGetEventHandle', 'ipcGetMemHandle', 'ipcOpenEventHandle', 'ipcOpenMemHandle', 'is_hip', 'launchHostFunc', 'malloc', 'malloc3DArray', 'mallocArray', 'mallocAsync', 'mallocFromPoolAsync', 'mallocManaged', 'memAdvise', 'memGetInfo', 'memPoolCreate', 'memPoolDestroy', 'memPoolGetAttribute', 'memPoolSetAttribute', 'memPoolTrimTo', 'memPrefetchAsync', 'memcpy', 'memcpy2D', 'memcpy2DAsync', 'memcpy2DFromArray', 'memcpy2DFromArrayAsync', 'memcpy2DToArray', 'memcpy2DToArrayAsync', 'memcpy3D', 'memcpy3DAsync', 'memcpyAsync', 'memcpyDefault', 'memcpyDeviceToDevice', 'memcpyDeviceToHost', 'memcpyHostToDevice', 'memcpyHostToHost', 'memcpyPeer', 'memcpyPeerAsync', 'memoryTypeDevice', 'memoryTypeHost', 'memoryTypeManaged', 'memoryTypeUnregistered', 'memset', 'memsetAsync', 'pointerGetAttributes', 'profilerStart', 'profilerStop', 'runtimeGetVersion', 'setDevice', 'streamAddCallback', 'streamBeginCapture', 'streamCaptureModeGlobal', 'streamCaptureModeRelaxed', 'streamCaptureModeThreadLocal', 'streamCaptureStatusActive', 'streamCaptureStatusInvalidated', 'streamCaptureStatusNone', 'streamCreate', 'streamCreateWithFlags', 'streamDefault', 'streamDestroy', 'streamEndCapture', 'streamIsCapturing', 'streamLegacy', 'streamNonBlocking', 'streamPerThread', 'streamQuery', 'streamSynchronize', 'streamWaitEvent']

2.2 使用設備查詢驗證GPU
我們已經安裝了 CUDA 驅動程序和工具包,并確認我們的系統能夠識別 GPU。在深入了解細節之前,讓我們先仔細看看機器中的硬件。設備查詢讓我們能夠查看 GPU 的所有重要細節,例如它擁有多少個多處理器、可用內存、支持的計算能力以及其他影響 CUDA 編程的功能。
運行設備查詢時,它會顯示您的安裝已成功,并幫助我們調整內核和庫設置以匹配您的硬件。這使得我們的編程在未來更加健壯、可預測且性能更佳。
2.2.1 運行設備查詢
CUDA 工具包附帶一個名為 deviceQuery 的便捷示例二進制文件。此工具會打印系統中每個可見 GPU 的完整報告。
在大多數 Linux 設置中,我們可以在以下位置找到 deviceQuery:/usr/local/cuda/samples/1_Utilities/deviceQuery/deviceQuery
如果沒有找到,我們可以按如下方式構建 CUDA 示例目錄:
cd /usr/local/cuda/samples/1_Utilities/deviceQuery
sudo make
./deviceQuery
實在不行還可以使用源碼編譯:
# git clone https://github.com/NVIDIA/cuda-samples
# cd cuda-samples/Samples/1_Utilities/build/deviceQuery
# make
# ./deviceQuery
輸出會顯示一長串屬性,其中對我們最有用的幾行是:
● 設備名稱
● 全局內存總量
● 多處理器數量
● 每個 SM 的 CUDA 核心數
● 每個塊的最大線程數
● 每個塊的共享內存
● 計算能力

2.2.2 python驗證設備屬性
我們經常希望直接在 Python 中訪問這些設置,尤其是在我們的代碼需要適應不同的硬件時。使用 CuPy,我們可以以編程方式檢查所需的一切。
現在,我們將打印出最重要的屬性:
In [1]: import cupy as cp
In [2]: device = cp.cuda.Device(0)
In [3]: attributes = device.attributes
In [4]: attributes
Out[4]:
{'AsyncEngineCount': 2,
'CanFlushRemoteWrites': 0,
'CanMapHostMemory': 1,
'CanUseHostPointerForRegisteredMem': 1,
'ClockRate': 2520000,
'ComputeMode': 0,
'ComputePreemptionSupported': 1,
'ConcurrentKernels': 1,
'ConcurrentManagedAccess': 1,
'CooperativeLaunch': 1,
'CooperativeMultiDeviceLaunch': 1,
'DirectManagedMemAccessFromHost': 0,
'EccEnabled': 0,
'GPUDirectRDMAFlushWritesOptions': 1,
'GPUDirectRDMASupported': 0,
'GPUDirectRDMAWritesOrdering': 0,
'GlobalL1CacheSupported': 1,
'GlobalMemoryBusWidth': 384,
'GpuOverlap': 1,
'HostNativeAtomicSupported': 0,
'HostRegisterReadOnlySupported': 0,
'HostRegisterSupported': 1,
'Integrated': 0,
'IsMultiGpuBoard': 0,
'KernelExecTimeout': 1,
'L2CacheSize': 75497472,
'LocalL1CacheSupported': 1,
'ManagedMemory': 1,
'MaxBlockDimX': 1024,
'MaxBlockDimY': 1024,
'MaxBlockDimZ': 64,
'MaxBlocksPerMultiprocessor': 24,
'MaxGridDimX': 2147483647,
'MaxGridDimY': 65535,
'MaxGridDimZ': 65535,
'MaxPitch': 2147483647,
'MaxRegistersPerBlock': 65536,
'MaxRegistersPerMultiprocessor': 65536,
'MaxSharedMemoryPerBlock': 49152,
'MaxSharedMemoryPerBlockOptin': 101376,
'MaxSharedMemoryPerMultiprocessor': 102400,
'MaxSurface1DLayeredLayers': 2048,
'MaxSurface1DLayeredWidth': 32768,
'MaxSurface1DWidth': 32768,
'MaxSurface2DHeight': 65536,
'MaxSurface2DLayeredHeight': 32768,
'MaxSurface2DLayeredLayers': 2048,
'MaxSurface2DLayeredWidth': 32768,
'MaxSurface2DWidth': 131072,
'MaxSurface3DDepth': 16384,
'MaxSurface3DHeight': 16384,
'MaxSurface3DWidth': 16384,
'MaxSurfaceCubemapLayeredLayers': 2046,
'MaxSurfaceCubemapLayeredWidth': 32768,
'MaxSurfaceCubemapWidth': 32768,
'MaxTexture1DLayeredLayers': 2048,
'MaxTexture1DLayeredWidth': 32768,
'MaxTexture1DLinearWidth': 268435456,
'MaxTexture1DMipmappedWidth': 32768,
'MaxTexture1DWidth': 131072,
'MaxTexture2DGatherHeight': 32768,
'MaxTexture2DGatherWidth': 32768,
'MaxTexture2DHeight': 65536,
'MaxTexture2DLayeredHeight': 32768,
'MaxTexture2DLayeredLayers': 2048,
'MaxTexture2DLayeredWidth': 32768,
'MaxTexture2DLinearHeight': 65000,
'MaxTexture2DLinearPitch': 2097120,
'MaxTexture2DLinearWidth': 131072,
'MaxTexture2DMipmappedHeight': 32768,
'MaxTexture2DMipmappedWidth': 32768,
'MaxTexture2DWidth': 131072,
'MaxTexture3DDepth': 16384,
'MaxTexture3DDepthAlt': 32768,
'MaxTexture3DHeight': 16384,
'MaxTexture3DHeightAlt': 8192,
'MaxTexture3DWidth': 16384,
'MaxTexture3DWidthAlt': 8192,
'MaxTextureCubemapLayeredLayers': 2046,
'MaxTextureCubemapLayeredWidth': 32768,
'MaxTextureCubemapWidth': 32768,
'MaxThreadsPerBlock': 1024,
'MaxThreadsPerMultiProcessor': 1536,
'MaxTimelineSemaphoreInteropSupported': 1,
'MemoryClockRate': 10501000,
'MemoryPoolSupportedHandleTypes': 9,
'MemoryPoolsSupported': 1,
'MultiGpuBoardGroupID': 0,
'MultiProcessorCount': 128,
'PageableMemoryAccess': 1,
'PageableMemoryAccessUsesHostPageTables': 0,
'PciBusId': 172,
'PciDeviceId': 0,
'PciDomainId': 0,
'Reserved92': 0,
'Reserved93': 0,
'Reserved94': 0,
'ReservedSharedMemoryPerBlock': 1024,
'SingleToDoublePrecisionPerfRatio': 64,
'SparseCudaArraySupported': 1,
'StreamPrioritiesSupported': 1,
'SurfaceAlignment': 512,
'TccDriver': 0,
'TextureAlignment': 512,
'TexturePitchAlignment': 32,
'TotalConstantMemory': 65536,
'UnifiedAddressing': 1,
'WarpSize': 32}
In [5]: properties = cp.cuda.runtime.getDeviceProperties(0)
In [6]: properties
Out[6]:
{'name': b'NVIDIA GeForce RTX 4090',
'totalGlobalMem': 25241190400,
'sharedMemPerBlock': 49152,
'regsPerBlock': 65536,
'warpSize': 32,
'maxThreadsPerBlock': 1024,
'maxThreadsDim': (1024, 1024, 64),
'maxGridSize': (2147483647, 65535, 65535),
'clockRate': 2520000,
'totalConstMem': 65536,
'major': 8,
'minor': 9,
'textureAlignment': 512,
'texturePitchAlignment': 32,
'multiProcessorCount': 128,
'kernelExecTimeoutEnabled': 1,
'integrated': 0,
'canMapHostMemory': 1,
'computeMode': 0,
'maxTexture1D': 131072,
'maxTexture2D': (131072, 65536),
'maxTexture3D': (16384, 16384, 16384),
'concurrentKernels': 1,
'ECCEnabled': 0,
'pciBusID': 172,
'pciDeviceID': 0,
'pciDomainID': 0,
'tccDriver': 0,
'memoryClockRate': 10501000,
'memoryBusWidth': 384,
'l2CacheSize': 75497472,
'maxThreadsPerMultiProcessor': 1536,
'isMultiGpuBoard': 0,
'cooperativeLaunch': 1,
'cooperativeMultiDeviceLaunch': 1,
'deviceOverlap': 1,
'maxTexture1DMipmap': 32768,
'maxTexture1DLinear': 268435456,
'maxTexture1DLayered': (32768, 2048),
'maxTexture2DMipmap': (32768, 32768),
'maxTexture2DLinear': (131072, 65000, 2097120),
'maxTexture2DLayered': (32768, 32768, 2048),
'maxTexture2DGather': (32768, 32768),
'maxTexture3DAlt': (8192, 8192, 32768),
'maxTextureCubemap': 32768,
'maxTextureCubemapLayered': (32768, 2046),
'maxSurface1D': 32768,
'maxSurface1DLayered': (32768, 2048),
'maxSurface2D': (131072, 65536),
'maxSurface2DLayered': (32768, 32768, 2048),
'maxSurface3D': (16384, 16384, 16384),
'maxSurfaceCubemap': 32768,
'maxSurfaceCubemapLayered': (32768, 2046),
'surfaceAlignment': 512,
'asyncEngineCount': 2,
'unifiedAddressing': 1,
'streamPrioritiesSupported': 1,
'globalL1CacheSupported': 1,
'localL1CacheSupported': 1,
'sharedMemPerMultiprocessor': 102400,
'regsPerMultiprocessor': 65536,
'managedMemory': 1,
'multiGpuBoardGroupID': 0,
'hostNativeAtomicSupported': 0,
'singleToDoublePrecisionPerfRatio': 64,
'pageableMemoryAccess': 1,
'concurrentManagedAccess': 1,
'computePreemptionSupported': 1,
'canUseHostPointerForRegisteredMem': 1,
'sharedMemPerBlockOptin': 101376,
'pageableMemoryAccessUsesHostPageTables': 0,
'directManagedMemAccessFromHost': 0,
'uuid': b'\xea\xce)\xa0\xbe\xf8\x9d\xfe\x06w\x96\xdb\x89\x84,\xc4',
'luid': b'',
'luidDeviceNodeMask': 0,
'persistingL2CacheMaxSize': 51904512,
'maxBlocksPerMultiProcessor': 24,
'accessPolicyMaxWindowSize': 134213632,
'reservedSharedMemPerBlock': 1024}
In [7]: properties['name']
Out[7]: b'NVIDIA GeForce RTX 4090'
In [8]: properties['major']
Out[8]: 8
In [9]: properties['minor']
Out[9]: 9
In [10]: print("Total Global Memory (MB):", device.mem_info[1] // (1024 * 1024))
Total Global Memory (MB): 24071
In [11]: print("Multiprocessors:", attributes['MultiProcessorCount'])
...: print("Max Threads per Block:", attributes['MaxThreadsPerBlock'])
...: print("Shared Memory per Block (KB):", attributes['MaxSharedMemoryPerBlock'] // 1024)
Multiprocessors: 128
Max Threads per Block: 1024
Shared Memory per Block (KB): 48
我們可以看到所有會影響代碼的屬性:線程塊可以設置多大、可以分配多少內存以及支持哪些功能。
2.2.3 驗證計算能力
CUDA 計算能力(Compute Capability) 是 NVIDIA GPU 的一個版本號,它定義了 GPU 的硬件特性和功能集。簡單來說,它告訴我們一張 NVIDIA 顯卡在執行 CUDA 應用程序時,支持哪些功能,以及它有哪些硬件上的限制(比如寄存器數量、共享內存大小等)。
這個版本號通常由兩個數字表示,例如 8.6 或 7.5,其中第一個數字是主版本號(major),第二個數字是次版本號(minor)。
主版本號(Major Version):表示 GPU 架構的代號。例如,8.x 代表 Ampere 架構,7.x 代表 Volta 架構,6.x 代表 Pascal 架構。主版本號的升級通常意味著架構上的重大變化和新功能的引入。
次版本號(Minor Version):表示在同一代 GPU 架構內的功能改進或修訂。例如,8.0 和 8.6 都屬于 Ampere 架構,但 8.6 可能在某些方面(如性能、功能)有所優化。
不同的計算能力版本支持不同的 CUDA 功能。例如,某些高級功能(如 Tensor Core、異步操作、增強的指令集等)可能只在較高的計算能力版本上才可用。如果你想在程序中使用這些新功能,你的 GPU 必須支持相應的計算能力。
nvcc 編譯器在編譯 CUDA 代碼時,會根據你指定的計算能力來生成優化的二進制代碼。指定正確的計算能力可以幫助編譯器更好地利用目標 GPU 的硬件特性,從而獲得更好的性能。
計算能力決定了 GPU 的硬件參數,例如:
- 每個多處理器(SM)的線程塊(Thread Block)數量。
- 每個線程塊的最大線程數。
- 每個線程塊的共享內存(Shared Memory)大小。
- 每個線程的寄存器(Register)數量。
這些參數直接影響到 CUDA 內核的設計和優化。開發者需要根據目標 GPU 的計算能力來調整網格(Grid)和線程塊(Block)的維度,以及共享內存的使用,以避免資源耗盡。計算能力的每次提升都會解鎖新的指令、更大的共享內存以及新的加速功能。
大多數現代 CUDA 庫都要求計算能力達到 6.0 或更高版本。如果我們的 GPU 報告計算能力達到 7.5、8.6 或類似水平,則幾乎可以支持所有當前的 CUDA 庫,包括最新版本的 CuPy、PyCUDA 和深度學習框架。如果我們的設備報告計算能力非常低(例如 3.x 或更低版本),則某些功能可能無法使用。在這種情況下,我們會限制使用兼容的庫,或者考慮升級硬件。
我們還可以在 PyCUDA 中查詢設備屬性:
>>> import pycuda.driver as drv
... import pycuda.autoinit
... device = drv.Device(0)
... print("Device Name:", device.name())
... print("Compute Capability:", f"{device.compute_capability()[0]}.{device.compute_capability()[1]}")
... print("Total Global Memory (MB):", device.total_memory() // (1024 * 1024))
... for key, value in device.get_attributes().items():
... print(f"{key}: {value}")
...
Device Name: NVIDIA GeForce RTX 4090
Compute Capability: 8.9
Total Global Memory (MB): 24071
ASYNC_ENGINE_COUNT: 2
CAN_MAP_HOST_MEMORY: 1
CAN_USE_HOST_POINTER_FOR_REGISTERED_MEM: 1
CLOCK_RATE: 2520000
COMPUTE_CAPABILITY_MAJOR: 8
COMPUTE_CAPABILITY_MINOR: 9
COMPUTE_MODE: DEFAULT
COMPUTE_PREEMPTION_SUPPORTED: 1
CONCURRENT_KERNELS: 1
CONCURRENT_MANAGED_ACCESS: 1
DIRECT_MANAGED_MEM_ACCESS_FROM_HOST: 0
ECC_ENABLED: 0
GENERIC_COMPRESSION_SUPPORTED: 1
GLOBAL_L1_CACHE_SUPPORTED: 1
GLOBAL_MEMORY_BUS_WIDTH: 384
GPU_OVERLAP: 1
HANDLE_TYPE_POSIX_FILE_DESCRIPTOR_SUPPORTED: 1
HANDLE_TYPE_WIN32_HANDLE_SUPPORTED: 0
HANDLE_TYPE_WIN32_KMT_HANDLE_SUPPORTED: 0
HOST_NATIVE_ATOMIC_SUPPORTED: 0
INTEGRATED: 0
KERNEL_EXEC_TIMEOUT: 1
L2_CACHE_SIZE: 75497472
LOCAL_L1_CACHE_SUPPORTED: 1
MANAGED_MEMORY: 1
MAXIMUM_SURFACE1D_LAYERED_LAYERS: 2048
MAXIMUM_SURFACE1D_LAYERED_WIDTH: 32768
MAXIMUM_SURFACE1D_WIDTH: 32768
MAXIMUM_SURFACE2D_HEIGHT: 65536
MAXIMUM_SURFACE2D_LAYERED_HEIGHT: 32768
MAXIMUM_SURFACE2D_LAYERED_LAYERS: 2048
MAXIMUM_SURFACE2D_LAYERED_WIDTH: 32768
MAXIMUM_SURFACE2D_WIDTH: 131072
MAXIMUM_SURFACE3D_DEPTH: 16384
MAXIMUM_SURFACE3D_HEIGHT: 16384
MAXIMUM_SURFACE3D_WIDTH: 16384
MAXIMUM_SURFACECUBEMAP_LAYERED_LAYERS: 2046
MAXIMUM_SURFACECUBEMAP_LAYERED_WIDTH: 32768
MAXIMUM_SURFACECUBEMAP_WIDTH: 32768
MAXIMUM_TEXTURE1D_LAYERED_LAYERS: 2048
MAXIMUM_TEXTURE1D_LAYERED_WIDTH: 32768
MAXIMUM_TEXTURE1D_LINEAR_WIDTH: 268435456
MAXIMUM_TEXTURE1D_MIPMAPPED_WIDTH: 32768
MAXIMUM_TEXTURE1D_WIDTH: 131072
MAXIMUM_TEXTURE2D_ARRAY_HEIGHT: 32768
MAXIMUM_TEXTURE2D_ARRAY_NUMSLICES: 2048
MAXIMUM_TEXTURE2D_ARRAY_WIDTH: 32768
MAXIMUM_TEXTURE2D_GATHER_HEIGHT: 32768
MAXIMUM_TEXTURE2D_GATHER_WIDTH: 32768
MAXIMUM_TEXTURE2D_HEIGHT: 65536
MAXIMUM_TEXTURE2D_LINEAR_HEIGHT: 65000
MAXIMUM_TEXTURE2D_LINEAR_PITCH: 2097120
MAXIMUM_TEXTURE2D_LINEAR_WIDTH: 131072
MAXIMUM_TEXTURE2D_MIPMAPPED_HEIGHT: 32768
MAXIMUM_TEXTURE2D_MIPMAPPED_WIDTH: 32768
MAXIMUM_TEXTURE2D_WIDTH: 131072
MAXIMUM_TEXTURE3D_DEPTH: 16384
MAXIMUM_TEXTURE3D_DEPTH_ALTERNATE: 32768
MAXIMUM_TEXTURE3D_HEIGHT: 16384
MAXIMUM_TEXTURE3D_HEIGHT_ALTERNATE: 8192
MAXIMUM_TEXTURE3D_WIDTH: 16384
MAXIMUM_TEXTURE3D_WIDTH_ALTERNATE: 8192
MAXIMUM_TEXTURECUBEMAP_LAYERED_LAYERS: 2046
MAXIMUM_TEXTURECUBEMAP_LAYERED_WIDTH: 32768
MAXIMUM_TEXTURECUBEMAP_WIDTH: 32768
MAX_BLOCKS_PER_MULTIPROCESSOR: 24
MAX_BLOCK_DIM_X: 1024
MAX_BLOCK_DIM_Y: 1024
MAX_BLOCK_DIM_Z: 64
MAX_GRID_DIM_X: 2147483647
MAX_GRID_DIM_Y: 65535
MAX_GRID_DIM_Z: 65535
MAX_PERSISTING_L2_CACHE_SIZE: 51904512
MAX_PITCH: 2147483647
MAX_REGISTERS_PER_BLOCK: 65536
MAX_REGISTERS_PER_MULTIPROCESSOR: 65536
MAX_SHARED_MEMORY_PER_BLOCK: 49152
MAX_SHARED_MEMORY_PER_BLOCK_OPTIN: 101376
MAX_SHARED_MEMORY_PER_MULTIPROCESSOR: 102400
MAX_THREADS_PER_BLOCK: 1024
MAX_THREADS_PER_MULTIPROCESSOR: 1536
MEMORY_CLOCK_RATE: 10501000
MEMORY_POOLS_SUPPORTED: 1
MULTIPROCESSOR_COUNT: 128
MULTI_GPU_BOARD: 0
MULTI_GPU_BOARD_GROUP_ID: 0
PAGEABLE_MEMORY_ACCESS: 1
PAGEABLE_MEMORY_ACCESS_USES_HOST_PAGE_TABLES: 0
PCI_BUS_ID: 172
PCI_DEVICE_ID: 0
PCI_DOMAIN_ID: 0
READ_ONLY_HOST_REGISTER_SUPPORTED: 0
RESERVED_SHARED_MEMORY_PER_BLOCK: 1024
SINGLE_TO_DOUBLE_PRECISION_PERF_RATIO: 64
STREAM_PRIORITIES_SUPPORTED: 1
SURFACE_ALIGNMENT: 512
TCC_DRIVER: 0
TEXTURE_ALIGNMENT: 512
TEXTURE_PITCH_ALIGNMENT: 32
TOTAL_CONSTANT_MEMORY: 65536
UNIFIED_ADDRESSING: 1
WARP_SIZE: 32
這會顯示所有可用屬性,以便我們可以根據需要調整內核配置。
每當我們更換機器、GPU 或驅動程序時,運行新的設備查詢始終是驗證兼容性的第一步。通過這種做法,我們的 CUDA 編程將保持可靠、靈活,并與現有硬件完美匹配。
參考資料
- 軟件測試精品書籍文檔下載持續更新 https://github.com/china-testing/python-testing-examples 請點贊,謝謝!
- 本文涉及的python測試開發庫 謝謝點贊! https://github.com/china-testing/python_cn_resouce
- python精品書籍下載 https://github.com/china-testing/python_cn_resouce/blob/main/python_good_books.md
- Linux精品書籍下載 http://www.rzrgm.cn/testing-/p/17438558.html
- python八字排盤 https://github.com/china-testing/bazi
- 聯系方式:釘ding或V信: pythontesting
2.3 在PyCUDA 中實現內核

我們已經使用 PyCUDA 編寫了一個基本的向量加法內核,但現在我們想進一步了解 PyCUDA 如何讓我們在 Python 腳本中插入和運行自定義 CUDA C 代碼。我們希望熟悉整個主機-設備工作流程:分配內存、移動數據、編寫更靈活的內核、動態編譯、啟動內核,然后檢索和驗證結果。
這個示例比我們之前的示例更好。在這里,我們將討論參數化、嘗試新的操作,并闡明為什么 PyCUDA 是 Python 和 CUDA 生態系統之間如此堅實的橋梁。
2.3.1 準備主機數據
我們將首先設置兩個輸入數組和一個用于輸出的占位符。我們將開始在主機上使用 NumPy 來簡化設置。
>>> import numpy as np
... N = 8
... a_host = np.arange(N, dtype=np.float32)
... b_host = np.arange(N, 0, -1).astype(np.float32)
... print("Input Array A:", a_host)
... print("Input Array B:", b_host)
...
Input Array A: [0. 1. 2. 3. 4. 5. 6. 7.]
Input Array B: [8. 7. 6. 5. 4. 3. 2. 1.]
為了清晰起見,我們選擇較小的數組,但同樣的工作流程也適用于更大的數據集。
2.3.2 配設備內存
使用 PyCUDA,我們將這些數組傳輸到 GPU。我們還為結果分配了空間。
>>> import pycuda.autoinit
... import pycuda.driver as drv
... import pycuda.gpuarray as gpuarray
... a_device = gpuarray.to_gpu(a_host)
... b_device = gpuarray.to_gpu(b_host)
... c_device = gpuarray.empty_like(a_device)
...
此時,a_device 和 b_device 位于 GPU 上,c_device 為結果保留空間。
2.3.3 編寫自定義 CUDA C 內核
這正是 PyCUDA 的優勢所在。我們可以將 CUDA C 代碼以字符串形式嵌入,并在運行時進行編譯。這樣,我們的內核將逐個元素地添加兩個數組,但我們也可以輕松地更改操作。
以下是 CUDA C 腳本:
... kernel_code = """
... __global__ void add_arrays(float *a, float *b, float *c, int n)
... {
... int idx = threadIdx.x + blockDim.x * blockIdx.x;
... if (idx < n)
... {
... c[idx] = a[idx] + b[idx]; // Try changing this operation!
... }
... }
... """
... mod = SourceModule(kernel_code)
... add_arrays = mod.get_function("add_arrays")
...
>>> threads_per_block = 4
... blocks_per_grid = (N + threads_per_block - 1) // threads_per_block
...
CUDA 要求我們指定每個塊中要運行的線程數以及要啟動的塊數。為簡單起見,我們可以使用 4 作為塊大小,并計算覆蓋所有元素的網格大小。
2.3.4 啟動內核并驗證結果
然后,我們使用 PyCUDA 的函數接口調用內核。所有指針和參數都按照它們在內核中出現的順序傳遞。
>>> add_arrays(
... a_device, b_device, c_device, np.int32(N),
... block=(threads_per_block, 1, 1), grid=(blocks_per_grid, 1)
... )
內核在 GPU 上異步運行,并行處理所有元素。
計算完成后,我們將結果從 GPU 復制回主機,并與 CPU 計算結果進行驗證。
>>> c_host = c_device.get()
... print("Result Array C:", c_host)
... # Validate correctness
... expected = a_host + b_host
... if np.allclose(c_host, expected):
... print("Result matches CPU computation.")
... else:
... print("Mismatch found!")
...
Result Array C: [8. 8. 8. 8. 8. 8. 8. 8.]
Result matches CPU computation.
快速總結一下我們的工作:
● 我們首先分配所需大小的設備數組——無需擔心主機內存。
● 使用 to_gpu() 和 .get() 時,PyCUDA 會自動處理主機到設備和設備到主機的移動。
● 我們的 CUDA C 代碼在腳本運行時嵌入并編譯,使我們能夠快速迭代。
● 然后,我們控制塊和網格的大小,從而獲得應對任何規模或復雜度問題的靈活性。
● 最后,通過對照 CPU 版本檢查結果,我們可以及早發現錯誤,并增強對 GPU 編程技能的信心。
這為我們提供了一種可靠、靈活的模式,可以使用 PyCUDA 在 Python 項目中嵌入和驗證 CUDA C 內核。這項技能非常有用,對于我們接下來處理更具挑戰性和創造性的 GPU 編程任務至關重要。
2.4 小結
總而言之,我們成功搭建了一個可靠且專業級的 GPU 編程環境,確保工作流程的每一步都保持穩健、可重復且能夠滿足我們的需求。我們首先加深了對 CUDA 驅動程序、CUDA 工具包和 NVIDIA 硬件之間關系的理解,確保所有組件都協調一致以實現最佳性能。我們學習了如何安裝和驗證工具包和驅動程序、更新環境變量,以及如何使用內置工具(例如 nvidia-smi 和 nvcc)來驗證系統是否已準備好應對繁重的 GPU 工作負載。
通過運行 CUDA 設備查詢并檢查 GPU 屬性(無論是在命令行還是在 Python 中),我們深入了解了設備的計算能力、可用內存和架構限制。這使我們能夠調整代碼和庫選擇,使其與硬件完美匹配。通過親手使用 PyCUDA,我們練習了如何在 Python 中嵌入、編譯和執行 CUDA C 內核,從而強化了主機-設備工作流程的各個方面。
浙公網安備 33010602011771號