Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PairG header-only library #1

Open
wants to merge 26 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
eb16654
Reduce the number of dependencies of PairG library
cartoonist Sep 3, 2020
d7a0baa
Move library header files to a separated directory
cartoonist Sep 3, 2020
caf217b
Use newer version of libvgio
cartoonist Oct 13, 2020
1504743
Use kokkos and kokkos-kernel develop branch
cartoonist Sep 3, 2020
19cfc2f
Adapt the new Kokkos API
cartoonist Oct 11, 2020
5d0060e
Fix some minor issues
cartoonist Oct 11, 2020
c4c6372
Update CMake source file
cartoonist Oct 11, 2020
5a60813
Suppress unused variable warnings
cartoonist Oct 16, 2020
4ea6984
Fix a minor issue avoiding an extra matrix multiplication
cartoonist Nov 12, 2020
6b54a02
Polish the CMake build script
cartoonist Apr 8, 2021
ae5b805
Add options for using and install bundled dependencies
cartoonist Apr 8, 2021
69f0148
Export and install pairg targets and configuration files
cartoonist Apr 8, 2021
db7d28a
Bump to version number v0.2.0
cartoonist Apr 8, 2021
f6bfa3f
Update Kokkos and Kokkos-kernels to v4.0.0
cartoonist Apr 11, 2023
f5f1602
Remove deprecated `random_shuffle`
cartoonist Apr 11, 2023
c50ef8c
Drop unnecessary template parameters
cartoonist Apr 12, 2023
3b68bef
Make functions inline
cartoonist Apr 15, 2023
4b48f02
Bump version number to v0.2.1
cartoonist May 1, 2023
e692d38
Add missing required package OpenMP
cartoonist Sep 10, 2023
5aa619f
Update Catch2 submodule
cartoonist Sep 10, 2023
436abb6
Make `matrixOps` generic
cartoonist Sep 10, 2023
e9e913c
Make all interface functions generic
cartoonist Sep 10, 2023
f6947c7
Fix references to template class `matrixOps`
cartoonist Sep 10, 2023
a8cef96
Add a fixture for all test scenarios using Kokkos
cartoonist Sep 10, 2023
72b212c
Update Kokkos and Kokkos-kernels to v4.1.00
cartoonist Dec 23, 2023
294277c
Update Kokkos and Kokkos-kernels to v4.2.00
cartoonist Feb 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
152 changes: 78 additions & 74 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,82 +1,86 @@
cmake_minimum_required(VERSION 3.1)
include(CheckCXXCompilerFlag)
cmake_minimum_required(VERSION 3.16)

# project settings
project(pairg)

##### General Compilation Settings
set(CMAKE_CXX_FLAGS "-w ${CMAKE_CXX_FLAGS} --std=c++11")

set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -O0")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O3 -g")

#Set default cmake build type to RelWithDebInfo during prototyping
IF(NOT CMAKE_BUILD_TYPE)
SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING
"Choose the type of build, options are: None Debug Release RelWithDebInfo"
FORCE)
ENDIF(NOT CMAKE_BUILD_TYPE)
# Project settings
project(pairg VERSION 0.2.1 LANGUAGES CXX)

## Options
# Check if the user wants to only build the library
option(BUILD_LIBRARY_ONLY "Inform whether only library should be built" OFF)
# Check if the user wants to build google test applications
OPTION(BUILD_TESTS "Inform whether test applications should be built" ON)
option(BUILD_TESTING "Inform whether test applications should be built" OFF)
# Check if the user wants to use bundled Kokkos library
option(USE_BUNDLED_KOKKOS "Use bundled Kokkos" OFF)
# Check if the user wants to use bundled KokkosKernels library
option(USE_BUNDLED_KOKKOS_KERNELS "Use bundled KokkosKernels" OFF)
# Check if the user wants to use all bundled dependencies
option(USE_BUNDLED_ALL "Use all bundled dependencies" OFF)

if(USE_BUNDLED_ALL)
set(USE_BUNDLED_KOKKOS on)
set(USE_BUNDLED_KOKKOS_KERNELS on)
endif(USE_BUNDLED_ALL)

