Skip to content

Commit

Permalink
Distributed vector/vector dot product implemented
Browse files Browse the repository at this point in the history
- adding distributed_vector facility
- adding locality annotations, more tiling annotation facilities
- adapting transposition to new facilities
  • Loading branch information
hkaiser committed Jul 15, 2019
1 parent 4cba390 commit 63b6d52
Show file tree
Hide file tree
Showing 31 changed files with 1,738 additions and 336 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Expand Up @@ -17,3 +17,5 @@ build*/
.vscode/
cmake-build-*
phylanx.egg-info/
/tests/unit/execution_tree/images
/tests/unit/plugins/controls/images
2 changes: 2 additions & 0 deletions examples/algorithms/lra/lra_csv_distributed.cpp
Expand Up @@ -36,6 +36,7 @@ char const* const read_x_code = R"(block(
annotate_d(
slice(file_read_csv(filepath),
list(row_start, row_stop), list(col_start, col_stop)),
"read_x",
list("tile",
list("rows", row_start, row_stop),
list("columns", col_start, col_stop)
Expand All @@ -53,6 +54,7 @@ char const* const read_y_code = R"(block(
annotate_d(
slice(file_read_csv(filepath),
list(row_start , row_stop), col_stop),
"read_y",
list("tile",
list("rows", row_start, row_stop),
list("columns", col_stop, col_stop+1)
Expand Down
32 changes: 32 additions & 0 deletions phylanx/execution_tree/annotation.hpp
Expand Up @@ -12,6 +12,7 @@

#include <hpx/runtime/serialization/serialization_fwd.hpp>

#include <cstdint>
#include <iosfwd>
#include <string>

Expand Down Expand Up @@ -99,6 +100,10 @@ namespace phylanx { namespace execution_tree
annotation&& data, std::string const& name,
std::string const& codename);

PHYLANX_EXPORT bool get_if(std::string const& key,
execution_tree::annotation& ann, std::string const& name = "",
std::string const& codename = "<unknown>") const;

friend bool operator==(annotation const& lhs, annotation const& rhs)
{
return lhs.data_ == rhs.data_;
Expand All @@ -123,6 +128,33 @@ namespace phylanx { namespace execution_tree
////////////////////////////////////////////////////////////////////////////
PHYLANX_EXPORT std::ostream& operator<<(
std::ostream& os, annotation const& ann);

////////////////////////////////////////////////////////////////////////////
struct annotation_information
{
annotation_information() = default;

PHYLANX_EXPORT annotation_information(
std::string name, std::int64_t generation);

PHYLANX_EXPORT annotation_information(
annotation const& ann, std::string const& name,
std::string const& codename);

PHYLANX_EXPORT std::string generate_name() const;
PHYLANX_EXPORT annotation as_annotation() const;

private:
void extract_from_name();

public:
std::string name_;
std::int64_t generation_ = 0;
};

PHYLANX_EXPORT annotation_information extract_annotation_information(
annotation const& ann, std::string const& name,
std::string const& codename);
}}

#endif
9 changes: 9 additions & 0 deletions phylanx/execution_tree/locality_annotation.hpp
Expand Up @@ -21,9 +21,18 @@ namespace phylanx { namespace execution_tree
struct locality_information
{
PHYLANX_EXPORT locality_information();

locality_information(
std::uint32_t locality_id, std::uint32_t num_localities)
: locality_id_(locality_id)
, num_localities_(num_localities)
{}

PHYLANX_EXPORT locality_information(ir::range const& data,
std::string const& name, std::string const& codename);

PHYLANX_EXPORT execution_tree::annotation as_annotation() const;

std::uint32_t locality_id_;
std::uint32_t num_localities_;
};
Expand Down
9 changes: 6 additions & 3 deletions phylanx/execution_tree/meta_annotation.hpp
Expand Up @@ -17,14 +17,17 @@ namespace phylanx { namespace execution_tree
{
PHYLANX_EXPORT hpx::future<annotation> meta_annotation(
annotation const& locality_ann, annotation&& ann,
std::string const& name, std::string const& codename);
std::string const& ann_name, std::string const& name,
std::string const& codename);

PHYLANX_EXPORT annotation meta_annotation(hpx::launch::sync_policy,
annotation const& locality_ann, annotation&& ann,
std::string const& name, std::string const& codename);
std::string const& ann_name, std::string const& name,
std::string const& codename);

PHYLANX_EXPORT annotation localities_annotation(annotation& locality_ann,
annotation&& ann, std::string const& name, std::string const& codename);
annotation&& ann, annotation_information const& ann_info,
std::string const& name, std::string const& codename);
}}

#endif
Expand Down
12 changes: 11 additions & 1 deletion phylanx/execution_tree/primitives/annotate_primitive.hpp
Expand Up @@ -37,11 +37,21 @@ namespace phylanx { namespace execution_tree { namespace primitives
primitive_arguments_type const& args,
eval_context ctx) const override;

protected:
hpx::future<primitive_argument_type> eval_annotate(
primitive_arguments_type const& operands,
primitive_arguments_type const& args,
eval_context ctx) const;
hpx::future<primitive_argument_type> eval_annotate_d(
primitive_arguments_type const& operands,
primitive_arguments_type const& args,
eval_context ctx) const;

protected:
primitive_argument_type annotate(primitive_argument_type&& target,
ir::range&& args) const;
primitive_argument_type annotate_d(primitive_argument_type&& target,
ir::range&& args) const;
std::string&& name, ir::range&& args) const;

private:
std::string func_name_;
Expand Down
17 changes: 13 additions & 4 deletions phylanx/plugins/dist_matrixops/dist_dot_operation.hpp
Expand Up @@ -10,6 +10,7 @@
#include <phylanx/execution_tree/primitives/base_primitive.hpp>
#include <phylanx/execution_tree/primitives/primitive_component_base.hpp>
#include <phylanx/ir/node_data.hpp>
#include <phylanx/plugins/dist_matrixops/localities_annotation.hpp>

#include <hpx/lcos/future.hpp>

Expand Down Expand Up @@ -51,7 +52,9 @@ namespace phylanx { namespace dist_matrixops { namespace primitives

template <typename T>
execution_tree::primitive_argument_type dot1d1d(
ir::node_data<T>&& lhs, ir::node_data<T>&& rhs) const;
ir::node_data<T>&& lhs, ir::node_data<T>&& rhs,
localities_information const& lhs_localities,
localities_information const& rhs_localities) const;
template <typename T>
execution_tree::primitive_argument_type dot1d2d(
ir::node_data<T>&& lhs, ir::node_data<T>&& rhs) const;
Expand All @@ -62,7 +65,9 @@ namespace phylanx { namespace dist_matrixops { namespace primitives
#endif
template <typename T>
execution_tree::primitive_argument_type dot1d(
ir::node_data<T>&& lhs, ir::node_data<T>&& rhs) const;
ir::node_data<T>&& lhs, ir::node_data<T>&& rhs,
localities_information const& lhs_localities,
localities_information const& rhs_localities) const;
execution_tree::primitive_argument_type dot1d(
execution_tree::primitive_argument_type&&,
execution_tree::primitive_argument_type&&) const;
Expand All @@ -80,7 +85,9 @@ namespace phylanx { namespace dist_matrixops { namespace primitives
#endif
template <typename T>
execution_tree::primitive_argument_type dot2d(
ir::node_data<T>&& lhs, ir::node_data<T>&& rhs) const;
ir::node_data<T>&& lhs, ir::node_data<T>&& rhs,
localities_information const& lhs_localities,
localities_information const& rhs_localities) const;
execution_tree::primitive_argument_type dot2d(
execution_tree::primitive_argument_type&&,
execution_tree::primitive_argument_type&&) const;
Expand All @@ -97,7 +104,9 @@ namespace phylanx { namespace dist_matrixops { namespace primitives
ir::node_data<T>&& lhs, ir::node_data<T>&& rhs) const;
template <typename T>
execution_tree::primitive_argument_type dot3d(
ir::node_data<T>&& lhs, ir::node_data<T>&& rhs) const;
ir::node_data<T>&& lhs, ir::node_data<T>&& rhs,
localities_information const& lhs_localities,
localities_information const& rhs_localities) const;
execution_tree::primitive_argument_type dot3d(
execution_tree::primitive_argument_type&&,
execution_tree::primitive_argument_type&&) const;
Expand Down
134 changes: 123 additions & 11 deletions phylanx/plugins/dist_matrixops/dist_dot_operation_impl.hpp
Expand Up @@ -11,15 +11,19 @@
#include <phylanx/config.hpp>
#include <phylanx/execution_tree/primitives/node_data_helpers.hpp>
#include <phylanx/ir/node_data.hpp>
#include <phylanx/plugins/dist_matrixops/dist_dot_operation.hpp>
#include <phylanx/plugins/common/dot_operation_nd.hpp>
#include <phylanx/plugins/dist_matrixops/dist_dot_operation.hpp>
#include <phylanx/plugins/dist_matrixops/localities_annotation.hpp>
#include <phylanx/util/distributed_vector.hpp>

#include <hpx/collectives/all_reduce.hpp>
#include <hpx/include/lcos.hpp>
#include <hpx/include/naming.hpp>
#include <hpx/include/util.hpp>
#include <hpx/throw_exception.hpp>

#include <cstddef>
#include <functional>
#include <memory>
#include <string>
#include <type_traits>
Expand All @@ -30,6 +34,17 @@
#include <blaze_tensor/Math.h>
#endif

using std_int64_t = std::int64_t;
using std_uint8_t = std::uint8_t;

REGISTER_DISTRIBUTED_VECTOR_DECLARATION(double);
REGISTER_DISTRIBUTED_VECTOR_DECLARATION(std_int64_t);
REGISTER_DISTRIBUTED_VECTOR_DECLARATION(std_uint8_t);

HPX_REGISTER_ALLREDUCE_DECLARATION(double);
HPX_REGISTER_ALLREDUCE_DECLARATION(std_int64_t);
HPX_REGISTER_ALLREDUCE_DECLARATION(std_uint8_t);

///////////////////////////////////////////////////////////////////////////////
namespace phylanx { namespace dist_matrixops { namespace primitives
{
Expand Down Expand Up @@ -67,21 +82,111 @@ namespace phylanx { namespace dist_matrixops { namespace primitives
}
}

///////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
template <typename T>
execution_tree::primitive_argument_type dist_dot_operation::dot1d1d(
ir::node_data<T>&& lhs, ir::node_data<T>&& rhs) const
ir::node_data<T>&& lhs, ir::node_data<T>&& rhs,
localities_information const& lhs_localities,
localities_information const& rhs_localities) const
{
if (lhs.size() != rhs.size())
if (lhs_localities.dimensions() < 1 || rhs_localities.dimensions() < 1)
{
HPX_THROW_EXCEPTION(hpx::bad_parameter,
"dist_dot_operation::dot1d1d",
generate_error_message(
"the operands have incompatible number of dimensions"));
"the operands have incompatible dimensionalities"));
}

if (lhs_localities.size() != rhs_localities.size())
{
HPX_THROW_EXCEPTION(hpx::bad_parameter,
"dist_dot_operation::dot1d1d",
generate_error_message(
"the operands have incompatible size"));
}

// construct a distributed vector object for the rhs
util::distributed_vector<T> rhs_data(
rhs_localities.annotation_.name_, rhs.vector(),
rhs_localities.locality_.num_localities_,
rhs_localities.locality_.locality_id_);

// use the local tile of lhs and calculate the dot product with all
// corresponding tiles of rhs
std::size_t lhs_span_index = 0;
if (!lhs_localities.has_span(0))
{
HPX_ASSERT(lhs_localities.has_span(1));
lhs_span_index = 1;
}

tiling_span const& lhs_span = lhs_localities.get_span(lhs_span_index);

// go over all tiles of rhs vector
T dot_result = T{0};

std::uint32_t loc = 0;
for (auto const& rhs_tile : rhs_localities.tiles_)
{
std::size_t rhs_span_index = 0;
if (!rhs_tile.spans_[0].is_valid())
{
HPX_ASSERT(rhs_tile.spans_[1].is_valid());
rhs_span_index = 1;
}

tiling_span const& rhs_span = rhs_tile.spans_[rhs_span_index];

tiling_span intersection;
if (!intersect(lhs_span, rhs_span, intersection))
{
++loc;
continue;
}

// project global coordinates onto local ones
tiling_span lhs_intersection = lhs_localities.project_coords(
lhs_localities.locality_.locality_id_, lhs_span_index,
intersection);
tiling_span rhs_intersection =
rhs_localities.project_coords(loc, rhs_span_index, intersection);

if (rhs_localities.locality_.locality_id_ == loc)
{
// calculate the dot product with local tile
dot_result += T{blaze::dot(
blaze::subvector(lhs.vector(), lhs_intersection.start_,
lhs_intersection.stop_ - lhs_intersection.start_),
blaze::subvector(*rhs_data, rhs_intersection.start_,
rhs_intersection.stop_ - rhs_intersection.start_))};
}
else
{
// calculate the dot product with remote tile
dot_result += T{blaze::dot(
blaze::subvector(lhs.vector(), lhs_intersection.start_,
lhs_intersection.stop_ - lhs_intersection.start_),
rhs_data.fetch(loc, rhs_intersection.start_,
rhs_intersection.stop_).get())};
}
++loc;
}

// collect overall result if left hand side vector is distributed
if (lhs_localities.locality_.num_localities_ > 1)
{
lhs = hpx::all_reduce(
("all_reduce_" + lhs_localities.annotation_.name_).c_str(),
dot_result, std::plus<T>{},
lhs_localities.locality_.num_localities_, std::size_t(-1),
lhs_localities.locality_.locality_id_)
.get();
}
else
{
lhs = dot_result;
}

// lhs.dimension(0) == rhs.dimension(0)
lhs = T(blaze::dot(lhs.vector(), rhs.vector()));
return execution_tree::primitive_argument_type{std::move(lhs)};
}

Expand Down Expand Up @@ -131,7 +236,9 @@ namespace phylanx { namespace dist_matrixops { namespace primitives
// Case 3: Inner product of a matrix (tensor slice)
template <typename T>
execution_tree::primitive_argument_type dist_dot_operation::dot1d(
ir::node_data<T>&& lhs, ir::node_data<T>&& rhs) const
ir::node_data<T>&& lhs, ir::node_data<T>&& rhs,
localities_information const& lhs_localities,
localities_information const& rhs_localities) const
{
switch (rhs.num_dimensions())
{
Expand All @@ -141,7 +248,8 @@ namespace phylanx { namespace dist_matrixops { namespace primitives

case 1:
// If is_vector(lhs) && is_vector(rhs)
return dot1d1d(std::move(lhs), std::move(rhs));
return dot1d1d(
std::move(lhs), std::move(rhs), lhs_localities, rhs_localities);

case 2:
// If is_vector(lhs) && is_matrix(rhs)
Expand Down Expand Up @@ -226,7 +334,9 @@ namespace phylanx { namespace dist_matrixops { namespace primitives
// Regular matrix multiplication
template <typename T>
execution_tree::primitive_argument_type dist_dot_operation::dot2d(
ir::node_data<T>&& lhs, ir::node_data<T>&& rhs) const
ir::node_data<T>&& lhs, ir::node_data<T>&& rhs,
localities_information const& lhs_localities,
localities_information const& rhs_localities) const
{
switch (rhs.num_dimensions())
{
Expand Down Expand Up @@ -324,7 +434,9 @@ namespace phylanx { namespace dist_matrixops { namespace primitives
// lhs_num_dims == 3
template <typename T>
execution_tree::primitive_argument_type dist_dot_operation::dot3d(
ir::node_data<T>&& lhs, ir::node_data<T>&& rhs) const
ir::node_data<T>&& lhs, ir::node_data<T>&& rhs,
localities_information const& lhs_localities,
localities_information const& rhs_localities) const
{
switch (rhs.num_dimensions())
{
Expand Down

0 comments on commit 63b6d52

Please sign in to comment.