static void exec(LHS &lhs, RHS const &rhs) { if (parallel::has_same_map<D>(lhs.map(), rhs)) { // Maps are same, no communication required. typedef typename distributed_local_block<LHS>::type lhs_local_block_type; typedef typename distributed_local_block<RHS>::type rhs_local_block_type; typedef typename block_traits<lhs_local_block_type>::plain_type lhs_local_storage_type; typedef typename block_traits<rhs_local_block_type>::plain_type rhs_local_storage_type; lhs_local_storage_type lhs_local_block = get_local_block(lhs); rhs_local_storage_type rhs_local_block = get_local_block(rhs); Dispatcher<D, lhs_local_block_type, rhs_local_block_type>::exec(lhs_local_block, rhs_local_block); } else { // Maps are different, fall out to general expression. lhs_view_type lhs_view(lhs); rhs_view_type rhs_view(const_cast<RHS&>(rhs)); parallel::expr(lhs_view, rhs_view); } }
static V<T, typename distributed_local_block<B>::type> exec(V<T, B> v) { typedef typename distributed_local_block<B>::type block_type; typedef typename block_traits<block_type>::plain_type storage_type; storage_type block = get_local_block(v.block()); return V<T, block_type>(block); }
static void exec(BlockT& block, value_type const& val) { typedef typename Distributed_local_block<BlockT>::type local_block_type; typedef typename impl::View_block_storage<local_block_type>::plain_type type; if (block.map().subblock() != no_subblock) { // If get_local_block returns a temporary value, we need to copy it. // Other (if it returns a reference), this captures it. type l_block = get_local_block(block); Block_fill<Dim, local_block_type>::exec(l_block, val); } }
static void exec(LHS &lhs, RHS const &rhs) { if (parallel::has_same_map<D>(lhs.map(), rhs)) { // Maps are same, no communication required. typedef typename distributed_local_block<LHS>::type lhs_local_block_type; typedef typename distributed_local_block<RHS>::type rhs_local_block_type; typedef typename block_traits<lhs_local_block_type>::plain_type lhs_local_storage_type; typedef typename block_traits<rhs_local_block_type>::plain_type rhs_local_storage_type; lhs_local_storage_type lhs_local_block = get_local_block(lhs); rhs_local_storage_type rhs_local_block = get_local_block(rhs); Dispatcher<D, lhs_local_block_type, rhs_local_block_type>::exec(lhs_local_block, rhs_local_block); } else { OVXX_DO_THROW(unimplemented("Expression cannot be reorganized")); } }
static void exec(T& r, Block const& a, OrderT, Int_type<Dim>) { typedef typename Block::value_type VT; T l_r = T(); typedef typename Distributed_local_block<Block>::type local_block_type; typedef typename Block_layout<local_block_type>::order_type order_type; typedef Int_type<Dim> dim_type; typedef ReduceT<VT> reduce_type; typedef typename Block::map_type map_type; dispatch<Op_reduce<ReduceT>, void, typename ReduceT<VT>::result_type&, local_block_type const&, order_type, dim_type> (l_r, get_local_block(a), order_type(), dim_type()); if (!Type_equal<map_type, Global_map<Block::dim> >::value) r = a.map().impl_comm().allreduce(ReduceT<T>::rtype, l_r); else r = l_r; }
static void exec(T& r, Block const& a, OrderT, Int_type<Dim>) { typedef typename Block::value_type VT; T l_r; typedef typename Distributed_local_block<Block>::type local_block_type; typedef typename Block_layout<local_block_type>::order_type order_type; typedef Int_type<Dim> dim_type; typedef Mean_magsq_value<VT> reduce_type; typedef typename Block::map_type map_type; dispatch<Op_reduce<Sum_magsq_value>, void, typename Sum_magsq_value<VT>::result_type&, local_block_type const&, order_type, dim_type> (l_r, get_local_block(a), order_type(), dim_type()); if (!Type_equal<map_type, Global_map<Block::dim> >::value) r = a.map().impl_comm().allreduce(reduce_type::rtype, l_r); else r = l_r; r /= static_cast<typename reduce_type::accum_type>(a.size()); }
local_type local() const { return local_type(get_local_block(in_)); }