Skip to content

Commit

Permalink
#9: rename inverse to reciprocal; add kokkos ops
Browse files Browse the repository at this point in the history
  • Loading branch information
cwschilly committed Oct 30, 2024
1 parent 906d8f5 commit c43ed94
Show file tree
Hide file tree
Showing 10 changed files with 247 additions and 13 deletions.
3 changes: 2 additions & 1 deletion include/pressio/ops.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ template<class ...> struct matching_extents;
#include "ops/eigen/ops_rank1_update.hpp"
#include "ops/eigen/ops_rank2_update.hpp"
#include "ops/eigen/ops_elementwise_multiply.hpp"
#include "ops/eigen/ops_elementwise_inverse.hpp"
#include "ops/eigen/ops_elementwise_reciprocal.hpp"
#include "ops/eigen/ops_level2.hpp"
#include "ops/eigen/ops_level3.hpp"
#endif
Expand All @@ -110,6 +110,7 @@ template<class ...> struct matching_extents;
#include "ops/kokkos/ops_vector_update.hpp"
#include "ops/kokkos/ops_rank2_update.hpp"
#include "ops/kokkos/ops_elementwise_multiply.hpp"
#include "ops/kokkos/ops_elementwise_reciprocal.hpp"
#include "ops/kokkos/ops_level2.hpp"
#include "ops/kokkos/ops_level3.hpp"
#endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//@HEADER
// ************************************************************************
//
// ops_elementwise_inverse.hpp
// ops_elementwise_reciprocal.hpp
// Pressio
// Copyright 2019
// National Technology & Engineering Solutions of Sandia, LLC (NTESS)
Expand Down Expand Up @@ -46,8 +46,8 @@
//@HEADER
*/

#ifndef PRESSIOOPS_OPS_EIGEN_OPS_ELEMENTWISE_INVERSE_HPP_
#define PRESSIOOPS_OPS_EIGEN_OPS_ELEMENTWISE_INVERSE_HPP_
#ifndef PRESSIOOPS_OPS_EIGEN_OPS_elementwise_reciprocal_HPP_
#define PRESSIOOPS_OPS_EIGEN_OPS_elementwise_reciprocal_HPP_

