Commit 84201902 authored by Utkarsh Ayachit's avatar Utkarsh Ayachit
Browse files

Merge branch 'diy-as-3rd-party' into 'master'

DIY as 3rd party import

See merge request vtk/vtk-m!1047
parents 91178ffc 4a052772
......@@ -14,4 +14,4 @@ data/* filter=lfs diff=lfs merge=lfs -text
*.rst whitespace=tab-in-indent conflict-marker-size=79
*.txt whitespace=tab-in-indent
diy/** -format.clang-format -whitespace
vtkm/thirdparty/diy/vtkmdiy/** -format.clang-format -whitespace
......@@ -39,9 +39,7 @@ set(FILES_TO_CHECK
set(EXCEPTIONS
LICENSE.txt
README.txt
diy/include/diy
diy/LEGAL.txt
diy/LICENSE.txt
vtkm/thirdparty/diy/vtkmdiy
)
if (NOT VTKm_SOURCE_DIR)
......
......@@ -39,11 +39,21 @@ set(FILES_TO_CHECK
set(EXCEPTIONS
)
set(DIRECTORY_EXCEPTIONS
${VTKm_SOURCE_DIR}/vtkm/thirdparty/diy/vtkmdiy
)
if (NOT VTKm_SOURCE_DIR)
message(SEND_ERROR "VTKm_SOURCE_DIR not defined.")
endif (NOT VTKm_SOURCE_DIR)
function(check_directory directory parent_CMakeLists_contents)
foreach(exception IN LISTS DIRECTORY_EXCEPTIONS)
if(directory MATCHES "^${exception}$")
return()
endif()
endforeach(exception)
message("Checking directory ${directory}...")
get_filename_component(directory_name "${directory}" NAME)
......
......@@ -221,11 +221,6 @@ find_package(Pyexpander)
#-----------------------------------------------------------------------------
# Add subdirectories
if(VTKm_ENABLE_MPI)
# This `if` is temporary and will be removed once `diy` supports building
# without MPI.
add_subdirectory(diy)
endif()
add_subdirectory(vtkm)
#-----------------------------------------------------------------------------
......
......@@ -67,6 +67,11 @@ vtkm_declare_headers(${headers})
#-----------------------------------------------------------------------------
#first add all the components vtkm that are shared between control and exec
if(VTKm_ENABLE_MPI)
# This `if` is temporary and will be removed once `diy` supports building
# without MPI.
add_subdirectory(thirdparty/diy)
endif()
add_subdirectory(testing)
add_subdirectory(internal)
......
......@@ -21,8 +21,10 @@
#if defined(VTKM_ENABLE_MPI)
#include <diy/mpi.hpp>
// clang-format off
#include <vtkm/cont/EnvironmentTracker.h>
#include VTKM_DIY(diy/mpi.hpp)
// clang-format on
#include <algorithm> // std::lower_bound
#include <numeric> // std::iota
......
......@@ -21,11 +21,15 @@
#define vtk_m_cont_AssignerMultiBlock_h
#include <vtkm/internal/Configure.h>
#if defined(VTKM_ENABLE_MPI)
#include <diy/assigner.hpp>
#if defined(VTKM_ENABLE_MPI)
#include <vtkm/cont/MultiBlock.h>
// clang-format off
#include <vtkm/thirdparty/diy/Configure.h>
#include VTKM_DIY(diy/assigner.hpp)
// clang-format on
namespace vtkm
{
namespace cont
......
......@@ -20,7 +20,12 @@
#include <vtkm/cont/EnvironmentTracker.h>
#if defined(VTKM_ENABLE_MPI)
#include <diy/mpi.hpp>
// clang-format off
#include <vtkm/thirdparty/diy/Configure.h>
#include VTKM_DIY(diy/mpi.hpp)
// clang-format on
#else
namespace diy
{
......
......@@ -25,6 +25,11 @@
#include <vtkm/internal/Configure.h>
#include <vtkm/internal/ExportMacros.h>
#if defined(VTKM_ENABLE_MPI)
// needed for diy mangling.
#include <vtkm/thirdparty/diy/Configure.h>
#endif
namespace diy
{
namespace mpi
......
......@@ -32,11 +32,14 @@
#include <vtkm/cont/MultiBlock.h>
#if defined(VTKM_ENABLE_MPI)
#include <diy/decomposition.hpp>
#include <diy/master.hpp>
#include <diy/partners/all-reduce.hpp>
#include <diy/partners/swap.hpp>
#include <diy/reduce.hpp>
// clang-format off
#include <vtkm/thirdparty/diy/Configure.h>
#include VTKM_DIY(diy/decomposition.hpp)
#include VTKM_DIY(diy/master.hpp)
#include VTKM_DIY(diy/partners/all-reduce.hpp)
#include VTKM_DIY(diy/partners/swap.hpp)
#include VTKM_DIY(diy/reduce.hpp)
// clang-format on
namespace vtkm
{
......
......@@ -36,7 +36,12 @@
#include <vtkm/exec/ConnectivityStructured.h>
#if defined(VTKM_ENABLE_MPI)
#include <diy/master.hpp>
// clang-format off
#include <vtkm/thirdparty/diy/Configure.h>
#include VTKM_DIY(diy/master.hpp)
// clang-format on
#endif
void DataSet_Compare(vtkm::cont::DataSet& LeftDateSet, vtkm::cont::DataSet& RightDateSet);
......
# Updating Third Party Projects
When updating a third party project, any changes to the imported project
itself (e.g., the `diy/vtkmdiy` directory for diy), should go through the
`update.sh` framework. This framework ensures that all patches to the third
party projects are tracked externally and available for (preferably) upstream
or other projects also embedding the library.
# Updating a Project
Once converted, a project should be updated by applying patches to the
repository specified in its `update.sh` script. Once the changes are merged,
pulling the changes involves running the `update.sh` script. This will update
the local copy of the project to the version specified in `update.sh` (usually
a `for/foo` branch, like `for/vtk-m` for example, but may be `master` or any
other Git reference) and merge it into the main tree.
This requires a Git 2.5 or higher due the `worktree` tool being used to
simplify the availability of the commits to the main checkout.
Here's an example of updating the `diy` project from tag v2.0 to v2.1,
starting with updating the third-party repo
```sh
$ cd diy
$ git checkout for/vtk-m
$ git fetch origin
$ git rebase --onto v2.1 v2.0
$ git push
```
Now import into VTK-m
```sh
$ cd vtkm/ThirdParty/diy
$ git checkout -b update_diy
$ ./update.sh
```
Now you can review the change and make a merge request from the branch as normal.
# Porting a Project
When converting a project, if there are any local patches, a project should be
created [on GitLab](https://gitlab.kitware.com/third-party) to track it. If
the upstream project does not use Git, it should be imported into Git (there
may be existing conversions available on Github already). The project's
description should indicate where the source repository lives.
Once a mirror of the project is created, a branch named `for/foo` should be
created where patches for the `foo` project will be applied (i.e., `for/vtk-m`
for VTK-m's patches to the project). Usually, changes to the build system, the
source code for mangling, the addition of `.gitattributes` files, and other
changes belong here. Functional changes should be submitted upstream (but may
still be tracked so that they may be used).
The basic steps to import a project `diy` based on the tag
`v2.0` looks like this:
```sh
$ git clone https://github.com/diatomic/diy.git
$ cd diy/
$ git remote add kitware git@gitlab.kitware.com:third-party/diy.git
$ git push -u kitware
$ git push -u kitware --tags
$ git checkout v2.0
$ git checkout -b for/vtk-m
$ git push --set-upstream kitware for/vtk-m
```
Making the initial import involves filling out the project's `update.sh`
script in its directory. The [update-common.sh](update-common.sh) script
describes what is necessary, but in a nutshell, it is basically metadata such
as the name of the project and where it goes in the importing project.
The most important bit is the `extract_source` function which should subset
the repository. If all that needs to be done is to extract the files given in
the `paths` variable (described in the `update-common.sh` script), the
`git_archive` function may be used if the `git archive` tool generates a
suitable subset.
Make sure `update.sh` is executable before commit. On Unix, run:
```sh
$ chmod u+x update.sh && git add -u update.sh
```
On Windows, run:
```sh
$ git update-index --chmod=+x update.sh
```
# Process
The basic process involves a second branch where the third party project's
changes are tracked. This branch has a commit for each time it has been
updated and is stripped to only contain the relevant parts (no unit tests,
documentation, etc.). This branch is then merged into the main branch as a
subdirectory using the `subtree` merge strategy.
Initial conversions will require a manual push by the maintainers since the
conversion involves a root commit which is not allowed under normal
circumstances. Please send an email to the mailing list asking for assistance
if necessary.
......@@ -19,17 +19,22 @@
## this software.
##
##=============================================================================
#==============================================================================
# See License.txt
#==============================================================================
add_library(diy INTERFACE)
vtkm_get_kit_name(kit_name kit_dir)
# diy needs C++11
target_compile_features(diy INTERFACE cxx_auto_type)
# placeholder to support external DIY
set(VTKM_USE_EXTERNAL_DIY OFF)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Configure.h.in
${VTKm_BINARY_INCLUDE_DIR}/${kit_dir}/Configure.h)
target_include_directories(diy INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
$<INSTALL_INTERFACE:${VTKm_INSTALL_INCLUDE_DIR}>)
# presently, this dependency is required. Make it optional in the future.
......@@ -55,11 +60,8 @@ endif()
install(TARGETS diy
EXPORT ${VTKm_EXPORT_NAME})
# Install headers
install(DIRECTORY include/diy
DESTINATION ${VTKm_INSTALL_INCLUDE_DIR})
# Install other files.
install(FILES LEGAL.txt LICENSE.txt
DESTINATION ${VTKm_INSTALL_INCLUDE_DIR}/diy
)
## Install headers
install(DIRECTORY vtkmdiy
DESTINATION ${VTKm_INSTALL_INCLUDE_DIR}/${kit_dir}/)
install(FILES ${VTKm_BINARY_INCLUDE_DIR}/${kit_dir}/Configure.h
DESTINATION ${VTKm_INSTALL_INCLUDE_DIR}/${kit_dir}/)
//=============================================================================
//
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
//
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2015 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2015 UT-Battelle, LLC.
// Copyright 2015 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//
//=============================================================================
#ifndef vtkm_diy_h
#define vtkm_diy_h
/* Use the diy library configured for VTM-m. */
#cmakedefine01 VTKM_USE_EXTERNAL_DIY
#if VTKM_USE_EXTERNAL_DIY
# define VTKM_DIY(header) <header>
#else
# define VTKM_DIY(header) <vtkmdiy/include/header>
# define diy vtkmdiy // mangle namespace diy
#endif
#endif
#!/usr/bin/env bash
set -e
set -x
shopt -s dotglob
readonly name="diy"
readonly ownership="Diy Upstream <kwrobot@kitware.com>"
readonly subtree="vtkm/thirdparty/$name/vtkm$name"
readonly repo="https://gitlab.kitware.com/third-party/diy2.git"
readonly tag="for/vtk-m"
readonly paths="
include
LEGAL.txt
LICENSE.txt
README.md
"
extract_source () {
git_archive
pushd "$extractdir/$name-reduced"
mv include/diy include/vtkmdiy
popd
}
. "${BASH_SOURCE%/*}/../update-common.sh"
## DIY is a block-parallel library
DIY is a block-parallel library for implementing scalable algorithms that can execute both
in-core and out-of-core. The same program can be executed with one or more threads per MPI
process, seamlessly combining distributed-memory message passing with shared-memory thread
parallelism. The abstraction enabling these capabilities is block parallelism; blocks
and their message queues are mapped onto processing elements (MPI processes or threads) and are
migrated between memory and storage by the DIY runtime. Complex communication patterns,
including neighbor exchange, merge reduction, swap reduction, and all-to-all exchange, are
possible in- and out-of-core in DIY.
## Licensing
DIY is released as open source software under a BSD-style [license](./LICENSE.txt).
## Dependencies
DIY requires an MPI installation. We recommend [MPICH](http://www.mpich.org/).
## Download, build, install
- You can clone this repository, or
- You can download the [latest tarball](https://github.com/diatomic/diy2/archive/master.tar.gz).
DIY is a header-only library. It does not need to be built; you can simply
include it in your project. The examples can be built using `cmake` from the
top-level directory.
## Documentation
[Doxygen pages](https://diatomic.github.io/diy)
## Example
A simple DIY program, shown below, consists of the following components:
- `struct`s called blocks,
- a diy object called the `master`,
- a set of callback functions performed on each block by `master.foreach()`,
- optionally, one or more message exchanges between the blocks by `master.exchange()`, and
- there may be other collectives and global reductions not shown below.
The callback functions (`enqueue_local()` and `average()` in the example below) receive the block
pointer and a communication proxy for the message exchange between blocks. It is usual for the
callback functions to enqueue or dequeue messages from the proxy, so that information can be
received and sent during rounds of message exchange.
```cpp
// --- main program --- //
struct Block { float local, average; }; // define your block structure
Master master(world); // world = MPI_Comm
... // populate master with blocks
master.foreach(&enqueue_local); // call enqueue_local() for each block
master.exchange(); // exchange enqueued data between blocks
master.foreach(&average); // call average() for each block
// --- callback functions --- //
// enqueue block data prior to exchanging it
void enqueue_local(Block* b, // current block
const Proxy& cp) // communication proxy provides access to the neighbor blocks
{
for (size_t i = 0; i < cp.link()->size(); i++) // for all neighbor blocks
cp.enqueue(cp.link()->target(i), b->local); // enqueue the data to be sent to this neighbor
// block in the next exchange
}
// use the received data after exchanging it, in this case compute its average
void average(Block* b, // current block
const Proxy& cp) // communication proxy provides access to the neighbor blocks
{
float x, average = 0;
for (size_t i = 0; i < cp.link()->size(); i++) // for all neighbor blocks
{
cp.dequeue(cp.link()->target(i).gid, x); // dequeue the data received from this
// neighbor block in the last exchange
average += x;
}
b->average = average / cp.link()->size();
}
```
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment