No way to get PAPI version from library, and PAPI_library_init documentation has issues

Issue #74 resolved
Leor Doron created an issue

As far as I can tell, there’s no way to request the internal version that was used to compile the PAPI library shared object file that gets loaded at run time. The provided utilities (e.g. papi_version.c, print_header.c) can only print the version from the papi.h header that they are compiled with.

Looking at the source, it seems that PAPI_library_init() will only return a version value if it matches the input version argument (and no other errors were encountered). If there is a version mismatch, it returns PAPI_EINVAL, but, contrary to the documentation, that error code is not definitive -- the function also may return PAPI_EINVAL in certain other cases where problems occur. The example code in the function documentation misleadingly contains:

if (retval != PAPI_VER_CURRENT && retval > 0) {...

However, that condition can never be true with the current implementation.

As a fix, I propose that PAPI_library_init() should be changed: when there is a version mismatch, it should return its internal value of PAPI_VER_CURRENT. Note that this would take the mismatch out of the realm of “errors”, since you wouldn’t be able to call the papi_return() macro, and thus the error handler would not be called.

Alternatively (or additionally), add an API function that simply returns the internal PAPI_VER_CURRENT, or maybe even PAPI_VERSION, and which is allowed to be called before PAPI_library_init(). You could reduce confusion by changing the latter to never return a version number; if the versions match, it would simply return PAPI_OK.

Comments (9)

  1. Anthony Danalis

    PAPI_get_opt() does return the version, but only if PAPI has been initialized. We can allow the version to be queried before initialization. Below is a test program:

    #include <stdio.h>
    #include "papi.h"

    int main(int argc, char **argv){
    PAPI_library_init(PAPI_VER_CURRENT);
    unsigned int v = PAPI_get_opt(PAPI_LIB_VERSION,NULL);
    printf("%d.%d.%d.%d\n",PAPI_VERSION_MAJOR(v), PAPI_VERSION_MINOR(v), PAPI_VERSION_REVISION(v), PAPI_VERSION_INCREMENT(v));
    return 0;
    }

  2. Leor Doron reporter

    Just to clarify, are you removing the initialization requirement for calls to PAPI_get_opt(PAPI_LIB_VERSION, NULL) (similar to how it isn’t required for PAPI_DEBUG)? Otherwise, we can only call it if we already know the correct version.

  3. Leor Doron reporter

    Great, thanks! There is still the documentation problem, with the impossible condition in the sample code. Will that also be fixed, or should I file it as its own issue?

  4. Giuseppe Congiu

    No need for a new issue as the PR is still open. I have updated it. Please let me know if I have missed anything else. Thanks

  5. Leor Doron reporter

    Thanks again! I was actually thinking of the initialization example that appears about halfway down this page: https://bitbucket.org/icl/papi/wiki/PAPI-LL.md . The condition (retval != PAPI_VER_CURRENT && retval > 0) will always be false. If there is a version mismatch, PAPI_library_init will return PAPI_EINVAL, which is negative, not the library version (which will now be accessible using PAPI_get_opt). But, note that PAPI_EINVAL does not guarantee to the caller that there was a mismatch, because it might also be returned for other reasons (such as a failure in _papi_hwi_init_global_internal).

    Maybe change the condition to (PAPI_get_opt(PAPI_LIB_VERSION, NULL) != PAPI_VER_CURRENT)? Then, you could move that entire conditional statement to occur above the call to PAPI_library_init.

  6. Log in to comment