Suugaku
Suugaku

Reputation: 2747

cmake finds cuda but fails to find cuda libraries on Windows

I have a small cmake project that works perfectly well on Linux but fails on Windows 10 (I tried with two different computers) with the latest versions of cmake and CUDA 8. It finds CUDA just fine, but fails to find the libraries. My cmake file:

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}")

In the same folder, I have the header 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 */

and 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 */

On Linux I get:

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

While on both Windows 10 machines I get

-- 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

...and of course it fails to compile because the linker can't find cublas.

I tried quite a few things: making the lib SHARED instead of STATIC, I made sure Cuda was in Windows' environmental variables, etc, but nothing works.

Upvotes: 1

Views: 3597

Answers (1)

Nicolas Holthaus
Nicolas Holthaus

Reputation: 8273

This is the CMake snippet I use to find CUDA 8 on Windows 10 with 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)

I think the quotes around the libraries are important since the Windows path will contain spaces.

I would also make sure that you delete your cache and regenerate the project. It's often the cause of errors when variable values appear correct on the surface (or when you make changes to a non-FORCE cache variable).

Upvotes: 1

Related Questions