找回密码
 立即注册
首页 业界区 安全 实战GPU编程(python高性能计算)2:环境验证

实战GPU编程(python高性能计算)2:环境验证

司空娅玲 2025-8-20 15:38:56
2 环境验证

2.1 安装

参考:https://developer.nvidia.com/cuda-downloads
1.png

然后安装CuPy,再安装PyCUDA。
验证安装:
  1. # nvidia-smi
  2. Wed Aug 20 11:02:36 2025
  3. +-----------------------------------------------------------------------------------------+
  4. | NVIDIA-SMI 570.124.06             Driver Version: 570.124.06     CUDA Version: 12.8     |
  5. |-----------------------------------------+------------------------+----------------------+
  6. | GPU  Name                 Persistence-M | Bus-Id          Disp.A | Volatile Uncorr. ECC |
  7. | Fan  Temp   Perf          Pwr:Usage/Cap |           Memory-Usage | GPU-Util  Compute M. |
  8. |                                         |                        |               MIG M. |
  9. |=========================================+========================+======================|
  10. |   0  NVIDIA L20                     Off |   00000000:02:00.0 Off |                    0 |
  11. | N/A   49C    P8             26W /  350W |      14MiB /  46068MiB |      0%      Default |
  12. |                                         |                        |                  N/A |
  13. +-----------------------------------------+------------------------+----------------------+
  14. +-----------------------------------------------------------------------------------------+
  15. | Processes:                                                                              |
  16. |  GPU   GI   CI              PID   Type   Process name                        GPU Memory |
  17. |        ID   ID                                                               Usage      |
  18. |=========================================================================================|
  19. |    0   N/A  N/A            2990      G   /usr/libexec/Xorg                         4MiB |
  20. +-----------------------------------------------------------------------------------------+
  21. # nvcc -V
  22. nvcc: NVIDIA (R) Cuda compiler driver
  23. Copyright (c) 2005-2025 NVIDIA Corporation
  24. Built on Wed_Jan_15_19:21:50_PST_2025
  25. Cuda compilation tools, release 12.8, V12.8.61
  26. Build cuda_12.8.r12.8/compiler.35404655_0
复制代码
如果找不到以上命令则需要设置环境变量:
  1. export PATH=/usr/local/cuda/bin:$PATH
  2. export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH
