Skip to content

Commit

Permalink
Merge 3c0c57b into cce5e88
Browse files Browse the repository at this point in the history
  • Loading branch information
cyrush committed Jul 27, 2021
2 parents cce5e88 + 3c0c57b commit 893baed
Show file tree
Hide file tree
Showing 6 changed files with 303 additions and 1 deletion.
11 changes: 11 additions & 0 deletions src/cmake/Setup3rdParty.cmake
Expand Up @@ -151,4 +151,15 @@ if(H5ZZFP_DIR)
endif()
endif()

################################
# Setup Parmetis if available
################################
if(PARMETIS_DIR)
include(cmake/thirdparty/SetupParmetis.cmake)
include_directories(${PARMETIS_INCLUDE_DIR})
# if we don't find it, throw a fatal error
if(NOT PARMETIS_FOUND)
message(FATAL_ERROR "PARMETIS_DIR is set, but parmetis wasn't found.")
endif()
endif()

73 changes: 73 additions & 0 deletions src/cmake/thirdparty/SetupParmetis.cmake
@@ -0,0 +1,73 @@
# Copyright (c) Lawrence Livermore National Security, LLC and other Conduit
# Project developers. See top-level LICENSE AND COPYRIGHT files for dates and
# other details. No copyright assignment is required to contribute to Conduit.
#
# Setup ParMeTiS
# This file defines:
# PARMETIS_DIRFOUND - If ParMeTiS was found
# PARMETIS_DIR_INCLUDE_DIRS - The ParMeTiS include directories
# PARMETIS_DIR_LIBRARIES - The libraries needed to use ParMeTiS


# first Check for PARMETIS_DIR

if(NOT METIS_DIR)
MESSAGE(FATAL_ERROR "Parmetis support needs explicit METIS_DIR")
endif()

if(NOT PARMETIS_DIR)
MESSAGE(FATAL_ERROR "Parmetis support needs explicit PARMETIS_DIR")
endif()

find_path(METIS_INCLUDE_DIR metis.h
PATHS ${METIS_DIR}/include
NO_DEFAULT_PATH
NO_CMAKE_ENVIRONMENT_PATH
NO_CMAKE_PATH
NO_SYSTEM_ENVIRONMENT_PATH
NO_CMAKE_SYSTEM_PATH)

find_library(METIS_LIB NAMES metis
PATHS ${METIS_DIR}/lib
NO_DEFAULT_PATH
NO_CMAKE_ENVIRONMENT_PATH
NO_CMAKE_PATH
NO_SYSTEM_ENVIRONMENT_PATH
NO_CMAKE_SYSTEM_PATH)


find_path(PARMETIS_INCLUDE_DIR parmetis.h
PATHS ${PARMETIS_DIR}/include
NO_DEFAULT_PATH
NO_CMAKE_ENVIRONMENT_PATH
NO_CMAKE_PATH
NO_SYSTEM_ENVIRONMENT_PATH
NO_CMAKE_SYSTEM_PATH)


find_library(PARMETIS_LIB NAMES parmetis
PATHS ${PARMETIS_DIR}/lib
NO_DEFAULT_PATH
NO_CMAKE_ENVIRONMENT_PATH
NO_CMAKE_PATH
NO_SYSTEM_ENVIRONMENT_PATH
NO_CMAKE_SYSTEM_PATH)

set(PARMETIS_LIBRARIES ${PARMETIS_LIB} ${METIS_LIB})
set(PARMETIS_INCLUDE_DIRS ${PARMETIS_INCLUDE_DIR} ${METIS_INCLUDE_DIR})


include(FindPackageHandleStandardArgs)
# handle the QUIETLY and REQUIRED arguments and set PARMETIS_FOUND to TRUE
# if all listed variables are TRUE
find_package_handle_standard_args(Parmetis DEFAULT_MSG
PARMETIS_LIBRARIES PARMETIS_INCLUDE_DIRS)

mark_as_advanced(PARMETIS_INCLUDE_DIR
PARMETIS_LIB)


blt_register_library(NAME parmetis
INCLUDES ${PARMETIS_INCLUDE_DIRS}
LIBRARIES ${PARMETIS_LIBRARIES} )

1 change: 1 addition & 0 deletions src/config/ConduitConfig.cmake.in
Expand Up @@ -34,6 +34,7 @@ if(NOT CONDUIT_FOUND)
set(CONDUIT_HDF5_DIR "@HDF5_DIR@")
set(CONDUIT_ADIOS_DIR "@ADIOS_DIR@")
set(CONDUIT_SILO_DIR "@SILO_DIR@")
set(CONDUIT_PARMETIS_DIR "@PARMETIS_DIR@")
set(CONDUIT_PYTHON_ENABLED "@PYTHON_FOUND@")
set(CONDUIT_PYTHON_EXECUTABLE "@PYTHON_EXECUTABLE@")
set(CONDUIT_PYTHON_MODULE_DIR "@CONDUIT_INSTALL_PYTHON_MODULE_DIR@")
Expand Down
14 changes: 13 additions & 1 deletion src/config/conduit_config.mk.in
Expand Up @@ -28,6 +28,8 @@ CONDUIT_SILO_DIR = @SILO_DIR@
CONDUIT_ADIOS_DIR = @ADIOS_DIR@
CONDUIT_ZFP_DIR = @ZFP_DIR@

