首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将uint数组传递给要填充的Dll ( NVML库)

将uint数组传递给要填充的Dll ( NVML库)
EN

Stack Overflow用户
提问于 2022-09-09 02:35:06
回答 1查看 38关注 0票数 0

我试图将一个uint数组从NVML函数nvmlDeviceGetAccountingPids(医生在这里)中传递给C#,下面是我到目前为止所得到的最起码的工作示例:

代码语言:javascript
复制
    {
        public const string NVMLDLL = "nvml.dll";
        public static class Constants
        {
            public const int NVML_DEVICE_INFOROM_VERSION_BUFFER_SIZE = 16;
            public const int NVML_DEVICE_NAME_BUFFER_SIZE = 64;
            public const int NVML_DEVICE_NAME_V2_BUFFER_SIZE = 96;
            public const int NVML_DEVICE_PART_NUMBER_BUFFER_SIZE = 80;
            public const int NVML_DEVICE_SERIAL_BUFFER_SIZE = 30;
            public const int NVML_DEVICE_UUID_BUFFER_SIZE = 80;
            public const int NVML_DEVICE_UUID_V2_BUFFER_SIZE = 96;
            public const int NVML_DEVICE_VBIOS_VERSION_BUFFER_SIZE = 32;
            public const int NVML_SYSTEM_DRIVER_VERSION_BUFFER_SIZE = 80;
            public const int NVML_SYSTEM_NVML_VERSION_BUFFER_SIZE = 80;
            public const int NVML_INIT_FLAG_NO_ATTACH = 2;
            public const int NVML_INIT_FLAG_NO_GPUS = 1;

        }
        public enum nvmlReturn_t
        {
            NVML_SUCCESS = 0,                           // The operation was successful. 
            NVML_ERROR_UNINITIALIZED = 1,               // NVML was not first initialized with nvmlInit(). 
            NVML_ERROR_INVALID_ARGUMENT = 2,            // A supplied argument is invalid. 
            NVML_ERROR_NOT_SUPPORTED = 3,               // The requested operation is not available on target device. 
            NVML_ERROR_NO_PERMISSION = 4,               // The current user does not have permission for operation. 
            NVML_ERROR_ALREADY_INITIALIZED = 5,         // Deprecated: Multiple initializations are now allowed through ref counting. 
            NVML_ERROR_NOT_FOUND = 6,                   // A query to find an object was unsuccessful. 
            NVML_ERROR_INSUFFICIENT_SIZE = 7,           // An input argument is not large enough. 
            NVML_ERROR_INSUFFICIENT_POWER = 8,          // A device's external power cables are not properly attached. 
            NVML_ERROR_DRIVER_NOT_LOADED = 9,           // NVIDIA driver is not loaded. 
            NVML_ERROR_TIMEOUT = 10,                    // User provided timeout passed. 
            NVML_ERROR_IRQ_ISSUE = 11,                  // NVIDIA Kernel detected an interrupt issue with a GPU. 
            NVML_ERROR_LIBRARY_NOT_FOUND = 12,          // NVML Shared Library couldn't be found or loaded. 
            NVML_ERROR_FUNCTION_NOT_FOUND = 13,         // Local version of NVML doesn't implement this function. 
            NVML_ERROR_CORRUPTED_INFOROM = 14,          // infoROM is corrupted 
            NVML_ERROR_GPU_IS_LOST = 15,                // The GPU has fallen off the bus or has otherwise become inaccessible. 
            NVML_ERROR_RESET_REQUIRED = 16,             // The GPU requires a reset before it can be used again. 
            NVML_ERROR_OPERATING_SYSTEM = 17,           // The GPU control device has been blocked by the operating system/cgroups. 
            NVML_ERROR_LIB_RM_VERSION_MISMATCH = 18,    // RM detects a driver/library version mismatch. 
            NVML_ERROR_IN_USE = 19,                     // An operation cannot be performed because the GPU is currently in use. 
            NVML_ERROR_MEMORY = 20,                     // Insufficient memory. 
            NVML_ERROR_NO_DATA = 21,                    // No data. 
            NVML_ERROR_VGPU_ECC_NOT_SUPPORTED = 22,     // The requested vgpu operation is not available on target device, becasue ECC is enabled. 
            NVML_ERROR_INSUFFICIENT_RESOURCES = 23,     // Ran out of critical resources, other than memory. 
            NVML_ERROR_FREQ_NOT_SUPPORTED = 24,         // Ran out of critical resources, other than memory. 
            NVML_ERROR_UNKNOWN = 999                    // An internal driver error occurred. 
        }
        [DllImport(NVMLDLL)]
        private static extern nvmlReturn_t nvmlInit_v2();
        [DllImport(NVMLDLL)]
        private static extern nvmlReturn_t nvmlShutdown();
        [DllImport(NVMLDLL)]
        private static extern nvmlReturn_t nvmlDeviceGetCount_v2(out uint deviceCount);
        [DllImport(NVMLDLL)]
        private static extern nvmlReturn_t nvmlDeviceGetHandleByIndex_v2(int index, out IntPtr handle);
        [DllImport(NVMLDLL)]
        private static extern nvmlReturn_t nvmlDeviceGetName(IntPtr device, [MarshalAs(UnmanagedType.LPStr)] StringBuilder deviceName, uint length);
        [DllImport(NVMLDLL)]
        private static extern nvmlReturn_t nvmlDeviceGetAccountingPids(IntPtr device, ref uint count, [In, Out] uint[] pids);

        static void Main(string[] args)
        {
            if (nvmlInit_v2() == nvmlReturn_t.NVML_SUCCESS)
            {
                nvmlDeviceGetCount_v2(out uint deviceCount);
                for (int i = 0; i < deviceCount; i++)
                {
                    StringBuilder name = new();
                    nvmlDeviceGetHandleByIndex_v2(i, out IntPtr _device);
                    nvmlDeviceGetName(_device, name, Constants.NVML_DEVICE_NAME_V2_BUFFER_SIZE);

                    // arbitrary number for now
                    uint count = 5;
                    uint[] pids = new uint[count];
                    nvmlDeviceGetAccountingPids(_device, ref count, pids);
                    foreach(uint ui in pids) Console.WriteLine(ui);

                }
                nvmlShutdown();
            }
        }
    }