复制代码
python验证:
  1. >>> import cupy as cp
  2. ... print("CuPy version:", cp.__version__)
  3. ... print("CUDA runtime version:", cp.cuda.runtime.runtimeGetVersion())
  4. ... print("Our available device:", cp.cuda.runtime.getDeviceProperties(0)['name'])
  5. ...
  6. CuPy version: 13.6.0
  7. CUDA runtime version: 12080
  8. Our available device: b'NVIDIA L20'
  9. >>> dir(cp.cuda.runtime)
  10. ['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.png

2.2 使用设备查询验证GPU

我们已经安装了 CUDA 驱动程序和工具包,并确认我们的系统能够识别 GPU。在深入了解细节之前,让我们先仔细看看机器中的硬件。设备查询让我们能够查看 GPU 的所有重要细节,例如它拥有多少个多处理器、可用内存、支持的计算能力以及其他影响 CUDA 编程的功能。
运行设备查询时,它会显示您的安装已成功,并帮助我们调整内核和库设置以匹配您的硬件。这使得我们的编程在未来更加健壮、可预测且性能更佳。
2.2.1 运行设备查询

CUDA 工具包附带一个名为 deviceQuery 的便捷示例二进制文件。此工具会打印系统中每个可见 GPU 的完整报告。
在大多数 Linux 设置中,我们可以在以下位置找到 deviceQuery:/usr/local/cuda/samples/1_Utilities/deviceQuery/deviceQuery
如果没有找到,我们可以按如下方式构建 CUDA 示例目录:
  1. cd /usr/local/cuda/samples/1_Utilities/deviceQuery
  2. sudo make
  3. ./deviceQuery
复制代码
实在不行还可以使用源码编译:
  1. # git clone https://github.com/NVIDIA/cuda-samples
  2. # cd cuda-samples/Samples/1_Utilities/build/deviceQuery
  3. # make
  4. # ./deviceQuery
复制代码
输出会显示一长串属性,其中对我们最有用的几行是:
● 设备名称
● 全局内存总量
● 多处理器数量
● 每个 SM 的 CUDA 核心数
● 每个块的最大线程数
● 每个块的共享内存
● 计算能力
3.png

2.2.2 python验证设备属性

我们经常希望直接在 Python 中访问这些设置,尤其是在我们的代码需要适应不同的硬件时。使用 CuPy,我们可以以编程方式检查所需的一切。
现在,我们将打印出最重要的属性:
  1. In [1]: import cupy as cp
  2. In [2]: device = cp.cuda.Device(0)
  3. In [3]: attributes = device.attributes
  4. In [4]: attributes
  5. Out[4]:
  6. {'AsyncEngineCount': 2,
  7. 'CanFlushRemoteWrites': 0,
  8. 'CanMapHostMemory': 1,
  9. 'CanUseHostPointerForRegisteredMem': 1,
  10. 'ClockRate': 2520000,
  11. 'ComputeMode': 0,
  12. 'ComputePreemptionSupported': 1,
  13. 'ConcurrentKernels': 1,
  14. 'ConcurrentManagedAccess': 1,
  15. 'CooperativeLaunch': 1,
  16. 'CooperativeMultiDeviceLaunch': 1,
  17. 'DirectManagedMemAccessFromHost': 0,
  18. 'EccEnabled': 0,
  19. 'GPUDirectRDMAFlushWritesOptions': 1,
  20. 'GPUDirectRDMASupported': 0,
  21. 'GPUDirectRDMAWritesOrdering': 0,
  22. 'GlobalL1CacheSupported': 1,
  23. 'GlobalMemoryBusWidth': 384,
  24. 'GpuOverlap': 1,
  25. 'HostNativeAtomicSupported': 0,
  26. 'HostRegisterReadOnlySupported': 0,
  27. 'HostRegisterSupported': 1,
  28. 'Integrated': 0,
  29. 'IsMultiGpuBoard': 0,
  30. 'KernelExecTimeout': 1,
  31. 'L2CacheSize': 75497472,
  32. 'LocalL1CacheSupported': 1,
  33. 'ManagedMemory': 1,
  34. 'MaxBlockDimX': 1024,
  35. 'MaxBlockDimY': 1024,
  36. 'MaxBlockDimZ': 64,
  37. 'MaxBlocksPerMultiprocessor': 24,
  38. 'MaxGridDimX': 2147483647,
  39. 'MaxGridDimY': 65535,
  40. 'MaxGridDimZ': 65535,
  41. 'MaxPitch': 2147483647,
  42. 'MaxRegistersPerBlock': 65536,
  43. 'MaxRegistersPerMultiprocessor': 65536,
  44. 'MaxSharedMemoryPerBlock': 49152,
  45. 'MaxSharedMemoryPerBlockOptin': 101376,
  46. 'MaxSharedMemoryPerMultiprocessor': 102400,
  47. 'MaxSurface1DLayeredLayers': 2048,
  48. 'MaxSurface1DLayeredWidth': 32768,
  49. 'MaxSurface1DWidth': 32768,
  50. 'MaxSurface2DHeight': 65536,
  51. 'MaxSurface2DLayeredHeight': 32768,
  52. 'MaxSurface2DLayeredLayers': 2048,
  53. 'MaxSurface2DLayeredWidth': 32768,
  54. 'MaxSurface2DWidth': 131072,
  55. 'MaxSurface3DDepth': 16384,
  56. 'MaxSurface3DHeight': 16384,
  57. 'MaxSurface3DWidth': 16384,
  58. 'MaxSurfaceCubemapLayeredLayers': 2046,
  59. 'MaxSurfaceCubemapLayeredWidth': 32768,
  60. 'MaxSurfaceCubemapWidth': 32768,
  61. 'MaxTexture1DLayeredLayers': 2048,
  62. 'MaxTexture1DLayeredWidth': 32768,
  63. 'MaxTexture1DLinearWidth': 268435456,
  64. 'MaxTexture1DMipmappedWidth': 32768,
  65. 'MaxTexture1DWidth': 131072,
  66. 'MaxTexture2DGatherHeight': 32768,
  67. 'MaxTexture2DGatherWidth': 32768,
  68. 'MaxTexture2DHeight': 65536,
  69. 'MaxTexture2DLayeredHeight': 32768,
  70. 'MaxTexture2DLayeredLayers': 2048,
  71. 'MaxTexture2DLayeredWidth': 32768,
  72. 'MaxTexture2DLinearHeight': 65000,
  73. 'MaxTexture2DLinearPitch': 2097120,
  74. 'MaxTexture2DLinearWidth': 131072,
  75. 'MaxTexture2DMipmappedHeight': 32768,
  76. 'MaxTexture2DMipmappedWidth': 32768,
  77. 'MaxTexture2DWidth': 131072,
  78. 'MaxTexture3DDepth': 16384,
  79. 'MaxTexture3DDepthAlt': 32768,
  80. 'MaxTexture3DHeight': 16384,
  81. 'MaxTexture3DHeightAlt': 8192,
  82. 'MaxTexture3DWidth': 16384,
  83. 'MaxTexture3DWidthAlt': 8192,
  84. 'MaxTextureCubemapLayeredLayers': 2046,
  85. 'MaxTextureCubemapLayeredWidth': 32768,
  86. 'MaxTextureCubemapWidth': 32768,
  87. 'MaxThreadsPerBlock': 1024,
  88. 'MaxThreadsPerMultiProcessor': 1536,
  89. 'MaxTimelineSemaphoreInteropSupported': 1,
  90. 'MemoryClockRate': 10501000,
  91. 'MemoryPoolSupportedHandleTypes': 9,
  92. 'MemoryPoolsSupported': 1,
  93. 'MultiGpuBoardGroupID': 0,
  94. 'MultiProcessorCount': 128,
  95. 'PageableMemoryAccess': 1,
  96. 'PageableMemoryAccessUsesHostPageTables': 0,
  97. 'PciBusId': 172,
  98. 'PciDeviceId': 0,
  99. 'PciDomainId': 0,
  100. 'Reserved92': 0,
  101. 'Reserved93': 0,
  102. 'Reserved94': 0,
  103. 'ReservedSharedMemoryPerBlock': 1024,
  104. 'SingleToDoublePrecisionPerfRatio': 64,
  105. 'SparseCudaArraySupported': 1,
  106. 'StreamPrioritiesSupported': 1,
  107. 'SurfaceAlignment': 512,
  108. 'TccDriver': 0,
  109. 'TextureAlignment': 512,
  110. 'TexturePitchAlignment': 32,
  111. 'TotalConstantMemory': 65536,
  112. 'UnifiedAddressing': 1,
  113. 'WarpSize': 32}
  114. In [5]: properties = cp.cuda.runtime.getDeviceProperties(0)
  115. In [6]: properties
  116. Out[6]:
  117. {'name': b'NVIDIA GeForce RTX 4090',
  118. 'totalGlobalMem': 25241190400,
  119. 'sharedMemPerBlock': 49152,
  120. 'regsPerBlock': 65536,
  121. 'warpSize': 32,
  122. 'maxThreadsPerBlock': 1024,
  123. 'maxThreadsDim': (1024, 1024, 64),
  124. 'maxGridSize': (2147483647, 65535, 65535),
  125. 'clockRate': 2520000,
  126. 'totalConstMem': 65536,
  127. 'major': 8,
  128. 'minor': 9,
  129. 'textureAlignment': 512,
  130. 'texturePitchAlignment': 32,
  131. 'multiProcessorCount': 128,
  132. 'kernelExecTimeoutEnabled': 1,
  133. 'integrated': 0,
  134. 'canMapHostMemory': 1,
  135. 'computeMode': 0,
  136. 'maxTexture1D': 131072,
  137. 'maxTexture2D': (131072, 65536),
  138. 'maxTexture3D': (16384, 16384, 16384),
  139. 'concurrentKernels': 1,
  140. 'ECCEnabled': 0,
  141. 'pciBusID': 172,
  142. 'pciDeviceID': 0,
  143. 'pciDomainID': 0,
  144. 'tccDriver': 0,
  145. 'memoryClockRate': 10501000,
  146. 'memoryBusWidth': 384,
  147. 'l2CacheSize': 75497472,
  148. 'maxThreadsPerMultiProcessor': 1536,
  149. 'isMultiGpuBoard': 0,
  150. 'cooperativeLaunch': 1,
  151. 'cooperativeMultiDeviceLaunch': 1,
  152. 'deviceOverlap': 1,
  153. 'maxTexture1DMipmap': 32768,
  154. 'maxTexture1DLinear': 268435456,
  155. 'maxTexture1DLayered': (32768, 2048),
  156. 'maxTexture2DMipmap': (32768, 32768),
  157. 'maxTexture2DLinear': (131072, 65000, 2097120),
  158. 'maxTexture2DLayered': (32768, 32768, 2048),
  159. 'maxTexture2DGather': (32768, 32768),
  160. 'maxTexture3DAlt': (8192, 8192, 32768),
  161. 'maxTextureCubemap': 32768,
  162. 'maxTextureCubemapLayered': (32768, 2046),
  163. 'maxSurface1D': 32768,
  164. 'maxSurface1DLayered': (32768, 2048),
  165. 'maxSurface2D': (131072, 65536),
  166. 'maxSurface2DLayered': (32768, 32768, 2048),
  167. 'maxSurface3D': (16384, 16384, 16384),
  168. 'maxSurfaceCubemap': 32768,
  169. 'maxSurfaceCubemapLayered': (32768, 2046),
  170. 'surfaceAlignment': 512,
  171. 'asyncEngineCount': 2,
  172. 'unifiedAddressing': 1,
  173. 'streamPrioritiesSupported': 1,
  174. 'globalL1CacheSupported': 1,
  175. 'localL1CacheSupported': 1,
  176. 'sharedMemPerMultiprocessor': 102400,
  177. 'regsPerMultiprocessor': 65536,
  178. 'managedMemory': 1,
  179. 'multiGpuBoardGroupID': 0,
  180. 'hostNativeAtomicSupported': 0,
  181. 'singleToDoublePrecisionPerfRatio': 64,
  182. 'pageableMemoryAccess': 1,
  183. 'concurrentManagedAccess': 1,
  184. 'computePreemptionSupported': 1,
  185. 'canUseHostPointerForRegisteredMem': 1,
  186. 'sharedMemPerBlockOptin': 101376,
  187. 'pageableMemoryAccessUsesHostPageTables': 0,
  188. 'directManagedMemAccessFromHost': 0,
  189. 'uuid': b'\xea\xce)\xa0\xbe\xf8\x9d\xfe\x06w\x96\xdb\x89\x84,\xc4',
  190. 'luid': b'',
  191. 'luidDeviceNodeMask': 0,
  192. 'persistingL2CacheMaxSize': 51904512,
  193. 'maxBlocksPerMultiProcessor': 24,
  194. 'accessPolicyMaxWindowSize': 134213632,
  195. 'reservedSharedMemPerBlock': 1024}
  196. In [7]: properties['name']
  197. Out[7]: b'NVIDIA GeForce RTX 4090'
  198. In [8]: properties['major']
  199. Out[8]: 8
  200. In [9]: properties['minor']
  201. Out[9]: 9
  202. In [10]: print("Total Global Memory (MB):", device.mem_info[1] // (1024 * 1024))
  203. Total Global Memory (MB): 24071
  204. In [11]: print("Multiprocessors:", attributes['MultiProcessorCount'])
  205.     ...: print("Max Threads per Block:", attributes['MaxThreadsPerBlock'])
  206.     ...: print("Shared Memory per Block (KB):", attributes['MaxSharedMemoryPerBlock'] // 1024)
  207. Multiprocessors: 128
  208. Max Threads per Block: 1024
  209. 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 中查询设备属性:
  1. >>> import pycuda.driver as drv
  2. ... import pycuda.autoinit
  3. ... device = drv.Device(0)
  4. ... print("Device Name:", device.name())
  5. ... print("Compute Capability:", f"{device.compute_capability()[0]}.{device.compute_capability()[1]}")
  6. ... print("Total Global Memory (MB):", device.total_memory() // (1024 * 1024))
  7. ... for key, value in device.get_attributes().items():
  8. ...    print(f"{key}: {value}")
  9. ...
  10. Device Name: NVIDIA GeForce RTX 4090
  11. Compute Capability: 8.9
  12. Total Global Memory (MB): 24071
  13. ASYNC_ENGINE_COUNT: 2
  14. CAN_MAP_HOST_MEMORY: 1
  15. CAN_USE_HOST_POINTER_FOR_REGISTERED_MEM: 1
  16. CLOCK_RATE: 2520000
  17. COMPUTE_CAPABILITY_MAJOR: 8
  18. COMPUTE_CAPABILITY_MINOR: 9
  19. COMPUTE_MODE: DEFAULT
  20. COMPUTE_PREEMPTION_SUPPORTED: 1
  21. CONCURRENT_KERNELS: 1
  22. CONCURRENT_MANAGED_ACCESS: 1
  23. DIRECT_MANAGED_MEM_ACCESS_FROM_HOST: 0
  24. ECC_ENABLED: 0
  25. GENERIC_COMPRESSION_SUPPORTED: 1
  26. GLOBAL_L1_CACHE_SUPPORTED: 1
  27. GLOBAL_MEMORY_BUS_WIDTH: 384
  28. GPU_OVERLAP: 1
  29. HANDLE_TYPE_POSIX_FILE_DESCRIPTOR_SUPPORTED: 1
  30. HANDLE_TYPE_WIN32_HANDLE_SUPPORTED: 0
  31. HANDLE_TYPE_WIN32_KMT_HANDLE_SUPPORTED: 0
  32. HOST_NATIVE_ATOMIC_SUPPORTED: 0
  33. INTEGRATED: 0
  34. KERNEL_EXEC_TIMEOUT: 1
  35. L2_CACHE_SIZE: 75497472
  36. LOCAL_L1_CACHE_SUPPORTED: 1
  37. MANAGED_MEMORY: 1
  38. MAXIMUM_SURFACE1D_LAYERED_LAYERS: 2048
  39. MAXIMUM_SURFACE1D_LAYERED_WIDTH: 32768
  40. MAXIMUM_SURFACE1D_WIDTH: 32768
  41. MAXIMUM_SURFACE2D_HEIGHT: 65536
  42. MAXIMUM_SURFACE2D_LAYERED_HEIGHT: 32768
  43. MAXIMUM_SURFACE2D_LAYERED_LAYERS: 2048
  44. MAXIMUM_SURFACE2D_LAYERED_WIDTH: 32768
  45. MAXIMUM_SURFACE2D_WIDTH: 131072
  46. MAXIMUM_SURFACE3D_DEPTH: 16384
  47. MAXIMUM_SURFACE3D_HEIGHT: 16384
  48. MAXIMUM_SURFACE3D_WIDTH: 16384
  49. MAXIMUM_SURFACECUBEMAP_LAYERED_LAYERS: 2046
  50. MAXIMUM_SURFACECUBEMAP_LAYERED_WIDTH: 32768
  51. MAXIMUM_SURFACECUBEMAP_WIDTH: 32768
  52. MAXIMUM_TEXTURE1D_LAYERED_LAYERS: 2048
  53. MAXIMUM_TEXTURE1D_LAYERED_WIDTH: 32768
  54. MAXIMUM_TEXTURE1D_LINEAR_WIDTH: 268435456
  55. MAXIMUM_TEXTURE1D_MIPMAPPED_WIDTH: 32768
  56. MAXIMUM_TEXTURE1D_WIDTH: 131072
  57. MAXIMUM_TEXTURE2D_ARRAY_HEIGHT: 32768
  58. MAXIMUM_TEXTURE2D_ARRAY_NUMSLICES: 2048
  59. MAXIMUM_TEXTURE2D_ARRAY_WIDTH: 32768
  60. MAXIMUM_TEXTURE2D_GATHER_HEIGHT: 32768
  61. MAXIMUM_TEXTURE2D_GATHER_WIDTH: 32768
  62. MAXIMUM_TEXTURE2D_HEIGHT: 65536
  63. MAXIMUM_TEXTURE2D_LINEAR_HEIGHT: 65000
  64. MAXIMUM_TEXTURE2D_LINEAR_PITCH: 2097120
  65. MAXIMUM_TEXTURE2D_LINEAR_WIDTH: 131072
  66. MAXIMUM_TEXTURE2D_MIPMAPPED_HEIGHT: 32768
  67. MAXIMUM_TEXTURE2D_MIPMAPPED_WIDTH: 32768
  68. MAXIMUM_TEXTURE2D_WIDTH: 131072
  69. MAXIMUM_TEXTURE3D_DEPTH: 16384
  70. MAXIMUM_TEXTURE3D_DEPTH_ALTERNATE: 32768
  71. MAXIMUM_TEXTURE3D_HEIGHT: 16384
  72. MAXIMUM_TEXTURE3D_HEIGHT_ALTERNATE: 8192
  73. MAXIMUM_TEXTURE3D_WIDTH: 16384
  74. MAXIMUM_TEXTURE3D_WIDTH_ALTERNATE: 8192
  75. MAXIMUM_TEXTURECUBEMAP_LAYERED_LAYERS: 2046
  76. MAXIMUM_TEXTURECUBEMAP_LAYERED_WIDTH: 32768
  77. MAXIMUM_TEXTURECUBEMAP_WIDTH: 32768
  78. MAX_BLOCKS_PER_MULTIPROCESSOR: 24
  79. MAX_BLOCK_DIM_X: 1024
  80. MAX_BLOCK_DIM_Y: 1024
  81. MAX_BLOCK_DIM_Z: 64
  82. MAX_GRID_DIM_X: 2147483647
  83. MAX_GRID_DIM_Y: 65535
  84. MAX_GRID_DIM_Z: 65535
  85. MAX_PERSISTING_L2_CACHE_SIZE: 51904512
  86. MAX_PITCH: 2147483647
  87. MAX_REGISTERS_PER_BLOCK: 65536
  88. MAX_REGISTERS_PER_MULTIPROCESSOR: 65536
  89. MAX_SHARED_MEMORY_PER_BLOCK: 49152
  90. MAX_SHARED_MEMORY_PER_BLOCK_OPTIN: 101376
  91. MAX_SHARED_MEMORY_PER_MULTIPROCESSOR: 102400
  92. MAX_THREADS_PER_BLOCK: 1024
  93. MAX_THREADS_PER_MULTIPROCESSOR: 1536
  94. MEMORY_CLOCK_RATE: 10501000
  95. MEMORY_POOLS_SUPPORTED: 1
  96. MULTIPROCESSOR_COUNT: 128
  97. MULTI_GPU_BOARD: 0
  98. MULTI_GPU_BOARD_GROUP_ID: 0
  99. PAGEABLE_MEMORY_ACCESS: 1
  100. PAGEABLE_MEMORY_ACCESS_USES_HOST_PAGE_TABLES: 0
  101. PCI_BUS_ID: 172
  102. PCI_DEVICE_ID: 0
  103. PCI_DOMAIN_ID: 0
  104. READ_ONLY_HOST_REGISTER_SUPPORTED: 0
  105. RESERVED_SHARED_MEMORY_PER_BLOCK: 1024
  106. SINGLE_TO_DOUBLE_PRECISION_PERF_RATIO: 64
  107. STREAM_PRIORITIES_SUPPORTED: 1
  108. SURFACE_ALIGNMENT: 512
  109. TCC_DRIVER: 0
  110. TEXTURE_ALIGNMENT: 512
  111. TEXTURE_PITCH_ALIGNMENT: 32
  112. TOTAL_CONSTANT_MEMORY: 65536
  113. UNIFIED_ADDRESSING: 1
  114. 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精品书籍下载 https://www.cnblogs.com/testing-/p/17438558.html
  • python八字排盘 https://github.com/china-testing/bazi
  • 联系方式:钉ding或V信: pythontesting
2.3 在PyCUDA 中实现内核

4.png

我们已经使用 PyCUDA 编写了一个基本的向量加法内核,但现在我们想进一步了解 PyCUDA 如何让我们在 Python 脚本中插入和运行自定义 CUDA C 代码。我们希望熟悉整个主机-设备工作流程:分配内存、移动数据、编写更灵活的内核、动态编译、启动内核,然后检索和验证结果。
这个示例比我们之前的示例更好。在这里,我们将讨论参数化、尝试新的操作,并阐明为什么 PyCUDA 是 Python 和 CUDA 生态系统之间如此坚实的桥梁。
2.3.1 准备主机数据

我们将首先设置两个输入数组和一个用于输出的占位符。我们将开始在主机上使用 NumPy 来简化设置。
  1. >>> import numpy as np
  2. ... N = 8
  3. ... a_host = np.arange(N, dtype=np.float32)
  4. ... b_host = np.arange(N, 0, -1).astype(np.float32)
  5. ... print("Input Array A:", a_host)
  6. ... print("Input Array B:", b_host)
  7. ...
  8. Input Array A: [0. 1. 2. 3. 4. 5. 6. 7.]
  9. Input Array B: [8. 7. 6. 5. 4. 3. 2. 1.]
复制代码
为了清晰起见,我们选择较小的数组,但同样的工作流程也适用于更大的数据集。
2.3.2 配设备内存

使用 PyCUDA,我们将这些数组传输到 GPU。我们还为结果分配了空间。
  1. >>> import pycuda.autoinit
  2. ... import pycuda.driver as drv
  3. ... import pycuda.gpuarray as gpuarray
  4. ... a_device = gpuarray.to_gpu(a_host)
  5. ... b_device = gpuarray.to_gpu(b_host)
  6. ... c_device = gpuarray.empty_like(a_device)
  7. ...
复制代码
此时,a_device 和 b_device 位于 GPU 上,c_device 为结果保留空间。
2.3.3 编写自定义 CUDA C 内核

这正是 PyCUDA 的优势所在。我们可以将 CUDA C 代码以字符串形式嵌入,并在运行时进行编译。这样,我们的内核将逐个元素地添加两个数组,但我们也可以轻松地更改操作。
以下是 CUDA C 脚本:
  1. ... kernel_code = """
  2. ... __global__ void add_arrays(float *a, float *b, float *c, int n)
  3. ... {
  4. ...     int idx = threadIdx.x + blockDim.x * blockIdx.x;
  5. ...    if (idx < n)
  6. ...    {
  7. ...        c[idx] = a[idx] + b[idx];  // Try changing this operation!
  8. ...    }
  9. ... }
  10. ... """
  11. ... mod = SourceModule(kernel_code)
  12. ... add_arrays = mod.get_function("add_arrays")
  13. ...
  14. >>> threads_per_block = 4
  15. ... blocks_per_grid = (N + threads_per_block - 1) // threads_per_block
  16. ...
复制代码
CUDA 要求我们指定每个块中要运行的线程数以及要启动的块数。为简单起见,我们可以使用 4 作为块大小,并计算覆盖所有元素的网格大小。
2.3.4 启动内核并验证结果

然后,我们使用 PyCUDA 的函数接口调用内核。所有指针和参数都按照它们在内核中出现的顺序传递。
  1. >>> add_arrays(
  2. ...    a_device, b_device, c_device, np.int32(N),
  3. ...    block=(threads_per_block, 1, 1), grid=(blocks_per_grid, 1)
  4. ... )
复制代码
内核在 GPU 上异步运行,并行处理所有元素。
计算完成后,我们将结果从 GPU 复制回主机,并与 CPU 计算结果进行验证。
  1. >>> c_host = c_device.get()
  2. ... print("Result Array C:", c_host)
  3. ... # Validate correctness
  4. ... expected = a_host + b_host
  5. ... if np.allclose(c_host, expected):
  6. ...    print("Result matches CPU computation.")
  7. ... else:
  8. ...    print("Mismatch found!")
  9. ...
  10. Result Array C: [8. 8. 8. 8. 8. 8. 8. 8.]
  11. 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 内核,从而强化了主机-设备工作流程的各个方面。

来源:豆瓜网用户自行投稿发布,如果侵权,请联系站长删除

相关推荐

您需要登录后才可以回帖 登录 | 立即注册