CONDUIT_PARMETIS_DIR = @PARMETIS_DIR@

# hdf5 info, including tpls
CONDUIT_HDF5_DIR = @HDF5_DIR@
CONDUIT_HDF5_EXTRA_INCLUDE_FLAGS = @CONDUIT_HDF5_TPL_INC_FLAGS@
Expand All @@ -41,11 +43,14 @@ CONDUIT_SILO_RPATH_FLAGS_VALUE = -Wl,-rpath,$(CONDUIT_SILO_DIR)/lib
CONDUIT_HDF5_RPATH_FLAGS_VALUE = -Wl,-rpath,$(CONDUIT_HDF5_DIR)/lib
CONDUIT_ADIOS_RPATH_FLAGS_VALUE = -Wl,-rpath,$(CONDUIT_ADIOS_DIR)/lib
CONDUIT_ZFP_RPATH_FLAGS_VALUE = -Wl,-rpath,$(CONDUIT_ZFP_DIR)/lib
CONDUIT_PARMETIS_RPATH_FLAGS_VALUE = -Wl,-rpath,$(CONDUIT_PARMETIS_DIR)/lib

CONDUIT_LINK_RPATH += $(if $(CONDUIT_SILO_DIR), $(CONDUIT_SILO_RPATH_FLAGS_VALUE))
CONDUIT_LINK_RPATH += $(if $(CONDUIT_HDF5_DIR), $(CONDUIT_HDF5_RPATH_FLAGS_VALUE))
CONDUIT_LINK_RPATH += $(if $(CONDUIT_ADIOS_DIR), $(CONDUIT_ADIOS_RPATH_FLAGS_VALUE))
CONDUIT_LINK_RPATH += $(if $(CONDUIT_ZFP_DIR), $(CONDUIT_ZFP_RPATH_FLAGS_VALUE))
CONDUIT_LINK_RPATH += $(if $(CONDUIT_PARMETIS_DIR), $(CONDUIT_PARMETIS_RPATH_FLAGS_VALUE))



