4

I have been trying for the last few days to get the temperature of my GPU using C++

using the NVAPI i have the following code

#include "stdafx.h"
#include "nvapi.h"


int _tmain(int argc, _TCHAR* argv[])
{
    NvAPI_Status ret = NVAPI_OK;
    int i=0;

    NvDisplayHandle hDisplay_a[NVAPI_MAX_PHYSICAL_GPUS*2] = {0};

    ret = NvAPI_Initialize();

    if (!ret == NVAPI_OK){
        NvAPI_ShortString string;
        NvAPI_GetErrorMessage(ret, string);
        printf("NVAPI NvAPI_Initialize: %s\n", string);
    }

    NvAPI_ShortString ver;

    NvAPI_GetInterfaceVersionString(ver);
    printf("NVAPI Version: %s\n", ver);

    NvU32 cnt;

    NvPhysicalGpuHandle phys;

    ret = NvAPI_EnumPhysicalGPUs(&phys, &cnt);

    if (!ret == NVAPI_OK){
        NvAPI_ShortString string;
        NvAPI_GetErrorMessage(ret, string);
        printf("NVAPI NvAPI_EnumPhysicalGPUs: %s\n", string);
    }

    NvAPI_ShortString name;

    NV_GPU_THERMAL_SETTINGS thermal;

    ret = NvAPI_GPU_GetFullName(phys, name);
    if (!ret == NVAPI_OK){
        NvAPI_ShortString string;
        NvAPI_GetErrorMessage(ret, string);
        printf("NVAPI NvAPI_GPU_GetFullName: %s\n", string);
    }

    printf("Name: %s\n", name);
    thermal.version =NV_GPU_THERMAL_SETTINGS_VER;
    ret = NvAPI_GPU_GetThermalSettings(phys,0, &thermal);

    if (!ret == NVAPI_OK){
        NvAPI_ShortString string;
        NvAPI_GetErrorMessage(ret, string);
        printf("NVAPI NvAPI_GPU_GetThermalSettings: %s\n", string);
    }

    printf("Temp: %l C\n", thermal.sensor[0].currentTemp);

    return 0;
}

The output i get is

NVAPI Version: NVidia Complete Version 1.10
Name: GeForce GTX 680
Temp:  C

So NVAPI is initializing, and it can find my GPU which is a GTX680, but it wont return a temperature

Shuttleu
  • 123
  • 2
  • 6
  • to print a long int, `printf("Temp: %l C\n")` should be `printf("Temp: %li C\n")`. l is just a length specifier, you should also specify the type it affects. Have a look [here](http://www.cplusplus.com/reference/cstdio/printf/) – Tom Knapen Mar 29 '13 at 19:31
  • thank you so much i guess i should have checked my types better – Shuttleu Mar 29 '13 at 19:38

4 Answers4

3

printf is very sensitive to the size and type of parameters it is passed.

Since currentTemp is fixed as a 32 bit unsigned (and C++ does not guarantee specific bitcounts for the types printf likes), cast it to a type that printf can anticipate.

printf("Temp: %u C\n", static_cast<unsigned>(thermal.sensor[0].currentTemp) );
Drew Dormann
  • 59,987
  • 13
  • 123
  • 180
  • Shouldn't `static_cast` be `static_cast`, since this question is tagged C++? unsigned on its own was a valid specifier in C, in C++ it no longer is. Also see my comment on OP's question, since this answer isn't directly related to OP's problem. – Tom Knapen Mar 29 '13 at 19:40
  • @TomKnapen it remains a valid type in C++. See [this reference](http://en.cppreference.com/w/cpp/language/types) – Drew Dormann Mar 29 '13 at 19:42
  • Yeah, I just ran a quick test and noticed it is still valid. I was already looking [here](http://stackoverflow.com/editing-help#comment-formatting) to see how to strike-through text in my comment. – Tom Knapen Mar 29 '13 at 19:44
3

I think that the problem is that you are required to set thermal settings in the following way:

NV_GPU_THERMAL_SETTINGS ThermalInfo;
ThermalInfo.version = NV_GPU_THERMAL_SETTINGS_VER_2;
ThermalInfo.sensor[0].controller = NVAPI_THERMAL_CONTROLLER_GPU_INTERNAL;
ThermalInfo.sensor[0].target = NVAPI_THERMAL_TARGET_GPU;

Also you should also write:

NvPhysicalGpuHandle  nvGPUHandle[NVAPI_MAX_PHYSICAL_GPUS];

because you could corrupt memory. (Note look at NvAPI_EnumPhysicalGPUs in the documentation supplied with NVAPI).

evilmacro
  • 31
  • 1
0

Your code almost works, just typos on these lines ;)

(!ret == NVAPI_OK)

change them to :

(ret != NVAPI_OK)
Tanguy
  • 2,227
  • 1
  • 18
  • 8
0

You are already able to get correct value for thermal.sensor[0].currentTemp,

just you are mistaking while printing.

Please Look at thermal.sensor structure in Nvapi:

struct
{
    NV_THERMAL_CONTROLLER       controller;         //!< internal, ADM1032, MAX6649...
    NvS32                       defaultMinTemp;     //!< Minimum default temperature value of the thermal sensor in degree Celsius
    NvS32                       defaultMaxTemp;     //!< Maximum default temperature value of the thermal sensor in degree Celsius
    NvS32                       currentTemp;        //!< Current temperature value of the thermal sensor in degree Celsius
    NV_THERMAL_TARGET           target;             //!< Thermal sensor targeted - GPU, memory, chipset, powersupply, Visual Computing Device, etc
} sensor[NVAPI_MAX_THERMAL_SENSORS_PER_GPU];

It shows that NvS32 currentTemp is Signed 32 bit integer.