cmake finder cuda, men undlader at finde cuda biblioteker på Windows

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg har et lille cmake projekt, der fungerer perfekt på Linux, men fejler på Windows 10 (jeg prøvede med to forskellige computere) med de nyeste versioner af cmake og CUDA 8. Det finder CUDA bare fint, men mangler at finde bibliotekerne. Min cmake-fil:


cmake\_minimum\_required(VERSION 3.0)
project(myproject)

find\_package(CUDA REQUIRED)

cuda\_add\_library(myproject STATIC matrix\_mm.cu)
target\_link\_libraries(myproject ${CUDA\_CUBLAS\_LIBRARIES})

message(STATUS "")
message(STATUS "FoundCUDA              : ${CUDA\_FOUND}")
message(STATUS "Cuda cublas libraries  : ${CUDA\_CUBLAS\_LIBRARIES}")


I den samme mappe har jeg overskriften matrix\_mm.cuh:


#include <cstdlib>

namespace myproject {

float* cuda\_mm(const float *a, const float *b, const size\_t m, const size\_t k, const size\_t n);

} /* end namespace myproject */


og matrix\_mm.cu:


#include <cublas\_v2.h>
#include "matrix\_mm.cuh"

namespace myproject {

// Adapted from https://solarianprogrammer.com/2012/05/31/matrix-multiplication-cuda-cublas-curand-thrust/

void gpu\_blas\_mmul(const float *a, const float *b, float *c, const size\_t m, const size\_t k, const size\_t n) {
  int lda = m, ldb = k, ldc = m;
  const float alf = 1;
  const float bet = 0;
  const float *alpha = &alf;
  const float *beta = &bet;

  // Create a handle for CUBLAS
  cublasHandle\_t handle;
  cublasCreate(&handle);

  // Do the actual multiplication
  cublasSgemm(handle, CUBLAS\_OP\_N, CUBLAS\_OP\_N, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc);

  // Destroy the handle
  cublasDestroy(handle);
}

float* cuda\_mm(const float *a, const float *b, const size\_t m, const size\_t k, const size\_t n) {
  size\_t const a\_bytes = m * k * sizeof(float);
  size\_t const b\_bytes = k * n * sizeof(float);
  size\_t const c\_bytes = m * n * sizeof(float);
  float* c = (float*)std::malloc(c\_bytes);

  float *d\_A, *d\_B, *d\_C;
  cudaMalloc(&d\_A, a\_bytes);
  cudaMalloc(&d\_B, b\_bytes);
  cudaMalloc(&d\_C, c\_bytes);

  cudaMemcpy(d\_A, a, a\_bytes, cudaMemcpyHostToDevice);
  cudaMemcpy(d\_B, b, b\_bytes, cudaMemcpyHostToDevice);

  gpu\_blas\_mmul(d\_A, d\_B, d\_C, m, k, n);

  cudaMemcpy(c, d\_C, c\_bytes, cudaMemcpyDeviceToHost);

  cudaFree(d\_A);
  cudaFree(d\_B);
  cudaFree(d\_C);

  return c;
}

} /* end namespace myproject */


På Linux får jeg:


-- FoundCUDA              : TRUE
-- Toolkit root           : /usr
-- Cuda cublas libraries  : /usr/lib/x86\_64-linux-gnu/libcublas.so


Mens jeg får begge Windows 10-maskiner


-- FoundCUDA              : TRUE
-- Toolkit root           : C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v8.0
-- Cuda cublas libraries  : CUDA\_cublas\_LIBRARY-NOTFOUND;CUDA\_cublas\_device\_LIBRARY-NOTFOUND


... og selvfølgelig undlader det at kompilere, fordi linkeren ikke kan finde cublas.


Jeg forsøgte et par ting: at gøre lib SHARED i stedet for STATIC, sørgede jeg for, at Cuda var i Windows 'miljøvariabler osv., Men ingenting virker.

Bedste reference


Dette er CMake-kodestykket, jeg bruger til at finde CUDA 8 på Windows 10 med CMake 3.7.1:


cmake\_minimum\_required(VERSION 3.7)
project(myproject)

# Check for CUDA ENV vars
IF(NOT DEFINED ENV{CUDA\_PATH})
    MESSAGE(FATAL\_ERROR "CUDA\_PATH Environment variable is not set.")
ENDIF(NOT DEFINED ENV{CUDA\_PATH})

# Set the toolkit path
FILE(TO\_CMAKE\_PATH "$ENV{CUDA\_PATH}" CUDA\_TOOLKIT\_ROOT\_DIR)
SET(CUDA\_TOOLKIT\_ROOT\_DIR ${CUDA\_TOOLKIT\_ROOT\_DIR} CACHE STRING "Root directory of the Cuda Library" FORCE)

# Find the package
find\_package(CUDA REQUIRED)

# Create and interface library as a link target (Requires CMake 3.7.0+)
add\_library(cuda INTERFACE)
set\_target\_properties(cuda PROPERTIES
    INTERFACE\_INCLUDE\_DIRECTORIES ${CUDA\_INCLUDE\_DIRS}
    INTERFACE\_LINK\_LIBRARIES "${CUDA\_LIBRARIES};${CUDA\_CUFFT\_LIBRARIES};${CUDA\_CUBLAS\_LIBRARIES}"
)

SET(CUDA\_HOST\_COMPILATION\_CPP ON)

cuda\_add\_library(myproject STATIC matrix\_mm.cu)
target\_link\_libraries(myproject cuda)


Jeg tror, ​​at citaterne omkring bibliotekerne er vigtige, da Windows-stien vil indeholde mellemrum.


Jeg vil også sørge for, at du sletter din cache og genskaber projektet. Det er ofte årsagen til fejl, når variable værdier vises korrekt på overfladen (eller når du ændrer en ikke-FORCE cache-variabel).