到目前为止,它正在返回使用gpu的进程的正确#,但是PID数组一直在返回所有的0。我对C#没有特别的经验,所以如果有人可以向我展示正确的语法(或者让我知道如果我不得不求助于IntPtr),原始函数具有以下签名:

代码语言:javascript
复制
nvmlReturn_t nvmlDeviceGetAccountingPids ( nvmlDevice_t device, unsigned int* count, unsigned int* pids )
    Parameters

    device
        The identifier of the target device 
    count
        Reference in which to provide the pids array size, and to return the number of elements ready to be queried 
    pids
        Reference in which to return list of process ids

如果有人知道那个魔法组合,我肯定会很感激的,谢谢你抽出时间

EN

回答 1

Stack Overflow用户

发布于 2022-09-09 03:52:59

有时我想我只打一些东西来解决^_^问题

代码语言:javascript
复制
        static void Main(string[] args)
        {
            if (nvmlInit_v2() == nvmlReturn_t.NVML_SUCCESS)
            {
                nvmlDeviceGetCount_v2(out uint deviceCount);
                for (int i = 0; i < deviceCount; i++)
                {
                    StringBuilder name = new();
                    nvmlDeviceGetHandleByIndex_v2(i, out IntPtr _device);
                    nvmlDeviceGetName(_device, name, Constants.NVML_DEVICE_NAME_V2_BUFFER_SIZE);

                    // arbitrary number for now
                    uint count = 0;
                    nvmlDeviceGetAccountingPids(_device, ref count, null);
                    uint[] pids = new uint[count];
                    if (nvmlDeviceGetAccountingPids(_device, ref count, pids) == nvmlReturn_t.NVML_SUCCESS)
                    {
                        foreach (uint ui in pids) Console.WriteLine(ui);
                    }

                }
                nvmlShutdown();
            }

因此,当将计数传递给函数时,它希望得到与数组大小相同的数字,以便填充pids列表(我认为这是合理的)。只需将count设置为"0“并将一个空数组传递给函数,就可以将count设置为数组的大小。创建一个这样大小的新uint数组,传递数组/count和BAM,它将按需要返回pids。谢谢你这么读!如果有人在语法/实践方面有一些建设性的批评,请发表评论,这样我就可以改进这段代码了。祝你有美好的一天

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73656780

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档