Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot dynamic link nvidia-ml and use gonvml at the same time #8

Open
wangkechun opened this issue Jan 17, 2019 · 1 comment
Open

Comments

@wangkechun
Copy link

example failed to query device count:

package main

// #cgo LDFLAGS: -ldl -lnvidia-ml
// #cgo CFLAGS: -I /usr/local/cuda-8.0/include
/*
#include <stdio.h>
#include "nvml.h"
void testNvml()
{
    nvmlReturn_t result;
    unsigned int device_count, i;

    // First initialize NVML library
    result = nvmlInit();
    if (NVML_SUCCESS != result)
    {
        printf("Failed to initialize NVML: %s\n", nvmlErrorString(result));
        return;
    }

    result = nvmlDeviceGetCount(&device_count);
    if (NVML_SUCCESS != result)
    {
        printf("Failed to query device count: %s\n", nvmlErrorString(result));
        return;
    }
    printf("Found %d device%s\n\n", device_count, device_count != 1 ? "s" : "");
}
*/
import "C"

import (
	"fmt"

	"github.com/mindprince/gonvml"
)

func testGoNvml() (value []string) {
	err := gonvml.Initialize()
	if err != nil {
		return
	}
	defer func() { _ = gonvml.Shutdown() }()

	n, err := gonvml.DeviceCount()
	if err != nil {
		panic(err)
	}
	fmt.Println("testGoNvml gpu num:", n)
	return
}

func main() {
	C.testNvml()
	testGoNvml()
	C.testNvml()
}

output:

Failed to query device count: nvmlErrorString Function Not Found
testGoNvml gpu num: 8
Found 8 devices

example ok

package main

// #cgo LDFLAGS: -ldl -lnvidia-ml
// #cgo CFLAGS: -I /usr/local/cuda-8.0/include
/*
#include <stdio.h>
#include "nvml.h"
void testNvml()
{
    nvmlReturn_t result;
    unsigned int device_count, i;

    // First initialize NVML library
    result = nvmlInit();
    if (NVML_SUCCESS != result)
    {
        printf("Failed to initialize NVML: %s\n", nvmlErrorString(result));
        return;
    }

    result = nvmlDeviceGetCount(&device_count);
    if (NVML_SUCCESS != result)
    {
        printf("Failed to query device count: %s\n", nvmlErrorString(result));
        return;
    }
    printf("Found %d device%s\n\n", device_count, device_count != 1 ? "s" : "");
}
*/
import "C"

func main() {
	C.testNvml()
}

output:

Found 8 devices

This is a simple example, actually a possible situation:

a complex golang program import package a and b
package a import gonvml
package b call libnvidia-xxx use cgo
libnvidia-xxx dynamic link libnvidia-ml
@wangkechun
Copy link
Author

Possible solution:

  1. Add the following line

// #cgo CFLAGS: -fvisibility=hidden

  1. Rename all duplicate symbols like

nvmlReturn_t nvmlDeviceGetCount(unsigned int *deviceCount) {

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant