cmake_minimum_required(VERSION 3.15)
project(graph500 LANGUAGES C)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
include(GNUInstallDirs)

SET(GRAPH500_SOURCES
	"${CMAKE_CURRENT_SOURCE_DIR}/options.c"
	"${CMAKE_CURRENT_SOURCE_DIR}/rmat.c"
	"${CMAKE_CURRENT_SOURCE_DIR}/kronecker.c"
	"${CMAKE_CURRENT_SOURCE_DIR}/verify.c"
	"${CMAKE_CURRENT_SOURCE_DIR}/prng.c"
	"${CMAKE_CURRENT_SOURCE_DIR}/xalloc.c"
	"${CMAKE_CURRENT_SOURCE_DIR}/timer.c"
)
ADD_LIBRARY(GRAPH500_OBJECTS OBJECT ${GRAPH500_SOURCES})
target_include_directories(GRAPH500_OBJECTS PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}")

SET(GENERATOR_SRC
	"${CMAKE_CURRENT_SOURCE_DIR}/generator/btrd_binomial_distribution.c"
	"${CMAKE_CURRENT_SOURCE_DIR}/generator/splittable_mrg.c"
	"${CMAKE_CURRENT_SOURCE_DIR}/generator/mrg_transitions.c"
	"${CMAKE_CURRENT_SOURCE_DIR}/generator/graph_generator.c"
	"${CMAKE_CURRENT_SOURCE_DIR}/generator/permutation_gen.c"
	"${CMAKE_CURRENT_SOURCE_DIR}/generator/make_graph.c"
	"${CMAKE_CURRENT_SOURCE_DIR}/generator/utils.c"
	"${CMAKE_CURRENT_SOURCE_DIR}/generator/scramble_edges.c"
)

