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

Support for 0D #112

Merged
merged 7 commits into from
Mar 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion benchmarks/deepcopy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ static void memcpy_2d(benchmark::State& state)
std::vector<double> src_data(state.range(0) * state.range(1), 0.0);
std::vector<double> dst_data(state.range(0) * state.range(1), -1.0);
for (auto _ : state) {
for (std::size_t i = 0; i < state.range(0); ++i) {
for (std::size_t i = 0ull; i < state.range(0); ++i) {
std::
memcpy(dst_data.data() + i * state.range(1),
src_data.data() + i * state.range(1),
Expand Down
6 changes: 4 additions & 2 deletions docs/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ set(DOXYGEN_BUILTIN_STL_SUPPORT YES)
if("${DOXYGEN_VERSION}" VERSION_GREATER_EQUAL 1.9.4)
# Doxygen <= 1.9.4 suffers from https://github.com/doxygen/doxygen/issues/8784
set(DOXYGEN_CLANG_ASSISTED_PARSING YES)
set(DOXYGEN_CLANG_OPTIONS "-Wno-pragma-once-outside-header -Wno-invalid-pp-token -std=c++17")
set(DOXYGEN_CLANG_DATABASE_PATH "${CMAKE_BINARY_DIR}")
set(DOXYGEN_CLANG_OPTIONS " -Wno-unused-command-line-argument -Wno-error -Wno-error=unused-command-line-argument ")
else()
set(DOXYGEN_WARN_AS_ERROR "FAIL_ON_WARNINGS")
endif()
set(DOXYGEN_DISABLE_INDEX YES)
set(DOXYGEN_ENUM_VALUES_PER_LINE 1)
Expand Down Expand Up @@ -44,7 +47,6 @@ set(DOXYGEN_TOC_INCLUDE_HEADINGS 4)
set(DOXYGEN_TYPEDEF_HIDES_STRUCT YES)
set(DOXYGEN_UML_LIMIT_NUM_FIELDS 20)
set(DOXYGEN_UML_LOOK YES)
set(DOXYGEN_WARN_AS_ERROR "FAIL_ON_WARNINGS")
set(DOXYGEN_WARN_NO_PARAMDOC YES)
set(DOXYGEN_WARN_IF_UNDOCUMENTED NO)
set(DOXYGEN_IMAGE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/images")
Expand Down
2 changes: 1 addition & 1 deletion examples/heat_equation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ int main(int argc, char** argv)
// Simulated time to reach as target of the simulation
double const end_time = 10.;
// Number of time-steps between outputs
size_t const t_output_period = 10;
ptrdiff_t const t_output_period = 10;
//! [parameters]

//! [main-start]
Expand Down
148 changes: 148 additions & 0 deletions include/ddc/discrete_domain.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,126 @@ class DiscreteDomain
}
};

template <>
class DiscreteDomain<>
{
template <class...>
friend class DiscreteDomain;

public:
using discrete_element_type = DiscreteElement<>;

using mlength_type = DiscreteVector<>;

static constexpr std::size_t rank()
{
return 0;
}

constexpr DiscreteDomain() = default;

// Construct a DiscreteDomain from a reordered copy of `domain`
template <class... ODDims>
explicit constexpr DiscreteDomain(DiscreteDomain<ODDims...> const& domain)
{
}

/** Construct a DiscreteDomain starting from element_begin with size points.
* @param element_begin the lower bound in each direction
* @param size the number of points in each direction
*/
constexpr DiscreteDomain(
[[maybe_unused]] discrete_element_type const& element_begin,
[[maybe_unused]] mlength_type const& size)
{
}

constexpr DiscreteDomain(DiscreteDomain const& x) = default;

constexpr DiscreteDomain(DiscreteDomain&& x) = default;

~DiscreteDomain() = default;

DiscreteDomain& operator=(DiscreteDomain const& x) = default;

DiscreteDomain& operator=(DiscreteDomain&& x) = default;

constexpr bool operator==(DiscreteDomain const& other) const
{
return true;
}

#if __cplusplus <= 201703L
// Shall not be necessary anymore in C++20
// `a!=b` shall be translated by the compiler to `!(a==b)`
constexpr bool operator!=(DiscreteDomain const& other) const
{
return !(*this == other);
}
#endif

constexpr std::size_t size() const
{
return 1;
}

constexpr mlength_type extents() const noexcept
{
return {};
}

constexpr discrete_element_type front() const noexcept
{
return {};
}

constexpr discrete_element_type back() const noexcept
{
return {};
}

constexpr DiscreteDomain take_first(mlength_type n) const
{
return *this;
}

constexpr DiscreteDomain take_last(mlength_type n) const
{
return *this;
}

constexpr DiscreteDomain remove_first(mlength_type n) const
{
return *this;
}

constexpr DiscreteDomain remove_last(mlength_type n) const
{
return *this;
}

constexpr DiscreteDomain remove(mlength_type n1, mlength_type n2) const
{
return *this;
}

template <class... ODims>
constexpr DiscreteDomain restrict(DiscreteDomain<ODims...> const&) const
{
return *this;
}

constexpr bool empty() const noexcept
{
return false;
}

constexpr explicit operator bool()
{
return true;
}
};

template <class... QueryDDims, class... DDims>
constexpr DiscreteDomain<QueryDDims...> select(DiscreteDomain<DDims...> const& domain)
{
Expand All @@ -239,6 +359,34 @@ constexpr DiscreteDomain<QueryDDims...> select(DiscreteDomain<DDims...> const& d
select<QueryDDims...>(domain.extents()));
}

namespace ddc_detail {

template <class T>
struct ConvertTypeSeqToDiscreteDomain;

template <class... DDims>
struct ConvertTypeSeqToDiscreteDomain<ddc_detail::TypeSeq<DDims...>>
{
using type = DiscreteDomain<DDims...>;
};

template <class T>
using convert_type_seq_to_discrete_domain = typename ConvertTypeSeqToDiscreteDomain<T>::type;

} // namespace ddc_detail

template <class... DDimsA, class... DDimsB>
constexpr auto remove_dims_of(
DiscreteDomain<DDimsA...> const& DDom_a,
DiscreteDomain<DDimsB...> const& DDom_b) noexcept
{
using TagSeqA = ddc_detail::TypeSeq<DDimsA...>;
using TagSeqB = ddc_detail::TypeSeq<DDimsB...>;

using type_seq_r = type_seq_remove_t<TagSeqA, TagSeqB>;
return ddc_detail::convert_type_seq_to_discrete_domain<type_seq_r>(DDom_a);
}

template <class... QueryDDims, class... DDims>
constexpr DiscreteVector<QueryDDims...> extents(DiscreteDomain<DDims...> const& domain) noexcept
{
Expand Down
77 changes: 73 additions & 4 deletions tests/chunk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,23 @@

namespace {

using DElem0D = ddc::DiscreteElement<>;
using DVect0D = ddc::DiscreteVector<>;
using DDom0D = ddc::DiscreteDomain<>;

template <class Datatype>
using Chunk0D = ddc::Chunk<Datatype, DDom0D>;
template <class Datatype>
using ChunkSpan0D = ddc::ChunkSpan<Datatype, DDom0D>;


struct DDimX;
using DElemX = ddc::DiscreteElement<DDimX>;
using DVectX = ddc::DiscreteVector<DDimX>;
using DDomX = ddc::DiscreteDomain<DDimX>;

template <class Datatype>
using ChunkX = ddc::Chunk<Datatype, DDomX>;
template <class Datatype>
using ChunkSpanX = ddc::ChunkSpan<Datatype, DDomX>;


struct DDimY;
Expand Down Expand Up @@ -47,6 +55,10 @@ template <class Datatype>
using ChunkYX = ddc::Chunk<Datatype, DDomYX>;


static DElem0D constexpr lbound_0d {};
static DVect0D constexpr nelems_0d {};
static DDom0D constexpr dom_0d(lbound_0d, nelems_0d);

static DElemX constexpr lbound_x(50);
static DVectX constexpr nelems_x(3);
static DDomX constexpr dom_x(lbound_x, nelems_x);
Expand All @@ -62,6 +74,15 @@ static DDomXY constexpr dom_x_y(lbound_x_y, nelems_x_y);

// Member types of Chunk 1D \{

TEST(Chunk0DTest, LayoutType)
{
Chunk0D<double> chunk;

EXPECT_TRUE((std::is_same_v<
std::decay_t<decltype(chunk)>::layout_type,
std::experimental::layout_right>));
}

TEST(Chunk1DTest, LayoutType)
{
ChunkX<double> chunk(dom_x);
Expand All @@ -76,6 +97,17 @@ TEST(Chunk1DTest, LayoutType)
// \}
// Functions implemented in Chunk 1D (and free functions specific to it) \{

TEST(Chunk0DTest, ChunkSpanConversionConstructor)
{
double constexpr factor = 1.391;
Chunk0D<double> chunk(dom_0d);
chunk() = factor;

Chunk0D<double> chunk2(chunk.span_view());
EXPECT_EQ(chunk2.domain(), dom_0d);
EXPECT_DOUBLE_EQ(factor, chunk2());
}

TEST(Chunk1DTest, ChunkSpanConversionConstructor)
{
double constexpr factor = 1.391;
Expand All @@ -87,11 +119,21 @@ TEST(Chunk1DTest, ChunkSpanConversionConstructor)
ChunkX<double> chunk2(chunk.span_view());
EXPECT_EQ(chunk2.domain(), dom_x);
for (auto&& ix : chunk2.domain()) {
// we expect exact equality, not EXPECT_DOUBLE_EQ: this is the same ref twice
EXPECT_EQ(factor * ix.uid(), chunk2(ix));
EXPECT_DOUBLE_EQ(factor * ix.uid(), chunk2(ix));
}
}

TEST(Chunk0DTest, MoveConstructor)
{
double constexpr factor = 1.391;
Chunk0D<double> chunk(dom_0d);
chunk() = factor;

Chunk0D<double> chunk2(std::move(chunk));
EXPECT_EQ(chunk2.domain(), dom_0d);
EXPECT_DOUBLE_EQ(factor, chunk2());
}

TEST(Chunk1DTest, MoveConstructor)
{
double constexpr factor = 1.391;
Expand All @@ -108,6 +150,18 @@ TEST(Chunk1DTest, MoveConstructor)
}
}

TEST(Chunk0DTest, MoveAssignment)
{
double constexpr factor = 1.976;
Chunk0D<double> chunk(dom_0d);
chunk() = factor;

Chunk0D<double> chunk2(DDom0D(lbound_0d, DVect0D()));
chunk2 = std::move(chunk);
EXPECT_EQ(chunk2.domain(), dom_0d);
EXPECT_DOUBLE_EQ(factor, chunk2());
}

TEST(Chunk1DTest, MoveAssignment)
{
double constexpr factor = 1.976;
Expand All @@ -125,6 +179,21 @@ TEST(Chunk1DTest, MoveAssignment)
}
}

TEST(Chunk0DTest, Swap)
{
double constexpr factor = 1.976;
Chunk0D<double> chunk(dom_0d);
chunk() = factor;

DDom0D empty_domain(lbound_0d, DVect0D());
Chunk0D<double> chunk2(empty_domain);

std::swap(chunk2, chunk);
EXPECT_EQ(chunk.domain(), empty_domain);
EXPECT_EQ(chunk2.domain(), dom_0d);
EXPECT_DOUBLE_EQ(factor, chunk2());
}

TEST(Chunk1DTest, Swap)
{
double constexpr factor = 1.976;
Expand Down
21 changes: 21 additions & 0 deletions tests/discrete_domain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ using DElemYX = ddc::DiscreteElement<DDimY, DDimX>;
using DVectYX = ddc::DiscreteVector<DDimY, DDimX>;
using DDomYX = ddc::DiscreteDomain<DDimY, DDimX>;

using DElemZY = ddc::DiscreteElement<DDimZ, DDimY>;
using DVectZY = ddc::DiscreteVector<DDimZ, DDimY>;
using DDomZY = ddc::DiscreteDomain<DDimZ, DDimY>;



static DElemX constexpr lbound_x(50);
static DVectX constexpr nelems_x(3);
Expand Down Expand Up @@ -107,3 +112,19 @@ TEST(ProductMDomainTest, RangeFor)
++ii.uid<DDimX>();
}
}

TEST(ProductMDomainTest, DiffEmpty)
{
DDomX const dom_x = DDomX();
auto const subdomain = ddc::remove_dims_of(dom_x, dom_x);
EXPECT_EQ(subdomain, ddc::DiscreteDomain<>());
}

TEST(ProductMDomainTest, Diff)
{
DDomX const dom_x = DDomX();
DDomXY const dom_x_y = DDomXY();
DDomZY const dom_z_y = DDomZY();
auto const subdomain = ddc::remove_dims_of(dom_x_y, dom_z_y);
EXPECT_EQ(subdomain, dom_x);
}
17 changes: 15 additions & 2 deletions tests/for_each.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

#include <gtest/gtest.h>

using DElem0D = ddc::DiscreteElement<>;
using DVect0D = ddc::DiscreteVector<>;
using DDom0D = ddc::DiscreteDomain<>;

struct DDimX;
using DElemX = ddc::DiscreteElement<DDimX>;
using DVectX = ddc::DiscreteVector<DDimX>;
Expand Down Expand Up @@ -33,8 +37,17 @@ TEST(ForEachSerialHost, Empty)
std::vector<int> storage(dom.size(), 0);
ddc::ChunkSpan<int, DDomX> view(storage.data(), dom);
ddc::for_each(ddc::policies::serial_host, dom, [=](DElemX const ix) { view(ix) += 1; });
ASSERT_EQ(std::count(storage.begin(), storage.end(), 1), dom.size());
std::cout << std::count(storage.begin(), storage.end(), 1) << std::endl;
ASSERT_EQ(std::count(storage.begin(), storage.end(), 1), dom.size())
<< std::count(storage.begin(), storage.end(), 1) << std::endl;
}

TEST(ForEachSerialHost, ZeroDimension)
{
DDom0D const dom;
int storage = 0;
ddc::ChunkSpan<int, DDom0D> view(&storage, dom);
ddc::for_each(ddc::policies::serial_host, dom, [=](DElem0D const ii) { view(ii) += 1; });
ASSERT_EQ(storage, 1) << storage << std::endl;
}

TEST(ForEachSerialHost, OneDimension)
Expand Down