From 32e3ef4b63725dbe21a38ca66346666c1512f7ca Mon Sep 17 00:00:00 2001
From: Chris Maffeo <cmaffeo2@illinois.edu>
Date: Wed, 2 Nov 2022 12:16:39 -0500
Subject: [PATCH] Initial port to CMake build system

---
 README                         | 112 -----------------------------
 README.md                      | 110 +++++++++++++++++++++++++++++
 src/CMakeLists.txt             |  91 ++++++++++++++++++++++++
 src/Makefile                   | 124 ---------------------------------
 src/{imd.c => imd.cpp}         |   0
 src/{vmdsock.c => vmdsock.cpp} |   0
 version.cmake                  |  43 ++++++++++++
 7 files changed, 244 insertions(+), 236 deletions(-)
 delete mode 100644 README
 create mode 100644 README.md
 create mode 100644 src/CMakeLists.txt
 delete mode 100644 src/Makefile
 rename src/{imd.c => imd.cpp} (100%)
 rename src/{vmdsock.c => vmdsock.cpp} (100%)
 create mode 100644 version.cmake

diff --git a/README b/README
deleted file mode 100644
index aff911c..0000000
--- a/README
+++ /dev/null
@@ -1,112 +0,0 @@
-/==========================================================\
-| Atomic Resolution Brownian Dynamics (ARBD) - beta Oct 19 |
-\==========================================================/
-
-Brownian dynamics (BD) simulation is method for studying biomolecules, ions, and
-nanomaterials that balances detail with computational efficiency.
-
-ARBD supports tabulated non-bonded and bonded interactions between BD
-particles that can also be influenced by grid-specified
-potentials. Uniquely, ARBD also allows grid-specified densities and
-potentials to be associated with rigid body particles that rotate and
-translate to represent larger molecules. Most importantly, the code is
-designed to run quickly on modern NVIDIA GPUs.
-
-ARBD is a rewrite of the BrownianMover code, moving almost all computations to
-the GPU and enabling grid-specified particle models. Please be aware that ARBD
-is being actively developed and is offered without warranty.
-
-
-/==========\
-| Building |
-\==========/
-
-To build, please run `make' in the src directory.
-
-If your CUDA toolkit is installed in a nonstandard location, you may specify
-that location using the CUDA_PATH environment variable. For example:
-make CUDA_PATH=/nonstandard/path/to/cuda
-
-Note that ARBD has been developed using CUDA-8.0 and targets NVIDIA GPUs featuring
-6.0 compute capability. The code should work with devices with compute capability >=2.0,
-but there are no guarantees.
-
-Older versions of CUDA are not compatible with SM 6.0, so you may need to change
-the SMS variable in the makefile, or specify it as an argument to make.
-
-
-/==============\
-| Installation |
-\==============/
-
-Please explore the examples in the 'tests' directory.
-
-For example, try the following commands:
-
-cd tests/argon-small
-mkdir output
-../../src/arbd BrownDyn.bd output/BrownDyn > output/BrownDyn.log
-
-You may use the '-g n' option to specify the n-th GPU on your machine, counting from 0.
-
-If you fail to compile and link the applications, we recommend running
-`make clean` to remove object files. Sometimes we have encountered
-CUDA related errors in binaries built in a "dirty" environment.
-
-
-/========\
-| Citing |
-\========/
-
-If you publish results obtained using ARBD, please cite the following manuscripts:
-
-"DNA base-calling from a nanopore using a Viterbi algorithm"
-Winston Timp, Jeffrey Comer, and Aleksei Aksimentiev
-Biophys J 102(10) L37-9 (2012)
-
-"Predicting the DNA sequence dependence of nanopore ion current using atomic-resolution Brownian dynamics"
-Jeffrey Comer and Aleksei Aksimentiev.
-J Phys Chem C Nanomater Interfaces 116:3376-3393 (2012).
-
-"Atoms-to-microns model for small solute transport through sticky nanochannels"
-Rogan Carr, Jeffrey Comer, Mark D. Ginsberg, and Aleksei Aksimentiev
-Lab Chip 11(22) 3766-73 (2011)
-
-
-/=========\
-| Authors |
-\=========/
-
-ARBD is developed by the Aksimentiev group (http://bionano.physics.illinois.edu)
-as a part of the NIH Center for Macromolecular Modeling and Bioinformatics
-(http://www.ks.uiuc.edu/).
-
-Please direct questions or problems to Chris.
-
-Christopher Maffeo <cmaffeo2@illinois.edu>
-Han-yi Chao
-Jeffrey Comer
-Max Belkin
-Emmanual Guzman
-Justin Dufresne
-Terrance Howard
-
-
-/====================\
-| Outstanding issues |
-\====================/
-
--- Not implemented --
-
-* There are no checks to ensure that pairlists are recalculated before
-  particles further than the pairlist distance move to within the
-  cutoff
-
--- Bugs --
-
-* A large amount of GPU memory for pairlists is allocated statically,
-  which may cause out-of-memory crashes in older hardware
-
-* If the number of pairs in the system exceeds the length of the array
-  allocated for pairlists, the non-bonded kernel will try to access
-  forbidden regions of memory, causing a crash
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..258dd3f
--- /dev/null
+++ b/README.md
@@ -0,0 +1,110 @@
+# Atomic Resolution Brownian Dynamics (ARBD) - Nov 22
+
+Brownian dynamics (BD) simulation is method for studying biomolecules,
+ions, and nanomaterials that balances detail with computational
+efficiency.
+
+ARBD supports tabulated non-bonded and bonded interactions between BD
+particles that can also be influenced by grid-specified
+potentials. Uniquely, ARBD also allows grid-specified densities and
+potentials to be associated with rigid body particles that rotate and
+translate to represent larger molecules. Most importantly, the code is
+designed to run quickly on modern NVIDIA GPUs.
+
+ARBD is a rewrite of the BrownianMover code, moving almost all
+computations to the GPU and enabling grid-specified particle
+models. Please be aware that ARBD is being actively developed and is
+offered without warranty.
+
+
+## Building
+
+### Dependencies
+
+Only tested on Linux with:
+  - CMake >= 3.9
+  - gcc >= 4.9
+  - cuda >= 9.0
+
+### Build process
+
+From the root arbd directory (where this README is found), run:
+```
+cmake -S src -B build &&
+(
+  cd build
+  make -j
+)
+```
+
+If your CUDA toolkit is installed in a nonstandard location that CMake
+is unable to find, you may provide use the environement variable
+`CMAKE_CUDA_COMPILER` to specify the path to nvcc. You may also find
+it neccesary to set the environment variable `CUDA_INCLUDE_DIRS` if
+compilation fails due to the compiler being unable to find <cuda.h>.
+
+Note that ARBD has been developed using CUDA-9.0 and targets NVIDIA
+GPUs featuring 6.0 compute capability. The code should work with
+devices with compute capability >=2.0, but there are no guarantees.
+
+Older versions of CUDA are not compatible with SM 6.0, so you may need
+to change the SMS variable in the makefile, or specify it as an
+argument to make.
+
+
+## Usage
+
+Please explore the examples in the 'tests' directory.
+
+For example, try the following commands:
+
+cd tests/argon-small
+mkdir output
+../../src/arbd BrownDyn.bd output/BrownDyn > output/BrownDyn.log
+
+You may use the '-g n' option to specify the n-th GPU on your machine,
+counting from 0.
+
+## Citing
+
+If you publish results obtained using ARBD, please cite the
+following manuscripts:
+
+"DNA base-calling from a nanopore using a Viterbi algorithm"
+Winston Timp, Jeffrey Comer, and Aleksei Aksimentiev
+Biophys J 102(10) L37-9 (2012)
+
+"Predicting the DNA sequence dependence of nanopore ion current using atomic-resolution Brownian dynamics"
+Jeffrey Comer and Aleksei Aksimentiev.
+J Phys Chem C Nanomater Interfaces 116:3376-3393 (2012).
+
+"Atoms-to-microns model for small solute transport through sticky nanochannels"
+Rogan Carr, Jeffrey Comer, Mark D. Ginsberg, and Aleksei Aksimentiev
+Lab Chip 11(22) 3766-73 (2011)
+
+
+## Authors
+
+ARBD is developed by the Aksimentiev group
+(http://bionano.physics.illinois.edu) as a part of the NIH Center for
+Macromolecular Modeling and Bioinformatics (http://www.ks.uiuc.edu/).
+
+Please direct questions or problems to Chris.
+
+Christopher Maffeo <cmaffeo2@illinois.edu>
+Han-yi Chao
+Jeffrey Comer
+Max Belkin
+Emmanual Guzman
+Justin Dufresne
+Terrance Howard
+
+
+## Outstanding issues
+
+* There are no checks to ensure that pairlists are recalculated before
+  particles further than the pairlist distance move to within the
+  cutoff
+
+* A large amount of GPU memory for pairlists is allocated statically,
+  which may cause out-of-memory crashes in older hardware
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644
index 0000000..1ce15b0
--- /dev/null
+++ b/src/CMakeLists.txt
@@ -0,0 +1,91 @@
+cmake_minimum_required(VERSION 3.9 FATAL_ERROR)
+
+# option(USE_CUDA "Use CUDA" ON)
+set(USE_CUDA ON)
+
+if(USE_CUDA)
+# set the project name and version
+project(arbd VERSION 1.2 LANGUAGES CXX CUDA)
+else(USE_CUDA)
+project(arbd VERSION 1.2 LANGUAGES CXX)
+endif()
+
+# specify the C++ standard
+set(CMAKE_CXX_STANDARD 14)
+set(CMAKE_CXX_STANDARD_REQUIRED True)
+set(CMAKE_VERBOSE_MAKEFILE True)
+
+## OPTIONS
+option(USE_NCCL "Use NCCL for single node GPU peer communication" ON)
+
+# configure_file(TutorialConfig.h.in TutorialConfig.h)
+message(STATUS "USE_CUDA: ${USE_CUDA}")
+if(USE_CUDA)
+    add_definitions(-DUSE_CUDA)
+    ## CUDA_INCLUDE_DIRS wasn't getting set on my system with cmake 3.14.1, so check if in env
+    if(DEFINED ENV{CUDA_INCLUDE_DIRS})
+    set(CUDA_INCLUDE_DIRS $ENV{CUDA_INCLUDE_DIRS})
+    endif()    
+    message(STATUS "CUDA_INC: ${CUDA_INCLUDE_DIRS}")
+    include_directories(${CUDA_INCLUDE_DIRS})
+endif()
+
+## Two lines below needed?
+set(CMAKE_CUDA_SEPARABLE_COMPILATION ON)
+set(CMAKE_POSITION_INDEPENDENT_CODE ON)
+
+## Print all variables by uncommenting block below 
+# get_cmake_property(_variableNames VARIABLES)
+# list (SORT _variableNames)
+# foreach (_variableName ${_variableNames})
+#     message(STATUS "${_variableName}=${${_variableName}}")
+# endforeach()
+
+## Set rpath
+set(CMAKE_MACOSX_RPATH 1)	# Unsure if this works for CMAKE_BUIlD_RPATH, or just CMAKE_INSTALL_RPATH
+set(CMAKE_BUILD_RPATH "${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES}")
+
+add_executable(arbd arbd.cpp
+Configuration.cpp
+FlowForce.cpp
+GPUManager.cpp
+Scatter.cpp
+SignalManager.cpp
+WKFUtils.cpp
+Angle.cu
+BaseGrid.cu
+BrownianParticle.cu
+BrownianParticleType.cpp
+RigidBodyController.cu
+RigidBody.cu
+RigidBodyGrid.cu
+RigidBodyType.cu
+CellDecomposition.cu
+ComputeForce.cuh
+ComputeForce.cu
+ComputeGridGrid.cuh
+ComputeGridGrid.cu
+CudaUtil.cu
+CudaUtil.cuh
+Dihedral.cu
+Exclude.cu
+GrandBrownTown.cu
+GrandBrownTown.cuh
+imd.cpp
+vmdsock.cpp
+JamesBond.cu
+RandomCUDA.cu
+Reservoir.cu
+TabulatedAngle.cu
+TabulatedDihedral.cu
+TabulatedMethods.cuh
+TabulatedPotential.cu
+useful.cu
+)
+
+target_link_libraries(arbd PRIVATE curand)
+
+message(STATUS "Run: ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} ${MPIEXEC_MAX_NUMPROCS} ${MPIEXEC_PREFLAGS} EXECUTABLE ${MPIEXEC_POSTFLAGS} ARGS")
+## target_link_libraries(ARBD PUBLIC) MPI::MPI_CXX)
+
+install(TARGETS arbd)
diff --git a/src/Makefile b/src/Makefile
deleted file mode 100644
index 68598f4..0000000
--- a/src/Makefile
+++ /dev/null
@@ -1,124 +0,0 @@
-### Paths, libraries, includes, options
-include ./findcudalib.mk
-
-SUFFIX ?= ""
-
-ifeq ($(dbg),1)
-	NV_FLAGS += -g -G -O0
-	EX_FLAGS = -g -m$(OS_SIZE)
-else
-	NV_FLAGS = -Xptxas -O3
-	EX_FLAGS = -O3 -m$(OS_SIZE)
-endif
-
-ifeq ($(omp),1)
-	NV_FLAGS += -Xcompiler -fopenmp
-	CC_FLAGS += -fopenmp
-endif
-
-## Determine the version; TODO add tags for versions
-ifndef (VERSION)
-ifeq ($(shell git status >& /dev/null && echo true),true)
-	VERSION:=git rev. $(shell git rev-parse HEAD | sed 's/\(.\{8\}\).*/\1/')
-ifneq ($(shell git status --porcelain),)
-	VERSION:=$(VERSION) (modified)
-endif
-else 
-	VERSION:=unknown (not compiled in a git repository)
-endif
-endif
-
-CC_FLAGS += -DVERSION="\"$(VERSION)\"" -DSIGNAL
-CC_FLAGS += -I$(CUDA_PATH)/include
-CC_FLAGS += -Wall -Wno-write-strings -std=c++14 -pedantic# TODO: test on Mac OSX and other architectures
-
-ifeq ($(dbg),1)
-NV_FLAGS += -lineinfo
-else
-NV_FLAGS += -lineinfo
-endif
-
-CUDA_VERSION_GT10 = $(shell expr `nvcc -V | tr 'V' ' ' | tr ' ' '\n' | tail -n1 | cut -f1 -d.` \> 10)
-ifeq "$(CUDA_VERSION_GT10)" "1"
-  CSTD:=c++14
-else
-  CSTD:=c++11
-endif
-NV_FLAGS := $(NV_FLAGS) -std=$(CSTD)
-
-ifneq ($(DARWIN),)
-  CUDALIB = $(CUDA_PATH)/lib
-else
-  CUDALIB = $(CUDA_PATH)/lib64
-  ifeq "$(CSTD)" "c++11"
-    CSTD := c++1y
-  endif
-endif
-CC_FLAGS += -std=$(CSTD)
-# NV_FLAGS += -ftz=true			# TODO: test if this preserves accurate simulation
-
-## Find valid compute capabilities for this machine
-SMS ?= 30 35 37 50 52 60 61
-$(info Testing CUDA toolkit with compute capabilities SMS='$(SMS)')
-SMS := $(shell for sm in $(SMS); do $(NVCC) cuda-test.c -arch=sm_$$sm -o /dev/null &> /dev/null && echo $$sm; done)
-
-ifeq (,$(SMS))
-    $(error nvcc ($(NVCC)) failed with all tested compute capabilities.)
-endif
-
-SMPTXS ?= $(lastword $(sort $(SMS)))
-$(info Building SASS code for SMS='$(SMS)' and PTX code for '$(SMPTXS)')
-
-## Generate SASS and PTX code
-$(foreach SM,$(SMS), $(eval NV_FLAGS += -gencode arch=compute_$(SM),code=sm_$(SM)) )
-$(foreach SM,$(SMPTXS), $(eval NV_FLAGS += -gencode arch=compute_$(SM),code=compute_$(SM)) )
-
-NVLD_FLAGS := $(NV_FLAGS) --device-link 
-LD_FLAGS = -L$(CUDALIB) -lcurand -lcudart -lcudadevrt -Wl,-rpath,$(CUDALIB)
-
-ifdef NCCL_PATH
-	CC_FLAGS += -DUSE_NCCL
-	CC_FLAGS += -I$(NCCL_PATH)/include
-	NV_FLAGS += -I$(NCCL_PATH)/include
-	LD_FLAGS += -L$(NCCL_PATH)/lib -lnccl -Wl,-rpath,$(NCCL_PATH)/lib
-endif
-
-### Sources
-CC_SRC := $(wildcard *.cpp)
-CC_SRC := $(filter-out arbd.cpp, $(CC_SRC))
-CU_SRC := $(wildcard *.cu)
-
-CC_OBJ := $(patsubst %.cpp, %.o, $(CC_SRC))
-CU_OBJ := $(patsubst %.cu, %.o, $(CU_SRC))
-
-### Targets
-TARGET := arbd
-ifeq ($(dbg),1)
-TARGET := $(TARGET)_dbg
-endif
-ifeq ($(omp),1)
-TARGET := $(TARGET)_omp
-endif
-
-all: $(TARGET)$(SUFFIX)
-	@echo "Done ->" $(TARGET)$(SUFFIX)
-
-$(TARGET)_link.o: $(CU_OBJ)
-#	$(NVCC) $(NVLD_FLAGS) $(CU_OBJ) $(CC_OBJ) -o $(TARGET)_link.o
-	$(NVCC) $(NVLD_FLAGS) $(CU_OBJ) -o $(TARGET)_link.o
-
-$(TARGET)$(SUFFIX): $(TARGET)_link.o $(CU_OBJ) $(CC_OBJ) arbd.cpp vmdsock.c imd.c imd.h
-#	$(NVCC) $(NVLD_FLAGS) $(CU_OBJ) $(CC_OBJ) -o $(TARGET)_link.o
-#	$(NVCC) $(NVLD_FLAGS) $(CU_OBJ) -o $(TARGET)_link.o
-	$(CC) $(CC_FLAGS) $(EX_FLAGS) arbd.cpp vmdsock.c imd.c $(TARGET)_link.o $(CU_OBJ) $(CC_OBJ) $(LD_FLAGS)  -o $(TARGET)$(SUFFIX)
-
-
-.SECONDEXPANSION:
-$(CU_OBJ): %.o: %.cu $$(wildcard %.h) $$(wildcard %.cuh)
-	$(NVCC) $(NV_FLAGS) $(EX_FLAGS) -dc $< -o $@
-
-$(CC_OBJ): %.o: %.cpp %.h 
-	$(CC) $(CC_FLAGS) $(EX_FLAGS) -c $< -o $@
-
-clean:
-	rm -f $(TARGET) $(CU_OBJ) $(CC_OBJ)
diff --git a/src/imd.c b/src/imd.cpp
similarity index 100%
rename from src/imd.c
rename to src/imd.cpp
diff --git a/src/vmdsock.c b/src/vmdsock.cpp
similarity index 100%
rename from src/vmdsock.c
rename to src/vmdsock.cpp
diff --git a/version.cmake b/version.cmake
new file mode 100644
index 0000000..c366f35
--- /dev/null
+++ b/version.cmake
@@ -0,0 +1,43 @@
+execute_process(COMMAND git log --pretty=format:'%h' -n 1
+                OUTPUT_VARIABLE GIT_REV
+		                ERROR_QUIET)
+
+# Check whether we got any revision (which isn't
+# always the case, e.g. when someone downloaded a zip
+# file from Github instead of a checkout)
+if ("${GIT_REV}" STREQUAL "")
+    set(GIT_REV "N/A")
+        set(GIT_DIFF "")
+	    set(GIT_TAG "N/A")
+	        set(GIT_BRANCH "N/A")
+		else()
+		    execute_process(
+		            COMMAND bash -c "git diff --quiet --exit-code || echo +"
+			            OUTPUT_VARIABLE GIT_DIFF)
+				        execute_process(
+					        COMMAND git describe --exact-match --tags
+						        OUTPUT_VARIABLE GIT_TAG ERROR_QUIET)
+							    execute_process(
+							            COMMAND git rev-parse --abbrev-ref HEAD
+								            OUTPUT_VARIABLE GIT_BRANCH)
+
+    string(STRIP "${GIT_REV}" GIT_REV)
+        string(SUBSTRING "${GIT_REV}" 1 7 GIT_REV)
+	    string(STRIP "${GIT_DIFF}" GIT_DIFF)
+	        string(STRIP "${GIT_TAG}" GIT_TAG)
+		    string(STRIP "${GIT_BRANCH}" GIT_BRANCH)
+		    endif()
+
+set(VERSION "const char* GIT_REV=\"${GIT_REV}${GIT_DIFF}\";
+const char* GIT_TAG=\"${GIT_TAG}\";
+const char* GIT_BRANCH=\"${GIT_BRANCH}\";")
+
+if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/version.cpp)
+    file(READ ${CMAKE_CURRENT_SOURCE_DIR}/version.cpp VERSION_)
+    else()
+        set(VERSION_ "")
+	endif()
+
+if (NOT "${VERSION}" STREQUAL "${VERSION_}")
+    file(WRITE ${CMAKE_CURRENT_SOURCE_DIR}/version.cpp "${VERSION}")
+endif()
\ No newline at end of file
-- 
GitLab