namespace pressio{ namespace ops{

Expand All @@ -57,7 +57,7 @@ namespace pressio{ namespace ops{

template <class T1, class T2>
std::enable_if_t<
// common elementwise_inverse constraints
// common elementwise_reciprocal constraints
::pressio::Traits<T1>::rank == 1
&& ::pressio::Traits<T2>::rank == 1
// TPL/container specific
Expand All @@ -73,7 +73,7 @@ std::enable_if_t<
&& (std::is_floating_point<typename ::pressio::Traits<T1>::scalar_type>::value
|| std::is_integral<typename ::pressio::Traits<T1>::scalar_type>::value)
>
elementwise_inverse(const T1 & z, T2 & y)
elementwise_reciprocal(const T1 & z, T2 & y)
{
assert(::pressio::ops::extent(z, 0)==::pressio::ops::extent(y, 0));

Expand All @@ -84,4 +84,4 @@ elementwise_inverse(const T1 & z, T2 & y)
}

}}//end namespace pressio::ops
#endif // PRESSIOOPS_OPS_EIGEN_OPS_ELEMENTWISE_INVERSE_HPP_
#endif // PRESSIOOPS_OPS_EIGEN_OPS_elementwise_reciprocal_HPP_
88 changes: 88 additions & 0 deletions include/pressio/ops/kokkos/ops_elementwise_reciprocal.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
//@HEADER
// ************************************************************************
//
// ops_elementwise_multiply.hpp
// Pressio
// Copyright 2019
// National Technology & Engineering Solutions of Sandia, LLC (NTESS)
//
// Under the terms of Contract DE-NA0003525 with NTESS, the
// U.S. Government retains certain rights in this software.
//
// Pressio is licensed under BSD-3-Clause terms of use:
//
// 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.
//
// Questions? Contact Francesco Rizzi ([email protected])
//
// ************************************************************************
//@HEADER
*/

#ifndef PRESSIOOPS_OPS_KOKKOS_OPS_ELEMENTWISE_RECIPROCAL_HPP_
#define PRESSIOOPS_OPS_KOKKOS_OPS_ELEMENTWISE_RECIPROCAL_HPP_

#include "ops_vector_reciprocal_kokkos_functor.hpp"

namespace pressio{ namespace ops{

//----------------------------------------------------------------------
// computing elementwise: y = 1/z
//----------------------------------------------------------------------
template <typename T1, typename T2>
std::enable_if_t<
// common elementwise_multiply constraints
::pressio::Traits<T1>::rank == 1
&& ::pressio::Traits<T2>::rank == 1
// TPL/container specific
&& (::pressio::is_native_container_kokkos<T1>::value
|| ::pressio::is_expression_acting_on_kokkos<T1>::value)
&& (::pressio::is_native_container_kokkos<T2>::value
|| ::pressio::is_expression_acting_on_kokkos<T2>::value)
// scalar compatibility
&& ::pressio::all_have_traits_and_same_scalar<T1, T2>::value
&& (std::is_floating_point<typename ::pressio::Traits<T1>::scalar_type>::value
|| std::is_integral<typename ::pressio::Traits<T1>::scalar_type>::value)
>
elementwise_reciprocal(const T1 & z, T2 & y)
{
assert(z.extent(0) == y.extent(0));

using t1_t = typename impl::NativeType<T1>::type;
using t2_t = typename impl::NativeType<T2>::type;
using scalar_t = typename ::pressio::Traits<T1>::scalar_type;

using fnctr_t = ::pressio::ops::impl::VectorReciprocalFunctor<t1_t,t2_t,scalar_t>;
fnctr_t F(impl::get_native(z), impl::get_native(y));
Kokkos::parallel_for(z.extent(0), F);
}

}}//end namespace pressio::ops
#endif // PRESSIOOPS_OPS_KOKKOS_OPS_ELEMENTWISE_RECIPROCAL_HPP_
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
//@HEADER
// ************************************************************************
//
// ops_vector_update_kokkos_functors.hpp
// Pressio
// Copyright 2019
// National Technology & Engineering Solutions of Sandia, LLC (NTESS)
//
// Under the terms of Contract DE-NA0003525 with NTESS, the
// U.S. Government retains certain rights in this software.
//
// Pressio is licensed under BSD-3-Clause terms of use:
//
// 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.
//
// Questions? Contact Francesco Rizzi ([email protected])
//
// ************************************************************************
//@HEADER
*/

#ifndef PRESSIOOPS_OPS_KOKKOS_OPS_VECTOR_RECIPROCAL_KOKKOS_FUNCTOR_HPP_
#define PRESSIOOPS_OPS_KOKKOS_OPS_VECTOR_RECIPROCAL_KOKKOS_FUNCTOR_HPP_

namespace pressio{ namespace ops{ namespace impl{

template <class T1, class T2, class sc_t>
struct VectorReciprocalFunctor {
T1 z_;
T2 y_;

VectorReciprocalFunctor(T1 z, T2 y) : z_(z), y_(y) {}

KOKKOS_INLINE_FUNCTION
void operator()(const int i) const {
y_(i) = static_cast<sc_t>(1) / z_(i);
}
};


}}}//end namespace pressio::ops::impl
#endif // PRESSIOOPS_OPS_KOKKOS_OPS_VECTOR_RECIPROCAL_KOKKOS_FUNCTOR_HPP_
4 changes: 2 additions & 2 deletions tests/ops/ops_eigen_diag.cc
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ TEST(ops_eigen_diag, elementwiseMultiply)
EXPECT_DOUBLE_EQ( y(2), 23.0);
}

TEST(ops_eigen_diag, elementwiseInverse)
TEST(ops_eigen_diag, elementwiseReciprocal)
{
Eigen::MatrixXd M1(3,3);
auto y = pressio::diagonal(M1);
Expand All @@ -407,7 +407,7 @@ TEST(ops_eigen_diag, elementwiseInverse)
auto y1 = 1. / z1;
auto y2 = 1. / z2;

pressio::ops::elementwise_inverse(z, y);
pressio::ops::elementwise_reciprocal(z, y);
EXPECT_DOUBLE_EQ( y(0), y0);
EXPECT_DOUBLE_EQ( y(1), y1);
EXPECT_DOUBLE_EQ( y(2), y2);
Expand Down
4 changes: 2 additions & 2 deletions tests/ops/ops_eigen_span.cc
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ TEST(ops_eigen_span, elementwiseMultiply)
EXPECT_DOUBLE_EQ( y(2), 23.0);
}

TEST(ops_eigen_span, elementwiseInverse)
TEST(ops_eigen_span, elementwiseReciprocal)
{
Eigen::VectorXd M1(6);
auto y = pressio::span(M1,2,3);
Expand All @@ -284,7 +284,7 @@ TEST(ops_eigen_span, elementwiseInverse)
auto y1 = 1. / z1;
auto y2 = 1. / z2;

pressio::ops::elementwise_inverse(z, y);
pressio::ops::elementwise_reciprocal(z, y);
EXPECT_DOUBLE_EQ( y(0), y0);
EXPECT_DOUBLE_EQ( y(1), y1);
EXPECT_DOUBLE_EQ( y(2), y2);
Expand Down
4 changes: 2 additions & 2 deletions tests/ops/ops_eigen_vector.cc
Original file line number Diff line number Diff line change
Expand Up @@ -415,12 +415,12 @@ TEST(ops_eigen_vector, elementwiseMultiply)
EXPECT_DOUBLE_EQ( y(2), 20.0);
}

TEST(ops_eigen_vector, elementwiseInverse)
TEST(ops_eigen_vector, elementwiseReciprocal)
{
V_t y; y << 0.,0.,0.;
V_t z; z << 3.,4.,5.;

pressio::ops::elementwise_inverse(z, y);
pressio::ops::elementwise_reciprocal(z, y);
EXPECT_DOUBLE_EQ( y(0), 1./3.);
EXPECT_DOUBLE_EQ( y(1), 1./4.);
EXPECT_DOUBLE_EQ( y(2), 1./5.);
Expand Down
27 changes: 27 additions & 0 deletions tests/ops/ops_kokkos_diag.cc
Original file line number Diff line number Diff line change
Expand Up @@ -380,3 +380,30 @@ TEST(ops_kokkos_diag, elementwiseMultiply)
EXPECT_DOUBLE_EQ( M1_h(1,1), 14.0);
EXPECT_DOUBLE_EQ( M1_h(2,2), 23.0);
}


TEST(ops_kokkos_diag, elementwiseReciprocal)
{
mat_t M1("M1",3,3);
mat_t M3("M3",3,3);

const auto z0 = 3.;
const auto z1 = 4.;
const auto z2 = 5.;

auto M1_h = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(), M1);
auto M3_h = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(), M3);
M3_h(0,0)=z0; M3_h(1,1)=z1; M3_h(2,2)=z2;