ADD_LIBRARY(generator-seq SHARED ${GENERATOR_SRC} $<TARGET_OBJECTS:GRAPH500_OBJECTS>)
target_compile_definitions(generator-seq PUBLIC GRAPH_GENERATOR_SEQ)
target_include_directories(generator-seq PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/generator")
target_link_libraries(generator-seq PUBLIC -liberty)
install(TARGETS generator-seq LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}")

if(BUILD_OPENMP)
	find_package(OpenMP REQUIRED)

	ADD_LIBRARY(generator-omp SHARED ${GENERATOR_SRC} $<TARGET_OBJECTS:GRAPH500_OBJECTS>)
	set_target_properties(generator-omp PROPERTIES COMPILE_FLAGS "-fopenmp")
	target_compile_definitions(generator-omp PUBLIC GRAPH_GENERATOR_OMP)
	target_include_directories(generator-omp PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/generator")
	target_link_libraries(generator-omp PUBLIC OpenMP::OpenMP_C -liberty)
	install(TARGETS generator-omp LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}")

	ADD_EXECUTABLE(omp-csr
		"${CMAKE_CURRENT_SOURCE_DIR}/omp-csr/omp-csr.c"
		"${CMAKE_CURRENT_SOURCE_DIR}/graph500.c"
	)
	target_link_libraries(omp-csr generator-omp -lm)
	install(TARGETS omp-csr RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")

	ADD_EXECUTABLE(generator_test_omp "${CMAKE_CURRENT_SOURCE_DIR}/generator/generator_test_omp.c")
	target_link_libraries(generator_test_omp generator-omp -lm)
	install(TARGETS generator_test_omp RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
endif()

ADD_EXECUTABLE(seq-list
	"${CMAKE_CURRENT_SOURCE_DIR}/seq-list/seq-list.c"
	"${CMAKE_CURRENT_SOURCE_DIR}/graph500.c"
)
target_link_libraries(seq-list generator-seq -lm)
install(TARGETS seq-list RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")

ADD_EXECUTABLE(seq-csr
	"${CMAKE_CURRENT_SOURCE_DIR}/seq-csr/seq-csr.c"
	"${CMAKE_CURRENT_SOURCE_DIR}/graph500.c"
)
target_link_libraries(seq-csr generator-seq -lm)
install(TARGETS seq-csr RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")

ADD_EXECUTABLE(generator_test_seq "${CMAKE_CURRENT_SOURCE_DIR}/generator/generator_test_seq.c")
target_link_libraries(generator_test_seq generator-seq -lm)
install(TARGETS generator_test_seq RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")

if(BUILD_MPI)
	find_package(MPI REQUIRED)

	ADD_LIBRARY(graph_generator_mpi SHARED
		"${CMAKE_CURRENT_SOURCE_DIR}/generator/apply_permutation_mpi.c"
		${GENERATOR_SRC}
	)
	target_compile_definitions(graph_generator_mpi PUBLIC restrict=__restrict__ GRAPH_GENERATOR_MPI GRAPHGEN_DISTRIBUTED_MEMORY)
	target_include_directories(graph_generator_mpi
		PUBLIC
		"${CMAKE_CURRENT_SOURCE_DIR}/generator"
		PRIVATE
		${MPI_INCLUDE_PATH}
	)
	target_link_libraries(graph_generator_mpi PUBLIC ${MPI_LIBRARIES} ${MPI_LINK_FLAGS} -liberty)
	install(TARGETS graph_generator_mpi LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}")

	ADD_EXECUTABLE(generator_test_mpi "${CMAKE_CURRENT_SOURCE_DIR}/generator/generator_test_mpi.c")
	target_compile_definitions(graph_generator_mpi PUBLIC restrict=__restrict__ GRAPH_GENERATOR_MPI GRAPHGEN_DISTRIBUTED_MEMORY)
	target_include_directories(generator_test_mpi
		PUBLIC
		"${CMAKE_CURRENT_SOURCE_DIR}/generator"
		PRIVATE
		${MPI_INCLUDE_PATH}
	)
	target_link_libraries(generator_test_mpi graph_generator_mpi ${MPI_LIBRARIES} ${MPI_LINK_FLAGS} -lm)
	install(TARGETS generator_test_mpi RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")

	SET(graph500_mpi_src
		"${CMAKE_CURRENT_SOURCE_DIR}/mpi/convert_to_csr.c"
		"${CMAKE_CURRENT_SOURCE_DIR}/mpi/find_roots.c"
		"${CMAKE_CURRENT_SOURCE_DIR}/mpi/utils.c"
		"${CMAKE_CURRENT_SOURCE_DIR}/mpi/validate.c"
	)
	ADD_LIBRARY(graph500_mpi_obj OBJECT ${graph500_mpi_src})
	target_include_directories(graph500_mpi_obj PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/mpi")
	target_compile_definitions(graph500_mpi_obj PUBLIC restrict=__restrict__ GRAPH_GENERATOR_MPI GRAPHGEN_DISTRIBUTED_MEMORY)
	ADD_LIBRARY(graph500_mpi SHARED $<TARGET_OBJECTS:graph500_mpi_obj>)
	install(TARGETS graph500_mpi LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}")

	ADD_EXECUTABLE(graph500_mpi_simple
		"${CMAKE_CURRENT_SOURCE_DIR}/mpi/main.c"
		"${CMAKE_CURRENT_SOURCE_DIR}/mpi/bfs_simple.c"
	)
	target_compile_definitions(graph500_mpi_simple PUBLIC restrict=__restrict__ GRAPH_GENERATOR_MPI GRAPHGEN_DISTRIBUTED_MEMORY)
	target_link_libraries(graph500_mpi_simple graph500_mpi graph_generator_mpi -lm)
	install(TARGETS graph500_mpi_simple RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")

	ADD_EXECUTABLE(graph500_mpi_one_sided
		"${CMAKE_CURRENT_SOURCE_DIR}/mpi/main.c"
		"${CMAKE_CURRENT_SOURCE_DIR}/mpi/bfs_one_sided.c"
	)
	target_compile_definitions(graph500_mpi_simple PUBLIC restrict=__restrict__ GRAPH_GENERATOR_MPI GRAPHGEN_DISTRIBUTED_MEMORY)
	target_link_libraries(graph500_mpi_one_sided graph500_mpi graph_generator_mpi -lm)
	install(TARGETS graph500_mpi_one_sided RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
endif()


install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/graph500" FILES_MATCHING PATTERN "*.h")
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/mpi/" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/graph500/mpi" FILES_MATCHING PATTERN "*.h")
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/generator/" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/graph500/generator" FILES_MATCHING PATTERN "*.h")
