Skip to content

Commit

Permalink
Merge: Add an IndexSet class
Browse files Browse the repository at this point in the history
This PR adds an Index set class which stores non-contiguous subsets of the form [begin,end). It is non-dynamic, which means that it is not possible to add and remove subsets after creation.

Internally, the class stores three separate arrays, containing the starts of the subsets, the end of the subsets and the superset index of the start of the subset, respectively. The class is optimized for storage by storing only the end points and hence is more efficient than storing complete index ranges. It aims to provide the following functionalities:

1. Local to global index conversions.
2. Global to local index conversions.
3. Checking the number of stored indices.
4. If given index is an element of the IndexSet.

Related PR: #676
  • Loading branch information
pratikvn authored Nov 4, 2021
2 parents e0bb433 + 3e04910 commit 6a35f6b
Show file tree
Hide file tree
Showing 26 changed files with 2,155 additions and 17 deletions.
29 changes: 15 additions & 14 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -695,20 +695,21 @@ build/dpcpp/igpu/release/shared:
DPCPP_SINGLE_MODE: "ON"
SYCL_DEVICE_TYPE: "GPU"

build/dpcpp/level_zero_igpu/debug/shared:
<<: *default_build_with_test
extends:
- .full_test_condition
- .use_gko-oneapi-igpu
variables:
<<: *default_variables
C_COMPILER: "gcc"
CXX_COMPILER: "dpcpp"
BUILD_DPCPP: "ON"
BUILD_TYPE: "Debug"
BUILD_SHARED_LIBS: "ON"
DPCPP_SINGLE_MODE: "ON"
SYCL_DEVICE_FILTER: "Level_Zero:GPU"
# TODO: Enable when debug shared library size issues are fixed
# build/dpcpp/level_zero_igpu/debug/shared:
# <<: *default_build_with_test
# extends:
# - .full_test_condition
# - .use_gko-oneapi-igpu
# variables:
# <<: *default_variables
# C_COMPILER: "gcc"
# CXX_COMPILER: "dpcpp"
# BUILD_DPCPP: "ON"
# BUILD_TYPE: "Debug"
# BUILD_SHARED_LIBS: "ON"
# DPCPP_SINGLE_MODE: "ON"
# SYCL_DEVICE_FILTER: "Level_Zero:GPU"