# Include external modules
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)
# Adding CMake module path.
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/modules)
## Finding dependencies
find_package(OpenMP REQUIRED)
find_package(Kokkos QUIET)
find_package(KokkosKernels QUIET)
# Handle bundled dependencies
include(${PROJECT_SOURCE_DIR}/ext/external.cmake)

## Defining target library `libpairg`
# Defining the INTERFACE library
add_library(libpairg INTERFACE)
# Defining include directories
target_include_directories(libpairg
INTERFACE $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>;$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>)
# Defining link libraries
target_link_libraries(libpairg
INTERFACE $<BUILD_INTERFACE:Kokkos::kokkos>;$<INSTALL_INTERFACE:Kokkos::kokkos>
INTERFACE $<BUILD_INTERFACE:Kokkos::kokkoskernels>;$<INSTALL_INTERFACE:Kokkos::kokkoskernels>)
# Use C++14
target_compile_features(libpairg INTERFACE cxx_std_14)
# Setting header files
file(GLOB HEADER_FILES RELATIVE "${PROJECT_SOURCE_DIR}/include" "${PROJECT_SOURCE_DIR}/include/pairg/*.hpp")
list(TRANSFORM HEADER_FILES PREPEND "${PROJECT_SOURCE_DIR}/include/" OUTPUT_VARIABLE BUILD_HEADER_FILES)
list(TRANSFORM HEADER_FILES PREPEND "${CMAKE_INSTALL_FULL_INCLUDEDIR}/" OUTPUT_VARIABLE INSTALL_HEADER_FILES)
# Defining target sources
target_sources(libpairg
INTERFACE "$<BUILD_INTERFACE:${BUILD_HEADER_FILES}>;$<INSTALL_INTERFACE:${INSTALL_HEADER_FILES}>")
# Defining `pairg::libpairg` alias
add_library(pairg::libpairg ALIAS libpairg)
# Install targets
install(FILES ${BUILD_HEADER_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/pairg)
# Exporting targets
install(TARGETS libpairg EXPORT pairg-targets)
install(EXPORT pairg-targets NAMESPACE pairg:: DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/pairg)
# Creating the package configuration file
configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/pairg-config.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/pairg-config.cmake"
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/pairg)
# Generating the version file for the configuration file
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/pairg-config-version.cmake"
VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}"
COMPATIBILITY AnyNewerVersion)
# Install generated configuration files
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/pairg-config.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/pairg-config-version.cmake"
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/pairg)

# Save libs and executables in the same place
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib CACHE PATH "Output directory for libraries" )

include_directories("${PROJECT_SOURCE_DIR}/ext")
include_directories("${PROJECT_SOURCE_DIR}/src/include")

#### kokkos stuff
include_directories("${PROJECT_SOURCE_DIR}/ext/kokkos-kernels/src")
include_directories("${PROJECT_SOURCE_DIR}/ext/kokkos-kernels/src/impl")
include_directories("${PROJECT_SOURCE_DIR}/ext/kokkos-kernels/src/impl/tpls")
include_directories("${PROJECT_SOURCE_DIR}/ext/kokkos-kernels/src/common")
include_directories("${PROJECT_SOURCE_DIR}/ext/kokkos-kernels/src/graph")
include_directories("${PROJECT_SOURCE_DIR}/ext/kokkos-kernels/src/graph/impl")
include_directories("${PROJECT_SOURCE_DIR}/ext/kokkos-kernels/src/sparse")
include_directories("${PROJECT_SOURCE_DIR}/ext/kokkos-kernels/src/sparse/impl")

add_subdirectory("${PROJECT_SOURCE_DIR}/ext/kokkos" ${PROJECT_BINARY_DIR}/kokkos)
include_directories(${Kokkos_INCLUDE_DIRS_RET})

file(WRITE "${PROJECT_BINARY_DIR}/KokkosKernels_config.h" "//dummy file for kokkos-kernels to include")
include_directories("${PROJECT_BINARY_DIR}")

### Include and compile htslib
include_directories("${PROJECT_SOURCE_DIR}/ext/htslib")
# Advice: in case htslib is missing some core libraries, install them
add_custom_target(LIBHTS COMMAND make WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}/ext/htslib" COMMENT "Compiling htslib")
set(HTS_LIBRARY "${PROJECT_SOURCE_DIR}/ext/htslib/libhts.so")


### Protobuf stuff
#NOTE: user is expected to set the following variable PROTOBUF_DIR
set(PROTOBUF_DIR CACHE STRING "absolute path to protobuf installation directory")
set(PROTOBUF_INCLUDE_DIR "${PROTOBUF_DIR}/include")
set(PROTOBUF_LIBRARY "${PROTOBUF_DIR}/lib/libprotobuf.so")
set(PROTOBUF_PROTOC_EXECUTABLE "${PROTOBUF_DIR}/bin/protoc")
if(EXISTS "${PROTOBUF_INCLUDE_DIR}" AND EXISTS "${PROTOBUF_LIBRARY}" AND EXISTS "${PROTOBUF_PROTOC_EXECUTABLE}")
message(STATUS "Protobuf libraries, header files and executables located")
else()
message(FATAL_ERROR "Protobuf path is invalid, cannot find required libraries, header files or executables. Set the cmake variable PROTOBUF_DIR properly.")
endif()
find_package(Protobuf REQUIRED)
include_directories(${PROTOBUF_INCLUDE_DIR})

### Include libvgio
PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HDRS "${PROJECT_SOURCE_DIR}/ext/libvgio/deps/vg.proto")
add_custom_target(SYMLNK COMMAND ${CMAKE_COMMAND} -E create_symlink . vg WORKING_DIRECTORY "${PROJECT_BINARY_DIR}" COMMENT "Adding symbolic link vg")
include_directories("${PROJECT_SOURCE_DIR}/ext/libvgio/include")
file(GLOB VGIO_SRC "${PROJECT_SOURCE_DIR}/ext/libvgio/src/*.cpp")
add_library(LIBVGIO ${PROTO_SRCS} ${VGIO_SRC})
add_dependencies(LIBVGIO SYMLNK)


###generate test executables if requested
add_subdirectory("${PROJECT_SOURCE_DIR}/tests")
# Build PairG command-line tool
if(NOT BUILD_LIBRARY_ONLY)
add_subdirectory("${PROJECT_SOURCE_DIR}/src")
endif(NOT BUILD_LIBRARY_ONLY)

###generate main executable
add_executable(pairg "${PROJECT_SOURCE_DIR}/src/main.cpp")
add_dependencies(pairg LIBHTS SYMLNK)
target_link_libraries(pairg kokkos ${PROTOBUF_LIBRARY} LIBVGIO ${HTS_LIBRARY})
# Generate test executables if requested
if(BUILD_TESTING)
add_subdirectory("${PROJECT_SOURCE_DIR}/tests")
endif(BUILD_TESTING)
37 changes: 37 additions & 0 deletions cmake/modules/FindHTSlib.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Find 'HTSlib' library.
#
# This set the following variables:
# - HTSlib_FOUND
# - HTSlib_VERSION
# - HTSlib_INCLUDEDIR
# - HTSlib_LIBRARIES
#
# and the following imported targets:
# - HTSlib::HTSlib

if(HTSlib_INCLUDEDIR)
set(HTSlib_FIND_QUIETLY TRUE)
else()
# Try pkg-config, first.
find_package(PkgConfig QUIET)
pkg_check_modules(HTSlib QUIET htslib)
# If HTSlib_INCLUDEDIR is not set, this searches for the header file.
find_path(HTSlib_INCLUDEDIR htslib/hts.h)
find_library(HTSlib_LIBRARIES hts)
endif(HTSlib_INCLUDEDIR)

## handle the QUIETLY and REQUIRED arguments and set HTSlib_FOUND to TRUE if
## all listed variables are TRUE
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(HTSlib DEFAULT_MSG HTSlib_INCLUDEDIR HTSlib_LIBRARIES)

mark_as_advanced(HTSlib_FOUND HTSlib_VERSION HTSlib_INCLUDEDIR HTSlib_LIBRARIES)