#################
Expand All @@ -63,6 +68,8 @@ CONDUIT_INCLUDE_FLAGS += $(if $(CONDUIT_HDF5_DIR),$(CONDUIT_HDF5_EXTRA_INCLUDE_F

CONDUIT_INCLUDE_FLAGS += $(if $(CONDUIT_ZFP_DIR),-I$(CONDUIT_ZFP_DIR)/include)

# Note: parmetis headers are not exposed in our api

#################
# Linking Flags
#################
Expand Down Expand Up @@ -91,6 +98,11 @@ CONDUIT_HDF5_LIB_FLAGS += $(if $(CONDUIT_HDF5_DIR),$(CONDUIT_HDF5_EXTRA_LIB_FLAG
##########
CONDUIT_ZFP_LIB_FLAGS = $(if $(CONDUIT_ZFP_DIR),-L $(CONDUIT_ZFP_DIR)/lib -lzfp)

##########
# PARMETIS
##########
CONDUIT_PARMETIS_LIB_FLAGS = $(if $(CONDUIT_PARMETIS_DIR),-L $(CONDUIT_PARMETIS_DIR)/lib -lparmetis)


##########
# Conduit
Expand All @@ -108,5 +120,5 @@ CONDUIT_MPI_LIB_FLAGS = -L $(CONDUIT_DIR)/lib \
-lconduit_blueprint_mpi \
-lconduit_blueprint \
-lconduit_relay \
-lconduit $(CONDUIT_ADIOS_MPI_LIB_FLAGS) $(CONDUIT_SILO_LIB_FLAGS) $(CONDUIT_HDF5_LIB_FLAGS) $(CONDUIT_ZFP_LIB_FLAGS) $(CONDUIT_EXTRA_LIB_FLAGS)
-lconduit $(CONDUIT_ADIOS_MPI_LIB_FLAGS) $(CONDUIT_SILO_LIB_FLAGS) $(CONDUIT_HDF5_LIB_FLAGS) $(CONDUIT_ZFP_LIB_FLAGS) $(CONDUIT_PARMETIS_LIB_FLAGS) $(CONDUIT_EXTRA_LIB_FLAGS)

11 changes: 11 additions & 0 deletions src/tests/thirdparty/CMakeLists.txt
Expand Up @@ -126,3 +126,14 @@ else()
message(STATUS "h5z-zfp disabled: Skipping related tests")
endif()


if(PARMETIS_FOUND)
message(STATUS "Parmetis enabled: Adding related unit tests")
add_cpp_mpi_test(TEST t_parmetis_smoke
NUM_MPI_TASKS 2
DEPENDS_ON parmetis
FOLDER tests/thirdparty)
else()
message(STATUS "Parmetis disabled: Skipping related tests")
endif()

194 changes: 194 additions & 0 deletions src/tests/thirdparty/t_parmetis_smoke.cpp
@@ -0,0 +1,194 @@
// Copyright (c) Lawrence Livermore National Security, LLC and other Conduit
// Project developers. See top-level LICENSE AND COPYRIGHT files for dates and
// other details. No copyright assignment is required to contribute to Conduit.

//-----------------------------------------------------------------------------
///
/// file: t_parmetis_smoke.cpp
///
//-----------------------------------------------------------------------------

#include <mpi.h>
#include <iostream>
#include <fstream>

#include <parmetis.h>

//------------------------------------------------------------------------------
int main(int argc, char** argv)
{
// Initialize MPI and get rank and comm size
MPI_Init(&argc, &argv);

int par_rank, par_size;
MPI_Comm_rank(MPI_COMM_WORLD, &par_rank);
MPI_Comm_size(MPI_COMM_WORLD, &par_size);

//
// Simple example mesh
//
// 0 ---- 1 ---- 2
// | e0 | e1 |
// 3 ---- 4 --- 5
// | e2 | e3 |
// 6 ---- 7 ---- 8


// elems across processors,
// first rank has [0,1,2], second rank has [3]
idx_t eldist[] = {0, 3, 4};

/*
The eptr and eind arrays are similar in nature to the xadj and adjncy
arrays used to specify the adjacency list of a graph but now for each
element they specify the set of nodes that make up each element.
Specifically, the set of nodes that belong to element i is stored in
array eind starting at index eptr[i] and ending at (but not including)
index eptr[i + 1] (in other words, eind[eptr[i]] up through and including
eind[eptr[i + 1]-1]). Hence, the node lists for each element are stored
consecutively in the array eind.
*/

// e0 vertices 0,1,3,4
// e1 vertices 1,2,4,5
// e2 vertices 3,4,6,7

idx_t eind_rank_0[] = {0,1,3,4,
1,2,4,5,
3,4,6,7};

idx_t eptr_rank_0[] = {0,4,8,12};

// e3 vertices 4,5,7,8
idx_t eind_rank_1[] = {4,5,7,8};
idx_t eptr_rank_1[] = {0,4};

idx_t wgtflag = 0; // weights are NULL
idx_t numflag = 0; // C-style numbering
idx_t ncon = 1; // the number of weights per vertex
idx_t ncommonnodes = 4; // we have quads
idx_t nparts = 2; //
// equal weights for each proc
real_t tpwgts[] = {0.5,0.5};
real_t ubvec=1.050000;

// options == extra output
idx_t options[] = {1,
PARMETIS_DBGLVL_TIME |
PARMETIS_DBGLVL_INFO |
PARMETIS_DBGLVL_PROGRESS |
PARMETIS_DBGLVL_REFINEINFO |
PARMETIS_DBGLVL_MATCHINFO |
PARMETIS_DBGLVL_RMOVEINFO |
PARMETIS_DBGLVL_REMAP,
0};
// outputs
idx_t edgecut = 0; // will hold # of cut edges

// each proc will have its local answer
// rank 0 has 3 eles to label
idx_t part_rank_0[] = {10,10,10};

// rank 1 has 1 ele to label
idx_t part_rank_1[] = {20};

MPI_Comm mpi_comm = MPI_COMM_WORLD;

int res = -1;

// make sure everything is ok
if(par_rank == 0)
{
std::cout << "before:" << std::endl;
std::cout << "part_rank_0: ";
for(int i=0;i<3;i++)
{
std::cout << part_rank_0[i] << " ";
}
}

MPI_Barrier(MPI_COMM_WORLD);

if(par_rank == 1)
{
std::cout << std::endl;
std::cout << "part_rank_1: ";
for(int i=0;i<1;i++)
{
std::cout << part_rank_1[i] << " ";
}
std::cout << std::endl;
}

if(par_rank == 0)
{
res = ParMETIS_V3_PartMeshKway(eldist,
eptr_rank_0,
eind_rank_0,
NULL,
&wgtflag,
&numflag,
&ncon,
&ncommonnodes,
&nparts,
tpwgts,
&ubvec,
options,
&edgecut,
part_rank_0,
&mpi_comm);
}
else // rank == 1
{
res = ParMETIS_V3_PartMeshKway(eldist,
eptr_rank_1,
eind_rank_1,
NULL,
&wgtflag,
&numflag,
&ncon,
&ncommonnodes,
&nparts,
tpwgts,
&ubvec,
options,
&edgecut,
part_rank_1,
&mpi_comm);
}

// make sure everything is ok
if(res == METIS_ERROR)
{
std::cout << "METIS_ERROR!" << std::endl;
}

// print results
if(par_rank == 0)
{
std::cout << "after:" << std::endl;
std::cout << "part_rank_0: ";
for(int i=0;i<3;i++)
{
std::cout << part_rank_0[i] << " ";
}
std::cout << std::endl;
}

MPI_Barrier(MPI_COMM_WORLD);

if(par_rank == 1)
{
std::cout << "part_rank_1: ";
for(int i=0;i<1;i++)
{
std::cout << part_rank_1[i] << " ";
}
std::cout << std::endl;
}

// Finalize MPI
MPI_Finalize();

return (res == METIS_OK) ? 0 : -1;
}

0 comments on commit 893baed

Please sign in to comment.