# It gives two available backends of GPU on tests
build/dpcpp/dgpu/release/static:
Expand Down
1 change: 1 addition & 0 deletions common/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
set(UNIFIED_SOURCES
base/index_set_kernels.cpp
components/precision_conversion.cpp
components/reduce_array.cpp
matrix/coo_kernels.cpp
Expand Down
74 changes: 74 additions & 0 deletions common/unified/base/index_set_kernels.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*******************************<GINKGO LICENSE>******************************
Copyright (c) 2017-2021, the Ginkgo authors
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
******************************<GINKGO LICENSE>*******************************/

#include "core/base/index_set_kernels.hpp"


#include <ginkgo/core/base/math.hpp>


#include "common/unified/base/kernel_launch.hpp"


namespace gko {
namespace kernels {
namespace GKO_DEVICE_NAMESPACE {
/**
* @brief The IndexSet namespace.
*
* @ingroup index_set
*/
namespace index_set {


template <typename IndexType>
void compute_validity(std::shared_ptr<const DefaultExecutor> exec,
const Array<IndexType>* local_indices,
Array<bool>* validity_array)
{
run_kernel(
exec,
[] GKO_KERNEL(auto elem, auto local_indices, auto validity_array) {
validity_array[elem] =
local_indices[elem] != invalid_index<IndexType>();
},
local_indices->get_num_elems(), *local_indices, *validity_array);
}

GKO_INSTANTIATE_FOR_EACH_INDEX_TYPE(
GKO_DECLARE_INDEX_SET_COMPUTE_VALIDITY_KERNEL);


} // namespace index_set
} // namespace GKO_DEVICE_NAMESPACE
} // namespace kernels
} // namespace gko
1 change: 1 addition & 0 deletions core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ target_sources(ginkgo
base/combination.cpp
base/composition.cpp
base/executor.cpp
base/index_set.cpp
base/mtx_io.cpp
base/perturbation.cpp
base/version.cpp
Expand Down
162 changes: 162 additions & 0 deletions core/base/index_set.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
/*******************************<GINKGO LICENSE>******************************
Copyright (c) 2017-2021, the Ginkgo authors
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
******************************<GINKGO LICENSE>*******************************/

#include <ginkgo/core/base/index_set.hpp>


#include <algorithm>
#include <iostream>
#include <mutex>
#include <vector>


#include <ginkgo/core/base/exception_helpers.hpp>
#include <ginkgo/core/base/types.hpp>


#include "core/base/index_set_kernels.hpp"


namespace gko {
namespace index_set {


GKO_REGISTER_OPERATION(to_global_indices, index_set::to_global_indices);
GKO_REGISTER_OPERATION(populate_subsets, index_set::populate_subsets);
GKO_REGISTER_OPERATION(global_to_local, index_set::global_to_local);
GKO_REGISTER_OPERATION(local_to_global, index_set::local_to_global);


} // namespace index_set


template <typename IndexType>
void IndexSet<IndexType>::populate_subsets(const gko::Array<IndexType>& indices,
const bool is_sorted)
{
auto exec = this->get_executor();
this->num_stored_indices_ = indices.get_num_elems();
exec->run(index_set::make_populate_subsets(
this->index_space_size_, &indices, &this->subsets_begin_,
&this->subsets_end_, &this->superset_cumulative_indices_, is_sorted));
}


template <typename IndexType>
bool IndexSet<IndexType>::contains(const IndexType input_index) const
{
auto local_index = this->get_local_index(input_index);
return local_index != invalid_index<IndexType>();
}


template <typename IndexType>
IndexType IndexSet<IndexType>::get_global_index(const IndexType index) const
{
auto exec = this->get_executor();
const auto local_idx =
Array<IndexType>(exec, std::initializer_list<IndexType>{index});
auto global_idx =
Array<IndexType>(exec, this->map_local_to_global(local_idx, true));

return exec->copy_val_to_host(global_idx.get_data());
}


template <typename IndexType>
IndexType IndexSet<IndexType>::get_local_index(const IndexType index) const
{
auto exec = this->get_executor();
const auto global_idx =
Array<IndexType>(exec, std::initializer_list<IndexType>{index});
auto local_idx =
Array<IndexType>(exec, this->map_global_to_local(global_idx, true));

return exec->copy_val_to_host(local_idx.get_data());
}


template <typename IndexType>
Array<IndexType> IndexSet<IndexType>::to_global_indices() const
{
auto exec = this->get_executor();
auto num_elems = exec->copy_val_to_host(
this->superset_cumulative_indices_.get_const_data() +
this->superset_cumulative_indices_.get_num_elems() - 1);
auto decomp_indices = gko::Array<IndexType>(exec, num_elems);
exec->run(index_set::make_to_global_indices(
this->index_space_size_, &this->subsets_begin_, &this->subsets_end_,
&this->superset_cumulative_indices_, &decomp_indices));

return decomp_indices;
}


template <typename IndexType>
Array<IndexType> IndexSet<IndexType>::map_local_to_global(
const Array<IndexType>& local_indices, const bool is_sorted) const
{
auto exec = this->get_executor();
auto global_indices =
gko::Array<IndexType>(exec, local_indices.get_num_elems());

GKO_ASSERT(this->get_num_subsets() >= 1);
exec->run(index_set::make_local_to_global(
this->index_space_size_, &this->subsets_begin_, &this->subsets_end_,
&this->superset_cumulative_indices_, &local_indices, &global_indices,
is_sorted));
return global_indices;
}


template <typename IndexType>
Array<IndexType> IndexSet<IndexType>::map_global_to_local(
const Array<IndexType>& global_indices, const bool is_sorted) const
{
auto exec = this->get_executor();
auto local_indices =
gko::Array<IndexType>(exec, global_indices.get_num_elems());

GKO_ASSERT(this->get_num_subsets() >= 1);
exec->run(index_set::make_global_to_local(
this->index_space_size_, &this->subsets_begin_, &this->subsets_end_,
&this->superset_cumulative_indices_, &global_indices, &local_indices,
is_sorted));
return local_indices;
}


#define GKO_DECLARE_INDEX_SET(_type) class IndexSet<_type>
GKO_INSTANTIATE_FOR_EACH_INDEX_TYPE(GKO_DECLARE_INDEX_SET);


} // namespace gko
Loading

0 comments on commit 6a35f6b

Please sign in to comment.