From 18098783e1ea3417804125b87ab21c051e48b783 Mon Sep 17 00:00:00 2001
From: Ben Cumming <louncharf@gmail.com>
Date: Mon, 15 May 2017 20:27:01 +0200
Subject: [PATCH] Fix incorrect GPU backend determination

Fixes #266.

Use CUDA to compile the `cell_group_factory` so that the CUDA back end is compiled correctly, instead of the null back end proxy.
  * Added bonus: the miniapp is now compiled using host C++ compiler instead of `nvcc`.

This is a little bit hacky, because this is a stop gap until we have separate compilation of CUDA code.
---
 CMakeLists.txt                  |  5 +++++
 miniapp/CMakeLists.txt          | 10 ++--------
 src/CMakeLists.txt              | 33 ++++++++++++++++++++++++---------
 src/cell_group_factory.cu       |  1 +
 tests/unit/CMakeLists.txt       |  6 ++----
 tests/unit/test_matrix.cu       |  1 +
 tests/validation/CMakeLists.txt |  4 ++--
 7 files changed, 37 insertions(+), 23 deletions(-)
 create mode 100644 src/cell_group_factory.cu

diff --git a/CMakeLists.txt b/CMakeLists.txt
index b08a739f..be8d1dec 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -52,6 +52,11 @@ option(NMC_AUTO_RUN_MODCC_ON_CHANGES
 set(EXTERNAL_LIBRARIES "")
 set(EXTERNAL_INCLUDES "")
 
+#----------------------------------------------------------
+# list of libraries built inside NestMC
+#----------------------------------------------------------
+set(NESTMC_LIBRARIES "")
+
 #----------------------------------------------------------
 # Threading model selection
 #----------------------------------------------------------
diff --git a/miniapp/CMakeLists.txt b/miniapp/CMakeLists.txt
index 801a48d2..c41f7c51 100644
--- a/miniapp/CMakeLists.txt
+++ b/miniapp/CMakeLists.txt
@@ -13,14 +13,9 @@ set(MINIAPP_SOURCES_CUDA
     morphology_pool.cpp
 )
 
-if(NMC_WITH_CUDA)
-    cuda_add_executable(miniapp.exe ${MINIAPP_SOURCES_CUDA} ${HEADERS})
-    target_link_libraries(miniapp.exe LINK_PUBLIC gpu)
-else()
-    add_executable(miniapp.exe ${MINIAPP_SOURCES} ${HEADERS})
-endif()
+add_executable(miniapp.exe ${MINIAPP_SOURCES} ${HEADERS})
 
-target_link_libraries(miniapp.exe LINK_PUBLIC nestmc)
+target_link_libraries(miniapp.exe LINK_PUBLIC ${NESTMC_LIBRARIES})
 target_link_libraries(miniapp.exe LINK_PUBLIC ${EXTERNAL_LIBRARIES})
 
 if(NMC_WITH_MPI)
@@ -32,4 +27,3 @@ set_target_properties(miniapp.exe
    PROPERTIES
    RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/miniapp"
 )
-
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 469086ad..badd3733 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,7 +1,7 @@
 set(BASE_SOURCES
     common_types_io.cpp
     cell.cpp
-    cell_group_factory.cpp
+    #cell_group_factory.cpp
     event_binner.cpp
     model.cpp
     morphology.cpp
@@ -25,13 +25,18 @@ set(CUDA_SOURCES
     memory/fill.cu
 )
 
+# The cell_group_factory acts like an interface between the
+# front end and back end.
+if(NMC_WITH_CUDA)
+    set(CUDA_SOURCES ${CUDA_SOURCES} cell_group_factory.cu)
+else()
+    set(BASE_SOURCES ${BASE_SOURCES} cell_group_factory.cpp)
+endif()
 
 if(NMC_WITH_MPI)
     set(BASE_SOURCES ${BASE_SOURCES} communication/mpi.cpp)
-
 elseif(NMC_WITH_DRYRUN)
     set(BASE_SOURCES ${BASE_SOURCES} communication/dryrun_global_policy.cpp)
-
 endif()
 
 if(NMC_WITH_CTHREAD)
@@ -39,14 +44,24 @@ if(NMC_WITH_CTHREAD)
 endif()
 
 add_library(nestmc ${BASE_SOURCES} ${HEADERS})
-
-if (NMC_AUTO_RUN_MODCC_ON_CHANGES)
-  add_dependencies(nestmc build_all_mods)
-endif()
+list(APPEND NESTMC_LIBRARIES nestmc)
 
 if(NMC_WITH_CUDA)
     cuda_add_library(gpu ${CUDA_SOURCES})
-    set(NESTMC_LIBRARIES ${NESTMC_LIBRARIES} gpu)
-    add_dependencies(gpu build_all_gpu_mods)
+    # FIXME
+    # The gpu library uses symbols fron nestmc, so we have to
+    # add nestmc to the end. This is a temporary hack that will
+    # go away when we have properly seperable front and back end
+    # compilation.
+    list(APPEND NESTMC_LIBRARIES gpu nestmc)
+endif()
+
+if (NMC_AUTO_RUN_MODCC_ON_CHANGES)
+    add_dependencies(nestmc build_all_mods)
+    if (NMC_WITH_CUDA)
+        add_dependencies(gpu build_all_gpu_mods)
+    endif()
 endif()
 
+# Make changes to the NMC_LIBRARIES visible to the parent scope.
+set(NESTMC_LIBRARIES "${NESTMC_LIBRARIES}" PARENT_SCOPE)
diff --git a/src/cell_group_factory.cu b/src/cell_group_factory.cu
new file mode 100644
index 00000000..21d20e7b
--- /dev/null
+++ b/src/cell_group_factory.cu
@@ -0,0 +1 @@
+#include "cell_group_factory.cpp"
diff --git a/tests/unit/CMakeLists.txt b/tests/unit/CMakeLists.txt
index 09935997..06899d2d 100644
--- a/tests/unit/CMakeLists.txt
+++ b/tests/unit/CMakeLists.txt
@@ -89,15 +89,13 @@ endif()
 target_include_directories(test.exe PRIVATE "${mech_proto_dir}/..")
 
 if(NMC_WITH_CUDA)
-    # Omit -DDATADIR for cuda target because of CMake 3.7/3.8 FindCUDA quoting bug.
-
     set(TARGETS ${TARGETS} test_cuda.exe)
     cuda_add_executable(test_cuda.exe ${TEST_CUDA_SOURCES} ${HEADERS})
-    target_link_libraries(test_cuda.exe LINK_PUBLIC gpu)
 endif()
 
 foreach(target ${TARGETS})
-    target_link_libraries(${target} LINK_PUBLIC gtest nestmc)
+    target_link_libraries(${target} LINK_PUBLIC gtest)
+    target_link_libraries(${target} LINK_PUBLIC ${NESTMC_LIBRARIES})
     target_link_libraries(${target} LINK_PUBLIC ${EXTERNAL_LIBRARIES})
 
     if(NMC_WITH_MPI)
diff --git a/tests/unit/test_matrix.cu b/tests/unit/test_matrix.cu
index dbf39f03..dac64cdf 100644
--- a/tests/unit/test_matrix.cu
+++ b/tests/unit/test_matrix.cu
@@ -1,4 +1,5 @@
 #include <numeric>
+#include <random>
 #include <vector>
 
 #include "../gtest.h"
diff --git a/tests/validation/CMakeLists.txt b/tests/validation/CMakeLists.txt
index 5523c3d2..288f7ded 100644
--- a/tests/validation/CMakeLists.txt
+++ b/tests/validation/CMakeLists.txt
@@ -48,8 +48,8 @@ endif()
 
 
 foreach(target ${TARGETS})
-    target_link_libraries(${target} LINK_PUBLIC nestmc gtest)
-
+    target_link_libraries(${target} LINK_PUBLIC gtest)
+    target_link_libraries(${target} LINK_PUBLIC ${NESTMC_LIBRARIES})
     target_link_libraries(${target} LINK_PUBLIC ${EXTERNAL_LIBRARIES})
 
     if(NMC_WITH_MPI)
-- 
GitLab