# Define `HTSlib::HTSlib` imported target
if(HTSlib_FOUND AND NOT TARGET HTSlib::HTSlib)
add_library(HTSlib::HTSlib INTERFACE IMPORTED)
set_target_properties(HTSlib::HTSlib PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${HTSlib_INCLUDEDIR}"
INTERFACE_LINK_LIBRARIES "${HTSlib_LIBRARIES}"
INTERFACE_LINK_DIRECTORIES "${HTSlib_LIBDIR}")
endif()
14 changes: 14 additions & 0 deletions cmake/pairg-config.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
@PACKAGE_INIT@

include(CMakeFindDependencyMacro)
find_dependency(Kokkos REQUIRED)
find_dependency(KokkosKernels REQUIRED)

if(NOT TARGET pairg::libpairg)
include("${CMAKE_CURRENT_LIST_DIR}/pairg-targets.cmake")
endif()

check_required_components(pairg)

include("${CMAKE_CURRENT_LIST_DIR}/pairg-config-version.cmake")
message(STATUS "Found PairG (version ${PACKAGE_VERSION})")
2 changes: 1 addition & 1 deletion ext/catch
Submodule catch updated 252 files
27 changes: 27 additions & 0 deletions ext/external.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
if(NOT TARGET Kokkos::kokkos)
if(NOT USE_BUNDLED_KOKKOS)
message(FATAL_ERROR "Kokkos library not found. "
"Pass in `-DUSE_BUNDLED_KOKKOS=on` when running cmake to use the bundled version. "
"It will be installed alongside the library.")
endif()
message(STATUS "Using bundled Kokkos library")
set(Kokkos_SOURCE_DIR ${PROJECT_SOURCE_DIR}/ext/kokkos)
execute_process(
COMMAND git submodule update --init --recursive -- ${Kokkos_SOURCE_DIR}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
add_subdirectory(${Kokkos_SOURCE_DIR})
endif()

if(NOT TARGET Kokkos::kokkoskernels)
if(NOT USE_BUNDLED_KOKKOS_KERNELS)
message(FATAL_ERROR "KokkosKernels library not found. "
"Pass in `-DUSE_BUNDLED_KOKKOS_KERNELS=on` when running cmake to use the bundled "
"version. It will be installed alongside the library.")
endif()
message(STATUS "Using bundled kokkos-kernels library")
set(KokkosKernels_SOURCE_DIR ${PROJECT_SOURCE_DIR}/ext/kokkos-kernels)
execute_process(
COMMAND git submodule update --init --recursive -- ${KokkosKernels_SOURCE_DIR}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
add_subdirectory(${KokkosKernels_SOURCE_DIR})
endif()
2 changes: 1 addition & 1 deletion ext/kokkos
Submodule kokkos updated 3024 files
2 changes: 1 addition & 1 deletion ext/kokkos-kernels
Submodule kokkos-kernels updated 6747 files
17 changes: 11 additions & 6 deletions src/include/heuristics.hpp → include/pairg/heuristics.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,33 @@
#ifndef PAIRG_HEURISTICS_HPP
#define PAIRG_HEURISTICS_HPP

#include <list>

#include "spgemm_utility.hpp"

namespace pairg
{
/**
* @brief implement a simple heuristic to check distance constraints
* @param[in] A adjacency matrix (CSR formatted)
* @param[in] p input parameters (pull distance constraints from here)
* @param[in] d_up distance constraint: upper bound on path length
* @param[in] src source vertex
* @param[in] target target vertex
* @details run BFS from source vertex up to d_2 levels and see if we reach
* the target vertex
* @return boolean value (true if reached, false if not)
*/
bool queryReachabilityBFS(const matrixOps::crsMat_t &A, const Parameters &p, matrixOps::lno_t src, matrixOps::lno_t target)
template< typename TMatrixOps=matrixOps<> >
inline bool queryReachabilityBFS(const typename TMatrixOps::crsMat_t &A,
int d_up, typename TMatrixOps::lno_t src,
typename TMatrixOps::lno_t target)
{
if (src >= A.numRows() || target >= A.numCols()) {
std::cout << "WARNING, pairg::matrixOps::queryValue, query index out of range" << std::endl;
return false;
}

assert(p.d_up > 0);
assert(d_up > 0);

if (src == target)
return true;
Expand All @@ -36,17 +41,17 @@ namespace pairg
int level = 0;

//dummy value to track BFS levels
matrixOps::lno_t dummy = std::numeric_limits<matrixOps::lno_t>::max();
typename TMatrixOps::lno_t dummy = std::numeric_limits<typename TMatrixOps::lno_t>::max();

//Mark all the vertices as not visited
std::vector<bool> visited(A.numRows(), false);

//queue for putting visited vertices
std::list<matrixOps::lno_t> Q;
std::list<typename TMatrixOps::lno_t> Q;
Q.push_back(src); visited[src] = true;
Q.push_back(dummy); //to travel the levels

while(!Q.empty() && level <= p.d_up)
while(!Q.empty() && level <= d_up)
{
//pick vertex from queue
auto cur = Q.front();
Expand Down
78 changes: 78 additions & 0 deletions include/pairg/reachability.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/**
* @file reachability.hpp
* @author Chirag Jain <[email protected]>
*/

#ifndef PAIRG_REACHABILITY_HPP
#define PAIRG_REACHABILITY_HPP

#include "spgemm_utility.hpp"

namespace pairg
{
/**
* @brief build adjacency matrix from variaton graph
*/
template< class TCharGraph, typename TMatrixOps=matrixOps<> >
inline typename TMatrixOps::crsMat_t getAdjacencyMatrix(const TCharGraph &cg)
{
typename TMatrixOps::lno_t nrows = cg.numVertices;
typename TMatrixOps::size_type nnz = cg.numEdges;

typename TMatrixOps::lno_nnz_view_t entries("entries", nnz);
typename TMatrixOps::scalar_view_t values("values", nnz);
typename TMatrixOps::lno_view_t rowmap("rowmap", nrows + 1);

for(typename TMatrixOps::size_type i = 0; i < nnz; i++) {
values(i) = 1; //boolean
}

for(typename TMatrixOps::size_type i = 0; i < nnz; i++) {
entries(i) = cg.adjcny_out[i];
}

for(typename TMatrixOps::lno_t i = 0; i < nrows + 1; i++) {
rowmap(i) = cg.offsets_out[i];
}

return typename TMatrixOps::crsMat_t("adjacency matrix", nrows, nrows, nnz, values, rowmap, entries);
}

/**
* @brief build matrix associated with valid vertices that satisfy
* distance constraints
* @param[in] A graph adjacency matrix
* @param[in] d_low distance constraint: lower bound on path length
* @param[in] d_up distance constraint: upper bound on path length
* @return validity matrix
* cell (i,j) = 1 iff there is a valid path from v_i to v_j
*/
template< typename TMatrixOps=matrixOps<> >
inline typename TMatrixOps::crsMat_t buildValidPairsMatrix(const typename TMatrixOps::crsMat_t &A, int d_low, int d_up)
{
pairg::timer T1;
typename TMatrixOps::crsMat_t B = TMatrixOps::addMatrices(A, TMatrixOps::createIdentityMatrix(A.numRows()));
std::cout << "INFO, pairg::buildValidPairsMatrix, time to add identity matrix (ms): " << T1.elapsed() << "\n";

pairg::timer T2;
typename TMatrixOps::crsMat_t C = TMatrixOps::power(A, d_low);
std::cout << "INFO, pairg::buildValidPairsMatrix, time to raise adjacency matrix (ms): " << T2.elapsed() << "\n";

pairg::timer T3;
typename TMatrixOps::crsMat_t D = TMatrixOps::power (B, d_up - d_low);
std::cout << "INFO, pairg::buildValidPairsMatrix, time to raise adjacency+identity matrix (ms): " << T3.elapsed() << "\n";

pairg::timer T4;
typename TMatrixOps::crsMat_t E = TMatrixOps::multiplyMatrices(C,D);
std::cout << "INFO, pairg::buildValidPairsMatrix, time to execute final multiplication (ms): " << T4.elapsed() << "\n";

//sort entries within each row
pairg::timer T5;
TMatrixOps::indexForQuery(E);
std::cout << "INFO, pairg::buildValidPairsMatrix, time to index for querying (ms): " << T5.elapsed() << "\n";

return E;
}
}

#endif
Loading