Kokkos::deep_copy(M1, M1_h);
Kokkos::deep_copy(M3, M3_h);

auto y = pressio::diagonal(M1);
const auto z = pressio::diagonal(M3);

pressio::ops::elementwise_reciprocal(z, y);
Kokkos::deep_copy(M1_h, M1);
EXPECT_DOUBLE_EQ( M1_h(0,0), 1 / z0);
EXPECT_DOUBLE_EQ( M1_h(1,1), 1 / z1);
EXPECT_DOUBLE_EQ( M1_h(2,2), 1 / z2);
}
26 changes: 26 additions & 0 deletions tests/ops/ops_kokkos_span.cc
Original file line number Diff line number Diff line change
Expand Up @@ -291,3 +291,29 @@ TEST(ops_kokkos_span, elementwiseMultiply)
EXPECT_DOUBLE_EQ( M1_h(4), 14.0);
EXPECT_DOUBLE_EQ( M1_h(5), 23.0);
}

TEST(ops_kokkos_span, elementwiseReciprocal)
{
vec_t M1("M1",6);
vec_t M3("M3",8);

const auto z0 = 3.;
const auto z1 = 4.;
const auto z2 = 5.;

auto M1_h = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(), M1);
auto M3_h = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(), M3);
M3_h(4)=z0; M3_h(5)=z1; M3_h(6)=z2;

Kokkos::deep_copy(M1, M1_h);
Kokkos::deep_copy(M3, M3_h);

auto y = pressio::span(M1,3,3);
const auto z = pressio::span(M3,4,3);

pressio::ops::elementwise_reciprocal(z, y);
Kokkos::deep_copy(M1_h, M1);
EXPECT_DOUBLE_EQ( M1_h(3), 1 / z0);
EXPECT_DOUBLE_EQ( M1_h(4), 1 / z1);
EXPECT_DOUBLE_EQ( M1_h(5), 1 / z2);
}
23 changes: 23 additions & 0 deletions tests/ops/ops_kokkos_vector.cc
Original file line number Diff line number Diff line change
Expand Up @@ -479,3 +479,26 @@ TEST(ops_kokkos_vector, vector_elementwiseMultiply)
EXPECT_DOUBLE_EQ( y_h(1), 12.0);
EXPECT_DOUBLE_EQ( y_h(2), 20.0);
}

TEST(ops_kokkos_vector, vector_elementwiseReciprocal)
{
Kokkos::View<double*> y("y", 3);
Kokkos::View<double*> z("z", 3);

const auto z0 = 3.;
const auto z1 = 4.;
const auto z2 = 5.;

auto y_h = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(), y);
auto z_h = Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(), z);
z_h(0) = z0; z_h(1) = z1; z_h(2) = z2;

Kokkos::deep_copy(y, y_h);
Kokkos::deep_copy(z, z_h);

pressio::ops::elementwise_reciprocal(z, y);
Kokkos::deep_copy(y_h, y);
EXPECT_DOUBLE_EQ( y_h(0), 1 / z0);
EXPECT_DOUBLE_EQ( y_h(1), 1 / z1);
EXPECT_DOUBLE_EQ( y_h(2), 1 / z2);
}

0 comments on commit c43ed94

Please sign in to comment.