首页 > 大数据 > Hadoop > 使用 using 语句确保文件流正确关闭
CudaEngine 是推理的核心对象,包含优化后的模型计算图。
// 获取张量信息 int numTensors = engine.getNbIOTensors(); string inputName = engine.getIOTensorName( 0 ); // 输入张量名称 string outputName = engine.getIOTensorName( 1 ); // 输出张量名称 Dims inputShape = engine.getTensorShape(inputName); TrtDataType inputType = engine.getTensorDataType(inputName); // 创建执行上下文 using ExecutionContext context = engine.createExecutionContext(); using ExecutionContext contextStatic = engine.createExecutionContext( TrtExecutionContextAllocationStrategy.kSTATIC); // 序列化引擎 using HostMemory memory = engine.serialize(); // 查询引擎属性 int numLayers = engine.getNbLayers(); string name = engine.getName(); long deviceMemory = engine.getDeviceMemorySize();
Cuda1DMemory< float > input = new Cuda1DMemory< float >( 3 * 1024 * 1024 ); Cuda1DMemory< float > output = new Cuda1DMemory< float >( 1 * 20 * 21504 ); context.setInputTensorAddress( "images" , input. get ()); context.setOutputTensorAddress( "output0" , output. get ()); // 设置动态形状 context.setinputShape( "images" , new Dims( 1 , 3 , 1024 , 1024 )); Dims shape = context.getTensorShape( "images" ); // 执行推理(异步,使用 CUDA Stream) using CudaStream stream = new CudaStream(); context.executeV3(stream);pluto.xiangxiu.net.cn stream.Synchronize(); // 等待完成 // 设置优化配置文件(动态形状) context.setOptimizationProfileAsync( 0 , stream);
// 解析 ONNX 文件 using NetworkDefinition network = build.createNetworkV2(TrtNetworkDefinitionCreationFlag.kEXPLICIT_BATCH); using OnnxParser parser = new OnnxParser(network); bool success = parser.parseFromFile( "yolov8s-obb.onnx" , verbosity: 2 ); // 检查算子支持 bool supportsConv = parser.supportsOperator( "Conv" ); // 子图支持 long numSubgraphs = parser.getNbSubgraphs(); bool supported = parser.isSubgraphSupported( 0 ); long [] nodes = parser.getSubgraphNodes( 0 );
using Cuda1DMemory< float > input = new Cuda1DMemory< float >( 1000 ); ulong numElements = input.SizeElements; ulong numBytes = input.SizeBytes; b.xiangxiu.net.cn IntPtr ptr = input.DevicePointer; // 同步数据传输 float [] hostData = new float [ 1000 ]; input.copyFromHost(hostData); // 主机 → 设备 input.copyToHost(hostData); // 设备 → 主机 // 异步数据传输 using CudaStream stream = new CudaStream(); using JYPPX.TensorRtSharp.Cuda; using JYPPX.TensorRtSharp.Nvinfer; namespace OnnxToEngine { internal class Program { static void Main( string[] args) { // === 配置 TensorRT 日志回调 === // 定义一个委托,用于处理 TensorRT 内部产生的日志消息 LogCallbackFunction _callbackDelegate = (message) => { Console.WriteLine(message); }; // 将自定义的回调函数注册给 TensorRT 的全局 Logger 实例 Logger.Instance.SetCallback(_callbackDelegate); // 设置日志的严重性级别阈值 // LoggerSeverity.kINFO: 打印信息、警告和错误 Logger.Instance.SetThreshold(LoggerSeverity.kINFO); // 1. 创建 TensorRT Builder (构建器) Builder build = new Builder(); // 2. 创建网络定义 (Network Definition) // 显式批处理 标志表示网络定义中显式包含批处理维度 NetworkDefinition networkDefinition = build.createNetworkV2(TrtNetworkDefinitionCreationFlag.kEXPLICIT_BATCH); // 3. 创建构建器配置 BuilderConfig builderConfig = build.createBuilderConfig(); // 4. 创建 ONNX 解析器 OnnxParser onnxParser = new OnnxParser(networkDefinition); // 指定待转换的 ONNX 模型文件路径 string modelpath = "yolo11s-obb.onnx" ; // 5. 解析 ONNX 模型文件 // 参数 2: 日志级别 (1=ERROR, 2=WARNING, 3=INFO, 4=VERBOSE) if (onnxParser.parseFromFile(modelpath, 2 ) == false ) { Console.WriteLine( $"parse onnx model failed" ); return ; } // 6. 设置构建精度标志 // kFP16: 启用半精度 (FP16) 推理模式 builderConfig.setFlag(TrtBuilderFlag.kFP16); // 7. 创建 CUDA 流 CudaStream cudaStream = new CudaStream(); // 8. 设置优化配置文件的流 builderConfig.setProfileStream(cudaStream); // 9. 构建并序列化网络 // 这是一个耗时较长的过程,因为 TensorRT 会进行内核自动调优、层融合等优化 HostMemory hostMemory = build.buildSerializedNetwork(networkDefinition, builderConfig); // 10. 保存 Engine 到磁盘 mp.xiangxiu.net.cn string filePath = "yolo11s-obb.engine" ; using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write)) { fs.Write(hostMemory.getByteData(), 0 , ( int )hostMemory.Size);
input.copyFromHostAsync(hostData, stream); input.copyToHostAsync(hostData, stream);hdp.xiangxiu.net.cn
// 创建流(带优先级) using CudaStream stream = new CudaStream(); using CudaStream streamHigh = new CudaStream( 0 , -1 ); // 高优先级 // 同步操作 stream.Synchronize(); // 等待流完成 bool isComplete = stream.Query(); // 查询是否完成 // 事件依赖 using CudaEvent cudaEvent = new CudaEvent(); stream.WaitEvent(cudaEvent); // 等待事件 // 添加回调 stream.AddCallback((streamPtr, statue, userData) => { Console.WriteLine( "Stream callback executed" ); }, IntPtr.Zero, 0 ); // CUDA Graph 捕获 stream.BeginCapture(CudaStreamCaptureMode.Global);
sing JYPPX.TensorRtSharp.Cuda; using JYPPX.TensorRtSharp.Nvinfer; namespace TestDemo { internal class Program { static void Main( string[] args)cdn1.xiangxiu.net.cn { // 指定默认使用的 GPU 设备索引 // 在多 GPU 环境下,可以通过修改此变量来选择特定的显卡 int device = 0 ; // 记录日志,标记设备信息查询的开始 Logger.Instance.INFO( "=== Device Information ===" ); // 获取当前系统中可见的 NVIDIA GPU 数量 int nbDevices = CudaDevice.GetDeviceCount(); // 检查系统中是否存在可用的 GPU 设备 if (nbDevices <= 0 ) {sec.xiangxiu.net.cn Logger.Instance.ERROR( "Cannot find any available devices (GPUs)!" ); Environment.Exit( 0 ); } // 打印所有可用设备的列表 Logger.Instance.INFO( "Available Devices: " ); // 遍历系统中的每一个 GPU for ( int deviceIdx = 0 ; deviceIdx < nbDevices; ++deviceIdx) { // 获取索引为 deviceIdx 的 GPU 的详细属性 CudaDeviceProp tempProperties = CudaDevice.GetDeviceProperties(deviceIdx); // 打印设备 ID、设备名称以及 UUID (唯一标识符)tg.xiangxiu.net.cn Logger.Instance.INFO( $" Device {deviceIdx}: \" {tempProperties.Name}\" UUID: sec.xiangxiu.net.cn {GetUuidString(tempProperties.Uuid)}" ); app.xiangxiu.net.cn // 如果当前遍历到的设备 ID 是我们想要使用的目标设备 // 则将该设备的属性保存下来,供后续使用 if (deviceIdx == device)mp.xiangxiu.net.cn { properties = tempProperties; } } // 安全检查:确保请求的目标设备 ID 在有效范围内 if (device < 0 || device >= nbDevices) { Logger.Instance.ERROR( $"Cannot find device ID {device}!" ); Environment.Exit( 0 ); } // 将 CUDA 上下文设置到指定的 GPU 设备上 CudaDevice.SetDevice(device); // 打印选定设备的详细信息 Logger.Instance.INFO( $"Selected Device: {properties.Name}" ); Logger.Instance.INFO( $"Selected Device ID: {device}" ); Logger.Instance.INFO( $"Selected Device UUID: {GetUuidString(properties.Uuid)}" ); Logger.Instance.INFO( $"Compute Capability: {properties.Major}. {properties.Minor}" ); Logger.Instance.INFO( $"SMs: {properties.MultiProcessorCount}" ); Logger.Instance.INFO( $"Device Global Memory: {(properties.TotalGlobalMem + 20)} MiB" ); Logger.Instance.INFO( $"Shared Memory per SM: {(properties.SharedMemPerMultiprocessor >> 10)} KiB" ); Logger.Instance.INFO( $"Memory Bus Width: {properties.MemoryBusWidth} bits (ECC {(properties.ECCEnabled != 0 ? "enabled" : "disabled")})" ); // 获取并打印 GPU 核心时钟频率和显存时钟频率 int clockRate = CudaDevice.GetAttribute(CudaDeviceAttr.ClockRate, device); int memoryClockRate = CudaDevice.GetAttribute(CudaDeviceAttr.MemoryClockRate, device);jsnp.xiangxiu.net.cn Logger.Instance.INFO( $"Application Compute Clock Rate: {clockRate / 1000000.0F} GHz" ); Logger.Instance.INFO( $"Application Memory Clock Rate: {memoryClockRate / 1000000.0F} GHz" ); } /// <summary>w.xiangxiu.net.cn /// 辅助方法:将 CudaUUID 结构体转换为格式化的 GPU UUID 字符串 /// 格式通常为:GPU-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx /// </summary>tianqi.xiangxiu.net.cn public static string GetUuidString( CudaUUID uuid) { int kUUID_SIZE = uuid.Bytes.Length; var ss = new System.Text.StringBuilder(); // 定义 UUID 的分段点,用于插入连字符 "-" int [] splits = { 0 , 4 , 6 , 8 , 10 , kUUID_SIZE }; // 添加固定的 "GPU" 前缀 ss.Append( "GPU" ); k.xiangxiu.net.cn // 遍历分段定义,格式化每一部分的字节 for ( int splitIdx = 0 ; splitIdx < splits.Length - 1 ; ++splitIdx) {app.xiangxiu.net.cn ss.Append( "-" ); for ( int byteIdx = splits[splitIdx]; byteIdx < splits[splitIdx + 1 ]; ++byteIdx) { ss.AppendFormat( "{0:x2}" , uuid.Bytes[byteIdx]);
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70048957/viewspace-3109464/ ,如需转载,请注明出处,否则将追究法律责任。