Actions

icon Post
text/html Subscribe
text/html Unsubscribe

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[patch] Support for split-storage of complex by Dense


  • To: VSIPL++ Developers List <vsipl++@xxxxxxxxxxxxxxxx>
  • Subject: [patch] Support for split-storage of complex by Dense
  • From: Jules Bergmann <jules@xxxxxxxxxxxxxxxx>
  • Date: Fri, 03 Feb 2006 12:37:57 -0500

This patch primarily allows dense blocks to store complex data in split format:

 - New configure option: --with-complex=FORMAT
   For example, to store data in split format, '--with-complex=split'
   Right now the default is to use interleaved, i.e.
   '--with-complex=inter'.  However, on the mercury we will want to make
   the default split.

 - New Ext_data_local class that combines aspects of working_view_holder
   (that translates a global view into a local view) and Ext_data
   (that returns a pointer to a local view, potentially rearranging
   the format).  This arrangement avoids a potential extra copy
   and perform memory allocations early.

This patch also: fixes a bug in Histogram::operator(). It should return a view with value-type scalar_i, not with value-type T. (Don, can you double-check that this is correct?)

				-- Jules
Index: ChangeLog
===================================================================
RCS file: /home/cvs/Repository/vpp/ChangeLog,v
retrieving revision 1.393
diff -u -r1.393 ChangeLog
--- ChangeLog	3 Feb 2006 16:01:36 -0000	1.393
+++ ChangeLog	3 Feb 2006 16:46:24 -0000
@@ -1,3 +1,71 @@
+2006-02-03  Jules Bergmann  <jules@xxxxxxxxxxxxxxxx>
+
+	* configure.ac (--with-complex=FORMAT): New option to set complex
+	  format used by dense.
+	* src/vsip/complex.hpp (recttopolar): Avoid using lvalues.
+	* src/vsip/dense.hpp: Use VSIP_IMPL_PREFER_SPLIT_COMPLEX to set
+	  VSIP_IMPL_DENSE_CMPLX_FMT.  Only use Lvalue_proxy is dense block
+	  is split-complex (result of Is_split_block trait).
+	* src/vsip/impl/adjust-layout.hpp: New file, classes to manipulate
+	  layout policies and check for equivalence between them.
+	* src/vsip/impl/block-copy.hpp (Block_fill): Remove separate
+	  template parameter for value being filled, use block::value_type.
+	* src/vsip/impl/block-traits.hpp (Is_split_block): New trait, value
+	  true if block is both Cmplx_split_fmt and has complex value type.
+	* src/vsip/impl/dispatch-assign.hpp: Use Is_split_block, avoid
+	  static cast on vector assignment.
+	* src/vsip/impl/eval-blas.hpp: Check that blocks are interleaved
+	  before dispatching to BLAS.
+	* src/vsip/impl/extdata-local.hpp: New file, extend Ext_data class
+	  to reorganize distributed data to be local.
+	* src/vsip/impl/extdata.hpp (Ext_data::element_type): New typedef,
+	  type of element pointed to by ptr_type.
+	* src/vsip/impl/layout.hpp: Add support for Any_type, used by
+	  adjust-layout.hpp.
+	* src/vsip/impl/par-chain-assign.hpp: Handle assignments with
+	  split-complex.
+	* src/vsip/impl/par-services-mpi.hpp (Chain::stitch): New overload for
+	  pair<void*, void*>.
+	* src/vsip/impl/par-services-none.hpp: Likewise.
+	* src/vsip/impl/signal-conv-ext.hpp: Use Ext_data_local instead
+	  of Working_view_holder.
+	* src/vsip/impl/signal-corr-ext.hpp: Likewise.
+	* src/vsip/impl/signal-fft.hpp (Fft_aligned): Insure block has
+	  Cmpl_inter_fmt.
+	* src/vsip/impl/signal-histo.hpp: Fix return type of operator().
+	* src/vsip/impl/signal-iir.hpp: Use non-lvalue operations.
+	* src/vsip/impl/solver-cholesky.hpp: Insure that internal storage
+	  and Ext_data accesses use Cmplx_inter_fmt.
+	* src/vsip/impl/solver-lu.hpp: Likewise.
+	* src/vsip/impl/solver-qr.hpp: Likewise.
+	* src/vsip/impl/solver-svd.hpp: Likewise.
+	* src/vsip/impl/solver-toepsol.hpp: Likewise.
+	* src/vsip/impl/subblock.hpp: Use storage_type::offset to generalize
+	  offset computation for both split and interleaved.
+	* src/vsip/impl/us-block.hpp: New file, block that layers on top
+	  of a user pointer.  Similar to Dense user-defined storage, but
+	  with control over split/interleaved format, and without admit/
+	  release.
+	* tests/corr-2d.cpp: Fix VERBOSE output on failure.
+	* tests/correlation.cpp: Initialize vsipl object.
+	* tests/dense.cpp: Avoid testing impl_ref if Dense is storing
+	  complex in split-format.
+	* tests/extdata-local.cpp: New file, unit tests for Ext_data_local.
+	* tests/extdata-subviews.cpp: Update to work with split-complex.
+	* tests/lvalue-proxy.cpp: Extend coverage for both operations
+	  and types of values proxied.
+	* tests/solver-cholesky.cpp: Update to work with complex Lvalue_proxys.
+	  Move Is_positive implementation to ...
+	* tests/solver-common.hpp: ... here. 
+	* tests/solver-lu.cpp: Distribute matrices used in checking solver.
+	* tests/solver-qr.cpp: Update to work with complex Lvalue_proxys.
+	* tests/solver-toepsol.cpp: Likewise.
+	* tests/test.hpp (equal): Add cases for comparing two Lvalue_proxy's.
+	* tests/us-block.cpp: New file, unit tests for Us_block.
+	* tests/util.hpp (create_view): Provide default value for map argument.
+	* tests/ref-impl/vector-const.cpp: Avoid assignment from vector of
+	  float to vector int, causes warning.
+
 2006-02-02  Jules Bergmann  <jules@xxxxxxxxxxxxxxxx>
 
 	* src/vsip/impl/lvalue-proxy.hpp: Specialize Lvalue_proxy's of
Index: configure.ac
===================================================================
RCS file: /home/cvs/Repository/vpp/configure.ac,v
retrieving revision 1.78
diff -u -r1.78 configure.ac
--- configure.ac	22 Jan 2006 08:56:22 -0000	1.78
+++ configure.ac	3 Feb 2006 16:46:24 -0000
@@ -1,3 +1,4 @@
+dnl Copyright (c) 2005, 2006 by CodeSourcery, LLC.  All rights reserved.
 dnl
 dnl File:   configure.ac
 dnl Author: Stefan Seefeld
@@ -219,6 +220,15 @@
   ,
   )
 
+# Control default complex storage of library (split vs interleaved)
+AC_ARG_WITH([complex],
+  AS_HELP_STRING([--with-complex=FORMAT],
+                 [Specify FORMAT to use for complex data: either 'split'
+		  or 'interleaved'.  Default is to use preferred
+		  format for system.]),
+  ,
+  )
+
 
 AC_ARG_ENABLE([profile_timer],
   AS_HELP_STRING([--enable-profile-timer=type],
@@ -1350,6 +1360,15 @@
 fi
 
 #
+# Configure complex storage
+#
+if test "$with_complex" == "split"; then
+  AC_DEFINE_UNQUOTED(VSIP_IMPL_PREFER_SPLIT_COMPLEX, 1, [Description])
+else
+  AC_DEFINE_UNQUOTED(VSIP_IMPL_PREFER_SPLIT_COMPLEX, 0, [Description])
+fi
+
+#
 # Configure profile timer
 #
 if test "$enable_profile_timer" == "none"; then
Index: src/vsip/complex.hpp
===================================================================
RCS file: /home/cvs/Repository/vpp/src/vsip/complex.hpp,v
retrieving revision 1.8
diff -u -r1.8 complex.hpp
--- src/vsip/complex.hpp	22 Nov 2005 22:43:46 -0000	1.8
+++ src/vsip/complex.hpp	3 Feb 2006 16:46:24 -0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2005 by CodeSourcery, LLC.  All rights reserved. */
+/* Copyright (c) 2005,2006 by CodeSourcery, LLC.  All rights reserved. */
 
 /** @file    complex.hpp
     @author  Jules Bergmann
@@ -74,7 +74,12 @@
 {
   assert(z.size() == rho.size() && z.size() == theta.size());
   for (index_type i = 0; i < z.size(); i++)
-    recttopolar(z(i), rho(i), theta(i));
+  {
+    // Use abs/arg instead of calling scalar recttopolar because that
+    // would require lvalue_proxy for split-storage.
+    rho.put(i,   abs(z.get(i)));
+    theta.put(i, arg(z.get(i)));
+  }
 }
 
 namespace impl
Index: src/vsip/dense.hpp
===================================================================
RCS file: /home/cvs/Repository/vpp/src/vsip/dense.hpp,v
retrieving revision 1.32
diff -u -r1.32 dense.hpp
--- src/vsip/dense.hpp	12 Jan 2006 05:47:13 -0000	1.32
+++ src/vsip/dense.hpp	3 Feb 2006 16:46:24 -0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2005 by CodeSourcery, LLC.  All rights reserved. */
+/* Copyright (c) 2005,2006 by CodeSourcery, LLC.  All rights reserved. */
 
 /** @file    vsip/dense.hpp
     @author  Jules Bergmann
@@ -26,7 +26,11 @@
 #include <vsip/impl/point.hpp>
 
 /// Complex storage format for dense blocks.
-#define VSIP_IMPL_DENSE_CMPLX_FMT vsip::impl::Cmplx_inter_fmt
+#if VSIP_IMPL_PREFER_SPLIT_COMPLEX
+#  define VSIP_IMPL_DENSE_CMPLX_FMT vsip::impl::Cmplx_split_fmt
+#else
+#  define VSIP_IMPL_DENSE_CMPLX_FMT vsip::impl::Cmplx_inter_fmt
+#endif
 
 
 
@@ -119,6 +123,14 @@
     return this->data_;
   }
 
+  // For scalar types, there is no distinction between interleaved and
+  // split.
+  typename Storage<Cmplx_split_fmt, T>::type as_storage(Cmplx_split_fmt) const
+  {
+    assert(this->format_ == array_format);
+    return this->data_;
+  }
+
   void find(T*& pointer)
   { pointer = this->data_; }
 
@@ -967,11 +979,11 @@
 /// Dense provides direct lvalue accessors via impl_ref.
 
 template <typename BlockT,
-	  typename CmplxFmt = typename BlockT::complex_type>
+	  bool     use_proxy = Is_split_block<BlockT>::value>
 struct Dense_lvalue_factory_type;
 
 template <typename BlockT>
-struct Dense_lvalue_factory_type<BlockT, Cmplx_inter_fmt>
+struct Dense_lvalue_factory_type<BlockT, false>
 {
   typedef True_lvalue_factory<BlockT> type;
   template <typename OtherBlock>
@@ -981,7 +993,7 @@
 };
 
 template <typename BlockT>
-struct Dense_lvalue_factory_type<BlockT, Cmplx_split_fmt>
+struct Dense_lvalue_factory_type<BlockT, true>
 {
   typedef Proxy_lvalue_factory<BlockT> type;
   template <typename OtherBlock>
@@ -1078,7 +1090,7 @@
 	  typename       OrderT>
 void
 assert_local(
-  Dense<Dim, T, OrderT, Local_map> const& block,
+  Dense<Dim, T, OrderT, Local_map> const& /*block*/,
   index_type                              sb)
 {
   assert(sb == 0);
@@ -1230,7 +1242,7 @@
 
 
 /***********************************************************************
-  Definitions - Dense_storage
+  Definitions - Dense_impl
 ***********************************************************************/
 
 template <dimension_type Dim,
Index: src/vsip/impl/adjust-layout.hpp
===================================================================
RCS file: src/vsip/impl/adjust-layout.hpp
diff -N src/vsip/impl/adjust-layout.hpp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/vsip/impl/adjust-layout.hpp	3 Feb 2006 16:46:24 -0000
@@ -0,0 +1,168 @@
+/* Copyright (c) 2006 by CodeSourcery, LLC.  All rights reserved. */
+
+/** @file    vsip/impl/adjust-layout.hpp
+    @author  Jules Bergmann
+    @date    2006-02-02
+    @brief   VSIPL++ Library: Utilities to adjust layout policies.
+*/
+
+#ifndef VSIP_IMPL_ADJUST_LAYOUT_HPP
+#define VSIP_IMPL_ADJUST_LAYOUT_HPP
+
+/***********************************************************************
+  Included Files
+***********************************************************************/
+
+#include <vsip/impl/layout.hpp>
+
+
+
+/***********************************************************************
+  Definitions
+***********************************************************************/
+
+namespace vsip
+{
+
+namespace impl
+{
+
+/// Adjust a type.  If a preferred type is given, use that.  Otherwise
+/// if 'Any_type' is given, use the actual type.
+
+/// Provides:
+///  - type  - typedef with the adjusted type.
+///  - equiv - bool set to true if the preferred and actual types
+///            were equivalent (either the same, or preferred was
+///            'Any_type').
+
+template <typename PreferredT,
+	  typename ActualT>
+struct Adjust_type
+{
+  typedef PreferredT type;
+  static bool const equiv = false;
+};
+
+template <typename ActualT>
+struct Adjust_type<Any_type, ActualT>
+{
+  typedef ActualT type;
+  static bool const equiv = true;
+};
+
+template <typename SameT>
+struct Adjust_type<SameT, SameT>
+{
+  typedef SameT type;
+  static bool const equiv = true;
+};
+
+
+
+/// Variant of Adjust_type for adjusting pack_type's.
+
+/// In particular, adjusts Stride_unknown pack types to something that
+/// can be used to allocate a block.
+
+template <typename PreferredT,
+	  typename ActualT>
+struct Adjust_pack_type
+  : Adjust_type<PreferredT, ActualT>
+{};
+
+template <>
+struct Adjust_pack_type<Any_type, Stride_unknown>
+{
+  typedef Stride_unit_dense type;
+  static bool const equiv = true;
+};
+
+
+
+/// Variant of Adjust_type for adjusting complex_type's.
+
+/// Uses the value type T to determine when the complex_type matters.
+/// In particular, for non-complex value types, the complex_type is
+/// not applicable.
+
+template <typename T,
+	  typename PreferredT,
+	  typename ActualT>
+struct Adjust_complex_type
+{
+  typedef ActualT type;
+  static bool const equiv = true;
+};
+
+template <typename T,
+	  typename PreferredT,
+	  typename ActualT>
+struct Adjust_complex_type<complex<T>, PreferredT, ActualT>
+  : Adjust_type<PreferredT, ActualT>
+{};
+
+
+
+/// Adjust an actual layout policy against a required layout policy.
+
+/// The resulting layout takes its values from the required layout
+/// where it specifies a value, or from the actual layout when the
+/// required layout specifies 'Any_type'.
+
+template <typename T,
+	  typename RequiredLP,
+	  typename ActualLP>
+struct Adjust_layout
+{
+  static dimension_type const dim = RequiredLP::dim;
+
+  typedef typename RequiredLP::order_type   req_order_t;
+  typedef typename RequiredLP::pack_type    req_pack_t;
+  typedef typename RequiredLP::complex_type req_complex_t;
+
+  typedef typename ActualLP::order_type     act_order_t;
+  typedef typename ActualLP::pack_type      act_pack_t;
+  typedef typename ActualLP::complex_type   act_complex_t;
+
+  typedef typename Adjust_type<req_order_t,     act_order_t>::type order_type;
+  typedef typename Adjust_pack_type<req_pack_t, act_pack_t>::type  pack_type;
+
+  typedef typename Adjust_complex_type<T, req_complex_t, act_complex_t>::type
+		complex_type;
+
+  typedef Layout<dim, order_type, pack_type, complex_type> type;
+};
+
+
+
+// Determine if an given layout policy is compatible with a required
+// layout policy.
+
+// The value_type 'T' is used to determine when differences between
+// complex_type matter.
+
+template <typename T,
+	  typename RequiredLP,
+	  typename ActualLP>
+struct Is_layout_compatible
+{
+  typedef typename RequiredLP::order_type   req_order_type;
+  typedef typename RequiredLP::pack_type    req_pack_type;
+  typedef typename RequiredLP::complex_type req_complex_type;
+
+  typedef typename ActualLP::order_type     act_order_type;
+  typedef typename ActualLP::pack_type      act_pack_type;
+  typedef typename ActualLP::complex_type   act_complex_type;
+
+  static bool const value =
+    RequiredLP::dim == ActualLP::dim                     &&
+    Adjust_type<           req_order_type,   act_order_type>::equiv &&
+    Adjust_pack_type<      req_pack_type,    act_pack_type>::equiv  &&
+    Adjust_complex_type<T, req_complex_type, act_complex_type>::equiv;
+};
+
+} // namespace vsip::impl
+} // namespace vsip
+
+#endif // VSIP_IMPL_ADJUST_LAYOUT_HPP
Index: src/vsip/impl/block-copy.hpp
===================================================================
RCS file: /home/cvs/Repository/vpp/src/vsip/impl/block-copy.hpp,v
retrieving revision 1.9
diff -u -r1.9 block-copy.hpp
--- src/vsip/impl/block-copy.hpp	2 Nov 2005 18:44:03 -0000	1.9
+++ src/vsip/impl/block-copy.hpp	3 Feb 2006 16:46:24 -0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2005 by CodeSourcery, LLC.  All rights reserved. */
+/* Copyright (c) 2005, 2006 by CodeSourcery, LLC.  All rights reserved. */
 
 /** @file    vsip/impl/block-copy.hpp
     @author  Jules Bergmann
@@ -83,8 +83,8 @@
 	  typename       OrderT>
 struct Block_fill<Dim, BlockT, OrderT, true>
 {
-  template <typename T>
-  static void exec(BlockT& block, T const& val)
+  typedef typename BlockT::value_type value_type;
+  static void exec(BlockT& block, value_type const& val)
   {
     typedef typename Distributed_local_block<BlockT>::type local_block_type;
     Block_fill<Dim, local_block_type>::exec(get_local_block(block), val);
@@ -95,19 +95,21 @@
 	  typename OrderT>
 struct Block_fill<1, BlockT, OrderT, false>
 {
-  template <typename T>
-  static void exec(BlockT& block, T const& val)
+  typedef typename BlockT::value_type value_type;
+
+  static void exec(BlockT& block, value_type const& val)
   {
     for (index_type i=0; i<block.size(1, 0); ++i)
       block.put(i, val);
   }
 };
 
-template <typename Block>
-struct Block_fill<2, Block, row2_type, false>
+template <typename BlockT>
+struct Block_fill<2, BlockT, row2_type, false>
 {
-  template <typename T>
-  static void exec(Block& block, T const& val)
+  typedef typename BlockT::value_type value_type;
+
+  static void exec(BlockT& block, value_type const& val)
   {
     for (vsip::index_type r=0; r<block.size(2, 0); ++r)
       for (vsip::index_type c=0; c<block.size(2, 1); ++c)
@@ -115,11 +117,12 @@
   }
 };
 
-template <typename Block>
-struct Block_fill<2, Block, col2_type, false>
+template <typename BlockT>
+struct Block_fill<2, BlockT, col2_type, false>
 {
-  template <typename T>
-  static void exec(Block& block, T const& val)
+  typedef typename BlockT::value_type value_type;
+
+  static void exec(BlockT& block, value_type const& val)
   {
     for (vsip::index_type c=0; c<block.size(2, 1); ++c)
       for (vsip::index_type r=0; r<block.size(2, 0); ++r)
Index: src/vsip/impl/block-traits.hpp
===================================================================
RCS file: /home/cvs/Repository/vpp/src/vsip/impl/block-traits.hpp,v
retrieving revision 1.17
diff -u -r1.17 block-traits.hpp
--- src/vsip/impl/block-traits.hpp	18 Jan 2006 12:32:05 -0000	1.17
+++ src/vsip/impl/block-traits.hpp	3 Feb 2006 16:46:24 -0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2005 by CodeSourcery, LLC.  All rights reserved. */
+/* Copyright (c) 2005, 2006 by CodeSourcery, LLC.  All rights reserved. */
 
 /** @file    vsip/impl/block-traits.hpp
     @author  Jules Bergmann
@@ -21,6 +21,7 @@
 
 #include <vsip/impl/refcount.hpp>
 #include <vsip/impl/layout.hpp>
+#include <vsip/impl/metaprogramming.hpp>
 
 
 
@@ -176,6 +177,20 @@
 
 
 
+template <typename BlockT>
+struct Is_split_block
+{
+private:
+  typedef typename Block_layout<BlockT>::complex_type complex_type;
+
+public:
+  static bool const value =
+    Is_complex<typename BlockT::value_type>::value &&
+    Type_equal<complex_type, Cmplx_split_fmt>::value;
+};
+
+
+
 /// Traits class to determine if block is a simple distributed block.
 
 template <typename Block>
Index: src/vsip/impl/dispatch-assign.hpp
===================================================================
RCS file: /home/cvs/Repository/vpp/src/vsip/impl/dispatch-assign.hpp,v
retrieving revision 1.14
diff -u -r1.14 dispatch-assign.hpp
--- src/vsip/impl/dispatch-assign.hpp	11 Jan 2006 16:22:44 -0000	1.14
+++ src/vsip/impl/dispatch-assign.hpp	3 Feb 2006 16:46:24 -0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2005 by CodeSourcery, LLC.  All rights reserved. */
+/* Copyright (c) 2005, 2006 by CodeSourcery, LLC.  All rights reserved. */
 
 /** @file    vsip/impl/dispatch-assign.hpp
     @author  Jules Bergmann
@@ -106,13 +106,8 @@
   static bool const is_rhs_simple = Is_simple_distributed_block<Block2>::value;
   static bool const is_rhs_reorg  = Is_par_reorg_ok<Block2>::value;
 
-  static bool const is_lhs_split  =
-    Type_equal<typename Block_layout<Block1>::complex_type,
-	       Cmplx_split_fmt>::value;
-
-  static bool const is_rhs_split  =
-    Type_equal<typename Block_layout<Block2>::complex_type,
-	       Cmplx_split_fmt>::value;
+  static bool const is_lhs_split  = Is_split_block<Block1>::value;
+  static bool const is_rhs_split  = Is_split_block<Block2>::value;
 
   static int const  lhs_cost      = Ext_data_cost<Block1>::value;
   static int const  rhs_cost      = Ext_data_cost<Block2>::value;
@@ -169,7 +164,7 @@
     {
       while (size--)
       {
-	*ptr1 = static_cast<typename Block1::value_type>(*ptr2);
+	*ptr1 = *ptr2;
 	ptr1 += stride1;
 	ptr2 += stride2;
       }
Index: src/vsip/impl/eval-blas.hpp
===================================================================
RCS file: /home/cvs/Repository/vpp/src/vsip/impl/eval-blas.hpp,v
retrieving revision 1.6
diff -u -r1.6 eval-blas.hpp
--- src/vsip/impl/eval-blas.hpp	11 Jan 2006 16:22:44 -0000	1.6
+++ src/vsip/impl/eval-blas.hpp	3 Feb 2006 16:46:24 -0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2005 by CodeSourcery, LLC.  All rights reserved. */
+/* Copyright (c) 2005, 2006 by CodeSourcery, LLC.  All rights reserved. */
 
 /** @file    vsip/impl/eval-blas.hpp
     @author  Jules Bergmann
@@ -113,7 +113,11 @@
     Type_equal<std::complex<T1>, typename Block2::value_type>::value &&
     // check that direct access is supported
     Ext_data_cost<Block1>::value == 0 &&
-    Ext_data_cost<Block2>::value == 0;
+    Ext_data_cost<Block2>::value == 0 &&
+    // check that format is interleaved.
+    !Is_split_block<Block0>::value &&
+    !Is_split_block<Block1>::value &&
+    !Is_split_block<Block2>::value;
 
   static bool rt_valid(Block0& /*r*/, std::complex<T1> /*alpha*/, 
     Block1 const& a, Block2 const& b)
@@ -191,7 +195,10 @@
     Type_equal<T, typename Block2::value_type>::value &&
     // check that direct access is supported
     Ext_data_cost<Block1>::value == 0 &&
-    Ext_data_cost<Block2>::value == 0;
+    Ext_data_cost<Block2>::value == 0 &&
+    // check that format is interleaved.
+    !Is_split_block<Block1>::value &&
+    !Is_split_block<Block2>::value;
 
   static bool rt_valid(Block1 const&, Block2 const&) { return true; }
 
@@ -229,7 +236,10 @@
     Type_equal<complex<T>, typename Block2::value_type>::value &&
     // check that direct access is supported
     Ext_data_cost<Block1>::value == 0 &&
-    Ext_data_cost<Block2>::value == 0;
+    Ext_data_cost<Block2>::value == 0 &&
+    // check that format is interleaved.
+    !Is_split_block<Block1>::value &&
+    !Is_split_block<Block2>::value;
 
   static bool rt_valid(
     Block1 const&, 
@@ -271,7 +281,11 @@
     Type_equal<T, typename Block2::value_type>::value &&
     // check that direct access is supported
     Ext_data_cost<Block1>::value == 0 &&
-    Ext_data_cost<Block2>::value == 0;
+    Ext_data_cost<Block2>::value == 0 &&
+    // check that format is interleaved.
+    !Is_split_block<Block0>::value &&
+    !Is_split_block<Block1>::value &&
+    !Is_split_block<Block2>::value;
 
   static bool rt_valid(Block0& /*r*/, Block1 const& a, Block2 const& b)
   {
@@ -356,7 +370,11 @@
     Type_equal<T, typename Block2::value_type>::value &&
     // check that direct access is supported
     Ext_data_cost<Block1>::value == 0 &&
-    Ext_data_cost<Block2>::value == 0;
+    Ext_data_cost<Block2>::value == 0 &&
+    // check that format is interleaved.
+    !Is_split_block<Block0>::value &&
+    !Is_split_block<Block1>::value &&
+    !Is_split_block<Block2>::value;
 
   static bool rt_valid(Block0& /*r*/, Block1 const& a, Block2 const& b)
   {
@@ -556,7 +574,11 @@
     // check that direct access is supported
     Ext_data_cost<Block0>::value == 0 &&
     Ext_data_cost<Block1>::value == 0 &&
-    Ext_data_cost<Block2>::value == 0;
+    Ext_data_cost<Block2>::value == 0 &&
+    // check that format is interleaved.
+    !Is_split_block<Block0>::value &&
+    !Is_split_block<Block1>::value &&
+    !Is_split_block<Block2>::value;
 
   static bool rt_valid(Block0&, T1, Block1 const& a, Block2 const& b, T2)
   {
Index: src/vsip/impl/extdata-local.hpp
===================================================================
RCS file: src/vsip/impl/extdata-local.hpp
diff -N src/vsip/impl/extdata-local.hpp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/vsip/impl/extdata-local.hpp	3 Feb 2006 16:46:24 -0000
@@ -0,0 +1,259 @@
+/* Copyright (c) 2006 by CodeSourcery, LLC.  All rights reserved. */
+
+/** @file    vsip/impl/extdata-local.hpp
+    @author  Jules Bergmann
+    @date    2006-01-31
+    @brief   VSIPL++ Library: Direct Data Access.
+
+*/
+
+#ifndef VSIP_IMPL_EXTDATA_LOCAL_HPP
+#define VSIP_IMPL_EXTDATA_LOCAL_HPP
+
+/***********************************************************************
+  Included Files
+***********************************************************************/
+
+#include <vsip/impl/static_assert.hpp>
+#include <vsip/impl/block-copy.hpp>
+#include <vsip/impl/block-traits.hpp>
+#include <vsip/impl/metaprogramming.hpp>
+#include <vsip/impl/layout.hpp>
+#include <vsip/impl/extdata.hpp>
+#include <vsip/impl/working-view.hpp>
+#include <vsip/impl/adjust-layout.hpp>
+#include <vsip/impl/us-block.hpp>
+
+
+
+/***********************************************************************
+  Declarations
+***********************************************************************/
+
+namespace vsip
+{
+
+namespace impl
+{
+
+namespace edl_details
+{
+
+/// Implementation tags for Ext_data local
+
+struct Impl_use_direct; // Use Ext_data directly on block.
+struct Impl_use_local;  // Use Ext_data on get_local_block of block
+struct Impl_remap;      // Use Ext_data on reorganized block.
+
+
+
+/// Choose Ext_data_local implementation tag for a block.
+
+/// Requires:
+///   BLOCKT is a block type to use direct access on,
+///   LP     is the requested layout policy.
+
+template <typename BlockT,
+	  typename LP>
+struct Choose_impl_tag
+{
+  static dimension_type const dim = LP::dim;
+  typedef typename BlockT::value_type                value_type;
+  typedef typename BlockT::map_type                  map_type;
+  typedef typename Block_layout<BlockT>::layout_type actual_LP;
+
+  static bool const local_equiv =
+	Is_layout_compatible<value_type, LP, actual_LP>::value &&
+        Type_equal<Global_map<dim>, map_type>::value;
+
+  static bool const equiv = local_equiv &&
+	Adjust_type<Local_map, map_type>::equiv;
+
+  static bool const is_local = Type_equal<Local_map, map_type>::value;
+
+  typedef typename
+    ITE_Type<is_local, As_type<Impl_use_direct>,
+	     ITE_Type<local_equiv, As_type<Impl_use_local>,
+		      As_type<Impl_remap> > >
+    ::type type;
+};
+
+} // namespace vsip::impl::edl_details
+
+
+
+/// High-level data access class, reorganizes distributed data to
+/// a single local copy.  Provides data access to data stored in
+/// blocks, using an appropriate low-level data interface.
+
+/// Requires:
+///   BLOCK is a block type.
+///   LP is the desired layout policy for the data access.
+///   RP is a reference counting policy.
+///   AT is a data access tag that selects the low-level interface
+///      used to access the data.  By default, Choose_access is used to
+///      select the appropriate access tag for a given block type
+///      BLOCK and layout LP.
+///   IMPLTAG is a tag to choose how block needs to be reorganized,
+///      if at all.
+///
+/// Notes:
+/// [1] Selecting a specific low-level interface is discouraged.
+///     Selecting one that is not compatible with BLOCK will result in
+///     undefined behavior.
+
+template <typename Block,
+	  typename LP      = typename Desired_block_layout<Block>::layout_type,
+	  typename RP      = No_count_policy,
+	  typename AT      = typename Choose_access<Block, LP>::type,
+	  typename ImplTag = typename 
+                             edl_details::Choose_impl_tag<Block, LP>::type>
+class Ext_data_local;
+
+
+
+/// Ext_data_local variant to directly use Ext_data for access to block.
+
+template <typename BlockT,
+	  typename LP,
+	  typename RP,
+	  typename AT>
+class Ext_data_local<BlockT, LP, RP, AT, edl_details::Impl_use_direct>
+  : public Ext_data<BlockT, LP, RP, AT>
+{
+  typedef Ext_data<BlockT, LP, RP, AT> base_type;
+
+  typedef typename base_type::storage_type storage_type;
+  typedef typename base_type::raw_ptr_type raw_ptr_type;
+
+  // Constructor and destructor.
+public:
+  Ext_data_local(BlockT&            block,
+		 sync_action_type   sync,
+		 raw_ptr_type       buffer)
+    : base_type(block, sync, buffer)
+  {}
+
+  Ext_data_local(BlockT const&      block,
+		 sync_action_type   sync,
+		 raw_ptr_type       buffer)
+    : base_type(block, sync, buffer)
+  {}
+
+  ~Ext_data_local() {}
+};
+
+
+
+/// Ext_data_local variant to use Ext_data access on a distributed block's
+/// local block (as returned by get_local_block).
+
+template <typename BlockT,
+	  typename LP,
+	  typename RP,
+	  typename AT>
+class Ext_data_local<BlockT, LP, RP, AT, edl_details::Impl_use_local>
+  : public Ext_data<typename Distributed_local_block<BlockT>::type, LP, RP, AT>
+{
+  typedef typename Distributed_local_block<BlockT>::type local_block_type;
+  typedef Ext_data<local_block_type, LP, RP, AT> base_type;
+
+  typedef typename base_type::storage_type storage_type;
+  typedef typename base_type::raw_ptr_type raw_ptr_type;
+
+  // Constructor and destructor.
+public:
+  Ext_data_local(BlockT&            block,
+		 sync_action_type   sync,
+		 raw_ptr_type       buffer)
+    : base_type(get_local_block(block), sync, buffer)
+  {}
+
+  Ext_data_local(BlockT const&      block,
+		 sync_action_type   sync,
+		 raw_ptr_type       buffer)
+    : base_type(get_local_block(block), sync, buffer)
+  {}
+
+  ~Ext_data_local() {}
+};
+
+
+
+/// Ext_data_local variant to use Ext_data access on a reorganized
+/// copy of the original distributed block.
+
+template <typename BlockT,
+	  typename LP,
+	  typename RP,
+	  typename AT>
+class Ext_data_local<BlockT, LP, RP, AT, edl_details::Impl_remap>
+{
+  static dimension_type const dim = BlockT::dim;
+  typedef typename BlockT::value_type value_type;
+  typedef Us_block<dim, value_type, LP, Local_map> block_type;
+  typedef typename View_of_dim<dim, value_type, block_type>::type view_type;
+
+  typedef typename View_of_dim<dim, value_type, BlockT>::type src_view_type;
+
+  typedef Ext_data<block_type, LP, RP, AT> ext_type;
+
+  typedef typename ext_type::storage_type storage_type;
+  typedef typename ext_type::raw_ptr_type raw_ptr_type;
+
+  // Constructor and destructor.
+public:
+  Ext_data_local(BlockT&            block,
+		 sync_action_type   sync,
+		 raw_ptr_type       buffer)
+    : src_   (block),
+      block_ (block_domain<dim>(block), buffer),
+      view_  (block_),
+      ext_   (block_, sync, buffer),
+      sync_  (sync)
+  {
+    assign_local(view_, src_);
+  }
+
+  Ext_data_local(BlockT const&      block,
+		 sync_action_type   sync,
+		 raw_ptr_type       buffer)
+    : src_   (const_cast<BlockT&>(block)),
+      block_ (block_domain<dim>(block), buffer),
+      view_  (block_),
+      ext_   (block_, sync, buffer),
+      sync_  (sync)
+  {
+    assert(sync != SYNC_OUT && sync != SYNC_INOUT);
+    assign_local(view_, src_);
+  }
+
+  ~Ext_data_local()
+  {
+    if (sync_ & SYNC_OUT)
+      assign_local(src_, view_);
+  }
+
+
+  // Direct data acessors.
+public:
+  raw_ptr_type	data  ()                 { return ext_.data  ();  }
+  stride_type	stride(dimension_type d) { return ext_.stride(d); }
+  length_type	size  (dimension_type d) { return ext_.size  (d); }
+
+  int           cost  ()                 { return ext_.cost(); }
+
+private:
+  src_view_type    src_;
+  block_type       block_;
+  view_type        view_;
+  ext_type         ext_;
+  sync_action_type sync_;
+};
+
+
+
+} // namespace vsip::impl
+} // namespace vsip
+
+#endif // VSIP_IMPL_EXTDATA_LOCAL_HPP
Index: src/vsip/impl/extdata.hpp
===================================================================
RCS file: /home/cvs/Repository/vpp/src/vsip/impl/extdata.hpp,v
retrieving revision 1.16
diff -u -r1.16 extdata.hpp
--- src/vsip/impl/extdata.hpp	28 Nov 2005 16:54:21 -0000	1.16
+++ src/vsip/impl/extdata.hpp	3 Feb 2006 16:46:24 -0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2005 by CodeSourcery, LLC.  All rights reserved. */
+/* Copyright (c) 2005, 2006 by CodeSourcery, LLC.  All rights reserved. */
 
 /** @file    vsip/impl/extdata.hpp
     @author  Jules Bergmann
@@ -667,7 +667,8 @@
   typedef Storage<typename LP::complex_type, typename Block::value_type>
 		storage_type;
 
-  typedef typename storage_type::type raw_ptr_type;
+  typedef typename storage_type::alloc_type element_type;
+  typedef typename storage_type::type       raw_ptr_type;
 
 
   // Compile- and run-time properties.
@@ -730,9 +731,11 @@
   typedef data_access::Low_level_data_access<AT, Block, LP> ext_type;
   typedef typename Block::value_type value_type;
 
-  typedef typename Storage<typename LP::complex_type,
-			   typename Block::value_type>::type
-		raw_ptr_type;
+  typedef Storage<typename LP::complex_type, typename Block::value_type>
+		storage_type;
+
+  typedef typename storage_type::alloc_type element_type;
+  typedef typename storage_type::type       raw_ptr_type;
 
 
   // Compile- and run-time properties.
@@ -745,8 +748,8 @@
   // Constructor and destructor.
 public:
   Persistent_ext_data(Block&             block,
-		    sync_action_type   sync   = SYNC_INOUT,
-		    raw_ptr_type       buffer = NULL)
+		      sync_action_type   sync   = SYNC_INOUT,
+		      raw_ptr_type       buffer = storage_type::null())
     : blk_ (&block),
       ext_ (block, buffer),
       sync_(sync)
Index: src/vsip/impl/layout.hpp
===================================================================
RCS file: /home/cvs/Repository/vpp/src/vsip/impl/layout.hpp,v
retrieving revision 1.16
diff -u -r1.16 layout.hpp
--- src/vsip/impl/layout.hpp	1 Sep 2005 20:02:16 -0000	1.16
+++ src/vsip/impl/layout.hpp	3 Feb 2006 16:46:24 -0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2005 by CodeSourcery, LLC.  All rights reserved. */
+/* Copyright (c) 2005, 2006 by CodeSourcery, LLC.  All rights reserved. */
 
 /** @file    vsip/impl/layout.hpp
     @author  Jules Bergmann
@@ -31,6 +31,8 @@
 namespace impl
 {
 
+struct Any_type;
+
 
 /// Packing Format Tags.
 ///  - Stride_unknown indicates that at compile-time, minor dimension
@@ -90,6 +92,7 @@
 template <typename T>
 struct Valid_pack_type;
 
+template <> struct Valid_pack_type<Any_type> {};
 template <> struct Valid_pack_type<Stride_unit> {};
 template <> struct Valid_pack_type<Stride_unit_dense> {};
 template <> struct Valid_pack_type<Stride_unknown> {};
@@ -102,6 +105,7 @@
 template <typename T>
 struct Valid_complex_fmt;
 
+template <> struct Valid_complex_fmt<Any_type> {};
 template <> struct Valid_complex_fmt<Cmplx_inter_fmt> {};
 template <> struct Valid_complex_fmt<Cmplx_split_fmt> {};
 
@@ -112,6 +116,7 @@
 template <typename T>
 struct Valid_order;
 
+template <> struct Valid_order<Any_type> {};
 template <dimension_type Dim0,
 	  dimension_type Dim1,
 	  dimension_type Dim2>
@@ -119,6 +124,7 @@
 
 
 
+
 /// Layout class encapsulating:
 ///  - Dimension,
 ///  - Dimension ordering,
Index: src/vsip/impl/par-chain-assign.hpp
===================================================================
RCS file: /home/cvs/Repository/vpp/src/vsip/impl/par-chain-assign.hpp,v
retrieving revision 1.15
diff -u -r1.15 par-chain-assign.hpp
--- src/vsip/impl/par-chain-assign.hpp	11 Jan 2006 16:22:45 -0000	1.15
+++ src/vsip/impl/par-chain-assign.hpp	3 Feb 2006 16:46:24 -0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2005 by CodeSourcery, LLC.  All rights reserved. */
+/* Copyright (c) 2005, 2006 by CodeSourcery, LLC.  All rights reserved. */
 
 /** @file    vsip/impl/par-chain-assign.hpp
     @author  Jules Bergmann
@@ -48,12 +48,12 @@
   ExtDataT&            ext,
   Domain<1> const&    dom)
 {
-  typedef typename ExtDataT::value_type value_type;
+  typedef typename ExtDataT::element_type element_type;
 
   dimension_type const dim0 = OrderT::impl_dim0;
   assert(dim0 == 0);
 
-  builder.add<value_type>(sizeof(value_type) * dom.first()*ext.stride(dim0),
+  builder.add<element_type>(sizeof(element_type) * dom.first()*ext.stride(dim0),
 			  dom.stride() * ext.stride(dim0),
 			  dom.length());
 }
@@ -68,13 +68,13 @@
   ExtDataT&            ext,
   Domain<2> const&    dom)
 {
-  typedef typename ExtDataT::value_type value_type;
+  typedef typename ExtDataT::element_type element_type;
 
   dimension_type const dim0 = OrderT::impl_dim0;
   dimension_type const dim1 = OrderT::impl_dim1;
 
-  builder.add<value_type>(
-              sizeof(value_type) * (dom[dim0].first()*ext.stride(dim0) +
+  builder.add<element_type>(
+              sizeof(element_type) * (dom[dim0].first()*ext.stride(dim0) +
 				    dom[dim1].first()*ext.stride(dim1)),
 	      dom[dim0].stride() * ext.stride(dim0), dom[dim0].length(),
 	      dom[dim1].stride() * ext.stride(dim1), dom[dim1].length());
@@ -90,7 +90,7 @@
   ExtDataT&            ext,
   Domain<3> const&    dom)
 {
-  typedef typename ExtDataT::value_type value_type;
+  typedef typename ExtDataT::element_type element_type;
 
   dimension_type const dim0 = OrderT::impl_dim0;
   dimension_type const dim1 = OrderT::impl_dim1;
@@ -98,8 +98,8 @@
 
   for (index_type i = 0; i < dom[dim0].size(); ++i)
   {
-    builder.add<value_type>(
-                sizeof(value_type) *
+    builder.add<element_type>(
+                sizeof(element_type) *
 		  ( (dom[dim0].first()+i*dom[dim0].stride())*ext.stride(dim0)
 		  +  dom[dim1].first()                      *ext.stride(dim1)
 		  +  dom[dim2].first()                      *ext.stride(dim2)),
@@ -166,6 +166,8 @@
 	  typename       Block1,
 	  typename       Block2>
 class Chained_parallel_assign
+  : Compile_time_assert<Is_split_block<Block1>::value ==
+                        Is_split_block<Block2>::value>
 {
   static dimension_type const dim = Dim;
 
@@ -215,18 +217,15 @@
 
   struct Msg_record
   {
-    Msg_record(processor_type proc, index_type sb, void* data,
-	      chain_type chain)
+    Msg_record(processor_type proc, index_type sb, chain_type chain)
       : proc_    (proc),
         subblock_(sb),
-	data_    (data),
 	chain_   (chain)
       {}
 
   public:
     processor_type proc_;    // destination processor
     index_type     subblock_;
-    void*          data_;
     chain_type     chain_;
   };
 
@@ -501,8 +500,7 @@
 	  }
 	}
 	if (!builder.is_empty())
-	  send_list.push_back(Msg_record(proc, src_sb, ext->data(),
-					builder.get_chain()));
+	  send_list.push_back(Msg_record(proc, src_sb, builder.get_chain()));
 	ext->end();
       }
     }
@@ -602,8 +600,7 @@
 	}
       }
       if (!builder.is_empty())
-	recv_list.push_back(Msg_record(proc, dst_sb, ext->data(),
-				      builder.get_chain()));
+	recv_list.push_back(Msg_record(proc, dst_sb, builder.get_chain()));
     }
     ext->end();
   }
Index: src/vsip/impl/par-services-mpi.hpp
===================================================================
RCS file: /home/cvs/Repository/vpp/src/vsip/impl/par-services-mpi.hpp,v
retrieving revision 1.17
diff -u -r1.17 par-services-mpi.hpp
--- src/vsip/impl/par-services-mpi.hpp	11 Jan 2006 16:22:45 -0000	1.17
+++ src/vsip/impl/par-services-mpi.hpp	3 Feb 2006 16:46:24 -0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2005 by CodeSourcery, LLC.  All rights reserved. */
+/* Copyright (c) 2005, 2006 by CodeSourcery, LLC.  All rights reserved. */
 
 /** @file    vsip/impl/par-services-mpi.hpp
     @author  Jules Bergmann
@@ -224,6 +224,12 @@
     types_.push_back(chain);
   }
 
+  void stitch(std::pair<void*,void*> base, MPI_Datatype chain)
+  {
+    stitch(base.first, chain);
+    stitch(base.second, chain);
+  }
+
   bool is_empty() const { return (lengths_.size() == 0); }
 
   // Private member data.
Index: src/vsip/impl/par-services-none.hpp
===================================================================
RCS file: /home/cvs/Repository/vpp/src/vsip/impl/par-services-none.hpp,v
retrieving revision 1.10
diff -u -r1.10 par-services-none.hpp
--- src/vsip/impl/par-services-none.hpp	11 Jan 2006 16:22:45 -0000	1.10
+++ src/vsip/impl/par-services-none.hpp	3 Feb 2006 16:46:24 -0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2005 by CodeSourcery, LLC.  All rights reserved. */
+/* Copyright (c) 2005, 2006 by CodeSourcery, LLC.  All rights reserved. */
 
 /** @file    vsip/impl/par-services-none.hpp
     @author  Jules Bergmann
@@ -81,6 +81,12 @@
   void stitch(void* base, Copy_chain chain)
   { chain_.append_offset(base, chain); }
 
+  void stitch(std::pair<void*, void*> base, Copy_chain chain)
+  {
+    chain_.append_offset(base.first,  chain);
+    chain_.append_offset(base.second, chain);
+  }
+
   bool is_empty() const { return (chain_.size() == 0); }
 
   // Private member data.
Index: src/vsip/impl/signal-conv-ext.hpp
===================================================================
RCS file: /home/cvs/Repository/vpp/src/vsip/impl/signal-conv-ext.hpp,v
retrieving revision 1.9
diff -u -r1.9 signal-conv-ext.hpp
--- src/vsip/impl/signal-conv-ext.hpp	11 Jan 2006 16:22:45 -0000	1.9
+++ src/vsip/impl/signal-conv-ext.hpp	3 Feb 2006 16:46:24 -0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2005 by CodeSourcery, LLC.  All rights reserved. */
+/* Copyright (c) 2005, 2006 by CodeSourcery, LLC.  All rights reserved. */
 
 /** @file    vsip/impl/signal-conv-ext.hpp
     @author  Jules Bergmann
@@ -21,7 +21,7 @@
 #include <vsip/impl/signal-types.hpp>
 #include <vsip/impl/profile.hpp>
 #include <vsip/impl/signal-conv-common.hpp>
-#include <vsip/impl/working-view.hpp>
+#include <vsip/impl/extdata-local.hpp>
 
 
 
@@ -134,6 +134,7 @@
   Domain<dim>     kernel_size_;
   Domain<dim>     input_size_;
   Domain<dim>     output_size_;
+
   T*              in_buffer_;
   T*              out_buffer_;
   T*              tmp_buffer_;
@@ -229,26 +230,11 @@
 void
 Convolution_impl<ConstViewT, Symm, Supp, T, n_times, a_hint, Generic_tag>::
 convolve(
-  const_Vector<T, Block0> a_in,
-  Vector<T, Block1>       a_out)
+  const_Vector<T, Block0> in,
+  Vector<T, Block1>       out)
 VSIP_NOTHROW
 {
-  using vsip::impl::Working_view_holder;
-
-  // PROFILE: Warn if arguments are not entirely on single processor
-  // (either as undistributed views or as local views of distr obj).
-
-  typedef Working_view_holder<const_Vector<T, Block0> > in_work_type;
-  typedef Working_view_holder<      Vector<T, Block1> > out_work_type;
-
-  in_work_type  w_in(a_in);
-  out_work_type w_out(a_out);
-
-  typename in_work_type::type  in  = w_in.view;
-  typename out_work_type::type out = w_out.view;
-
-  typedef typename in_work_type::type::block_type  in_block_type;
-  typedef typename out_work_type::type::block_type out_block_type;
+  using vsip::impl::Any_type;
 
   length_type const M = this->coeff_.size(0);
   length_type const N = this->input_size_[0].size();
@@ -256,8 +242,16 @@
 
   assert(P == out.size());
 
-  typedef vsip::impl::Ext_data<in_block_type> in_ext_type;
-  typedef vsip::impl::Ext_data<out_block_type> out_ext_type;
+  typedef typename Block_layout<Block0>::layout_type LP0;
+  typedef typename Block_layout<Block1>::layout_type LP1;
+
+  typedef Layout<1, Any_type, Any_type, Cmplx_inter_fmt> req_LP;
+
+  typedef typename Adjust_layout<T, req_LP, LP0>::type use_LP0;
+  typedef typename Adjust_layout<T, req_LP, LP1>::type use_LP1;
+
+  typedef vsip::impl::Ext_data_local<Block0, use_LP0>  in_ext_type;
+  typedef vsip::impl::Ext_data_local<Block1, use_LP1> out_ext_type;
 
   in_ext_type  in_ext (in.block(),  vsip::impl::SYNC_IN,  in_buffer_);
   out_ext_type out_ext(out.block(), vsip::impl::SYNC_OUT, out_buffer_);
@@ -300,27 +294,15 @@
 void
 Convolution_impl<ConstViewT, Symm, Supp, T, n_times, a_hint, Generic_tag>::
 convolve(
-  const_Matrix<T, Block0> a_in,
-  Matrix<T, Block1>       a_out)
+  const_Matrix<T, Block0> in,
+  Matrix<T, Block1>       out)
 VSIP_NOTHROW
 {
-  using vsip::impl::Working_view_holder;
+  using vsip::impl::Any_type;
 
   // PROFILE: Warn if arguments are not entirely on single processor
   // (either as undistributed views or as local views of distr obj).
 
-  typedef Working_view_holder<const_Matrix<T, Block0> > in_work_type;
-  typedef Working_view_holder<      Matrix<T, Block1> > out_work_type;
-
-  in_work_type  w_in(a_in);
-  out_work_type w_out(a_out);
-
-  typename in_work_type::type  in  = w_in.view;
-  typename out_work_type::type out = w_out.view;
-
-  typedef typename in_work_type::type::block_type  in_block_type;
-  typedef typename out_work_type::type::block_type out_block_type;
-
   length_type const Mr = this->coeff_.size(0);
   length_type const Mc = this->coeff_.size(1);
 
@@ -332,8 +314,16 @@
 
   assert(Pr == out.size(0) && Pc == out.size(1));
 
-  typedef vsip::impl::Ext_data<in_block_type>  in_ext_type;
-  typedef vsip::impl::Ext_data<out_block_type> out_ext_type;
+  typedef typename Block_layout<Block0>::layout_type LP0;
+  typedef typename Block_layout<Block1>::layout_type LP1;
+
+  typedef Layout<2, Any_type, Any_type, Cmplx_inter_fmt> req_LP;
+
+  typedef typename Adjust_layout<T, req_LP, LP0>::type use_LP0;
+  typedef typename Adjust_layout<T, req_LP, LP1>::type use_LP1;
+
+  typedef vsip::impl::Ext_data_local<Block0, use_LP0>  in_ext_type;
+  typedef vsip::impl::Ext_data_local<Block1, use_LP1> out_ext_type;
 
   in_ext_type  in_ext (in.block(),  vsip::impl::SYNC_IN,  in_buffer_);
   out_ext_type out_ext(out.block(), vsip::impl::SYNC_OUT, out_buffer_);
Index: src/vsip/impl/signal-corr-ext.hpp
===================================================================
RCS file: /home/cvs/Repository/vpp/src/vsip/impl/signal-corr-ext.hpp,v
retrieving revision 1.2
diff -u -r1.2 signal-corr-ext.hpp
--- src/vsip/impl/signal-corr-ext.hpp	12 Dec 2005 17:47:50 -0000	1.2
+++ src/vsip/impl/signal-corr-ext.hpp	3 Feb 2006 16:46:24 -0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2005 by CodeSourcery, LLC.  All rights reserved. */
+/* Copyright (c) 2005, 2006 by CodeSourcery, LLC.  All rights reserved. */
 
 /** @file    vsip/impl/signal-corr-ext.hpp
     @author  Jules Bergmann
@@ -22,6 +22,7 @@
 #include <vsip/impl/profile.hpp>
 #include <vsip/impl/signal-conv-common.hpp>
 #include <vsip/impl/signal-corr-common.hpp>
+#include <vsip/impl/extdata-local.hpp>
 
 
 
@@ -215,9 +216,22 @@
   assert(N == in.size());
   assert(P == out.size());
 
-  typedef vsip::impl::Ext_data<Block0> ref_ext_type;
-  typedef vsip::impl::Ext_data<Block1> in_ext_type;
-  typedef vsip::impl::Ext_data<Block2> out_ext_type;
+  // PROFILE: Warn if arguments are not entirely on single processor
+  // (either as undistributed views or as local views of distr obj).
+
+  typedef typename Block_layout<Block0>::layout_type LP0;
+  typedef typename Block_layout<Block1>::layout_type LP1;
+  typedef typename Block_layout<Block2>::layout_type LP2;
+
+  typedef Layout<1, Any_type, Any_type, Cmplx_inter_fmt> req_LP;
+
+  typedef typename Adjust_layout<T, req_LP, LP0>::type use_LP0;
+  typedef typename Adjust_layout<T, req_LP, LP1>::type use_LP1;
+  typedef typename Adjust_layout<T, req_LP, LP2>::type use_LP2;
+
+  typedef vsip::impl::Ext_data_local<Block0, use_LP0> ref_ext_type;
+  typedef vsip::impl::Ext_data_local<Block1, use_LP1>  in_ext_type;
+  typedef vsip::impl::Ext_data_local<Block2, use_LP2> out_ext_type;
 
   ref_ext_type ref_ext(ref.block(), vsip::impl::SYNC_IN,  ref_buffer_);
   in_ext_type  in_ext (in.block(),  vsip::impl::SYNC_IN,  in_buffer_);
@@ -270,6 +284,8 @@
   Matrix<T, Block2>       out)
 VSIP_NOTHROW
 {
+  using vsip::impl::Any_type;
+
   length_type const Mr = this->ref_size_[0].size();
   length_type const Mc = this->ref_size_[1].size();
   length_type const Nr = this->input_size_[0].size();
@@ -284,9 +300,22 @@
   assert(Pr == out.size(0));
   assert(Pc == out.size(1));
 
-  typedef vsip::impl::Ext_data<Block0> ref_ext_type;
-  typedef vsip::impl::Ext_data<Block1> in_ext_type;
-  typedef vsip::impl::Ext_data<Block2> out_ext_type;
+  // PROFILE: Warn if arguments are not entirely on single processor
+  // (either as undistributed views or as local views of distr obj).
+
+  typedef typename Block_layout<Block0>::layout_type LP0;
+  typedef typename Block_layout<Block1>::layout_type LP1;
+  typedef typename Block_layout<Block2>::layout_type LP2;
+
+  typedef Layout<2, Any_type, Any_type, Cmplx_inter_fmt> req_LP;
+
+  typedef typename Adjust_layout<T, req_LP, LP0>::type use_LP0;
+  typedef typename Adjust_layout<T, req_LP, LP1>::type use_LP1;
+  typedef typename Adjust_layout<T, req_LP, LP2>::type use_LP2;
+
+  typedef vsip::impl::Ext_data_local<Block0, use_LP0> ref_ext_type;
+  typedef vsip::impl::Ext_data_local<Block1, use_LP1>  in_ext_type;
+  typedef vsip::impl::Ext_data_local<Block2, use_LP2> out_ext_type;
 
   ref_ext_type ref_ext(ref.block(), vsip::impl::SYNC_IN,  ref_buffer_);
   in_ext_type  in_ext (in.block(),  vsip::impl::SYNC_IN,  in_buffer_);
Index: src/vsip/impl/signal-fft.hpp
===================================================================
RCS file: /home/cvs/Repository/vpp/src/vsip/impl/signal-fft.hpp,v
retrieving revision 1.28
diff -u -r1.28 signal-fft.hpp
--- src/vsip/impl/signal-fft.hpp	29 Sep 2005 02:01:10 -0000	1.28
+++ src/vsip/impl/signal-fft.hpp	3 Feb 2006 16:46:24 -0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2005 by CodeSourcery, LLC.  All rights reserved. */
+/* Copyright (c) 2005, 2006 by CodeSourcery, LLC.  All rights reserved. */
 
 /** @file    vsip/impl/signal-fft.hpp
     @author  Nathan Myers
@@ -159,24 +159,19 @@
 struct Fft_aligned
 {
   typedef typename
-#if 1
-    vsip::Dense<Dim,T,vsip::tuple<0,1,2>,Map_type>
-#else
-
-    // Need to use the correct stride (to get to the next
-    // row/column) given the padding before we can use Fast_block 
-    // for FFTs.  This will require making the interface to the
-    // FFT engines a little more complicated.
-
     impl::Fast_block<
-      Dim,T, 
+      Dim, T,
       impl::Layout<
-	Dim,vsip::tuple<0,1,2>,
-        impl::Stride_unit_align<16>,impl::Cmplx_inter_fmt>,
+	Dim, vsip::tuple<0,1,2>,
+        impl::Stride_unit_dense, impl::Cmplx_inter_fmt>,
       Map_type>
-#endif
     block_type;
 
+    // Need to use the correct stride (to get to the next
+    // row/column) given the padding before we can use Stride_unit_align<16> 
+    // for FFTs.  This will require making the interface to the
+    // FFT engines a little more complicated.
+
   typedef typename impl::View_of_dim<Dim, T, block_type>::type
     view_type;
 };
Index: src/vsip/impl/signal-histo.hpp
===================================================================
RCS file: /home/cvs/Repository/vpp/src/vsip/impl/signal-histo.hpp,v
retrieving revision 1.1
diff -u -r1.1 signal-histo.hpp
--- src/vsip/impl/signal-histo.hpp	6 Dec 2005 00:58:40 -0000	1.1
+++ src/vsip/impl/signal-histo.hpp	3 Feb 2006 16:46:24 -0000
@@ -55,7 +55,7 @@
 
   // Histogram operators [signal.histo.operators]
   template <typename Block>
-  const_Vector<T>
+  const_Vector<scalar_i>
   operator()(
     const_Vector<T, Block> data,
     bool accumulate = false)
@@ -71,7 +71,7 @@
     }
 
   template <typename Block>
-  const_Vector<T>
+  const_Vector<scalar_i>
   operator()(
     const_Matrix<T, Block> data,
     bool accumulate = false)
@@ -104,7 +104,7 @@
   T max_;
   T delta_;
   length_type const num_bin_;
-  Vector<T> hist_;
+  Vector<scalar_i> hist_;
 };
 
 
Index: src/vsip/impl/signal-iir.hpp
===================================================================
RCS file: /home/cvs/Repository/vpp/src/vsip/impl/signal-iir.hpp,v
retrieving revision 1.1
diff -u -r1.1 signal-iir.hpp
--- src/vsip/impl/signal-iir.hpp	20 Dec 2005 03:01:32 -0000	1.1
+++ src/vsip/impl/signal-iir.hpp	3 Feb 2006 16:46:24 -0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2005 by CodeSourcery, LLC.  All rights reserved. */
+/* Copyright (c) 2005, 2006 by CodeSourcery, LLC.  All rights reserved. */
 
 /** @file    vsip/impl/signal-iir.hpp
     @author  Jules Bergmann
@@ -195,18 +195,18 @@
     for (index_type m=0; m<M; ++m)
     {
       T w0 = val
-           - a_(m, A1) * w_(m, W1)
-           - a_(m, A2) * w_(m, W2);
+	   - a_.get(m, A1) * w_.get(m, W1)
+           - a_.get(m, A2) * w_.get(m, W2);
 
-      val  = b_(m, B0) * w0
-           + b_(m, B1) * w_(m, W1)
-           + b_(m, B2) * w_(m, W2);
+      val  = b_.get(m, B0) * w0
+           + b_.get(m, B1) * w_.get(m, W1)
+           + b_.get(m, B2) * w_.get(m, W2);
 
-      w_(m, W2) = w_(m, W1);
-      w_(m, W1) = w0;
+      w_.put(m, W2, w_.get(m, W1));
+      w_.put(m, W1, w0);
     }
 
-    out(i) = val;
+    out.put(i, val);
   }
 
   if (c_f == state_no_save)
Index: src/vsip/impl/solver-cholesky.hpp
===================================================================
RCS file: /home/cvs/Repository/vpp/src/vsip/impl/solver-cholesky.hpp,v
retrieving revision 1.2
diff -u -r1.2 solver-cholesky.hpp
--- src/vsip/impl/solver-cholesky.hpp	30 Sep 2005 21:43:07 -0000	1.2
+++ src/vsip/impl/solver-cholesky.hpp	3 Feb 2006 16:46:24 -0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2005 by CodeSourcery, LLC.  All rights reserved. */
+/* Copyright (c) 2005, 2006 by CodeSourcery, LLC.  All rights reserved. */
 
 /** @file    vsip/impl/solver-cholesky.hpp
     @author  Jules Bergmann
@@ -47,7 +47,9 @@
 class Chold_impl
   : Compile_time_assert<blas::Blas_traits<T>::valid>
 {
-  typedef Dense<2, T, col2_type> data_block_type;
+  // BLAS/LAPACK require complex data to be in interleaved format.
+  typedef Layout<2, col2_type, Stride_unit_dense, Cmplx_inter_fmt> data_LP;
+  typedef Fast_block<2, T, data_LP> data_block_type;
 
   // Constructors, copies, assignments, and destructors.
 public:
@@ -240,12 +242,12 @@
   assert(b.size(0) == length_);
   assert(b.size(0) == x.size(0) && b.size(1) == x.size(1));
 
-  Matrix<T, Dense<2, T, col2_type> > b_int(b.size(0), b.size(1));
+  Matrix<T, data_block_type> b_int(b.size(0), b.size(1));
   b_int = b;
 
   {
-    Ext_data<Dense<2, T, col2_type> > b_ext(b_int.block());
-    Ext_data<data_block_type>         a_ext(data_.block());
+    Ext_data<data_block_type> b_ext(b_int.block());
+    Ext_data<data_block_type> a_ext(data_.block());
 
     lapack::potrs(uplo_ == upper ? 'U' : 'L',
 		  length_,
Index: src/vsip/impl/solver-lu.hpp
===================================================================
RCS file: /home/cvs/Repository/vpp/src/vsip/impl/solver-lu.hpp,v
retrieving revision 1.2
diff -u -r1.2 solver-lu.hpp
--- src/vsip/impl/solver-lu.hpp	11 Jan 2006 16:22:45 -0000	1.2
+++ src/vsip/impl/solver-lu.hpp	3 Feb 2006 16:46:24 -0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2005 by CodeSourcery, LLC.  All rights reserved. */
+/* Copyright (c) 2005, 2006 by CodeSourcery, LLC.  All rights reserved. */
 
 /** @file    vsip/impl/solver-lu.hpp
     @author  Jules Bergmann
@@ -41,7 +41,9 @@
 class Lud_impl
   : Compile_time_assert<blas::Blas_traits<T>::valid>
 {
-  typedef Dense<2, T, col2_type> data_block_type;
+  // BLAS/LAPACK require complex data to be in interleaved format.
+  typedef Layout<2, col2_type, Stride_unit_dense, Cmplx_inter_fmt> data_LP;
+  typedef Fast_block<2, T, data_LP> data_block_type;
 
   // Constructors, copies, assignments, and destructors.
 public:
@@ -256,7 +258,7 @@
 
   char trans;
 
-  Matrix<T, Dense<2, T, col2_type> > b_int(b.size(0), b.size(1));
+  Matrix<T, data_block_type> b_int(b.size(0), b.size(1));
   assign_local(b_int, b);
 
   if (tr == mat_ntrans)
@@ -270,8 +272,8 @@
   }
 
   {
-    Ext_data<Dense<2, T, col2_type> > b_ext(b_int.block());
-    Ext_data<data_block_type>         a_ext(data_.block());
+    Ext_data<data_block_type> b_ext(b_int.block());
+    Ext_data<data_block_type> a_ext(data_.block());
 
     lapack::getrs(trans,
 		  length_,			  // order of A
Index: src/vsip/impl/solver-qr.hpp
===================================================================
RCS file: /home/cvs/Repository/vpp/src/vsip/impl/solver-qr.hpp,v
retrieving revision 1.4
diff -u -r1.4 solver-qr.hpp
--- src/vsip/impl/solver-qr.hpp	11 Jan 2006 16:22:45 -0000	1.4
+++ src/vsip/impl/solver-qr.hpp	3 Feb 2006 16:46:24 -0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2005 by CodeSourcery, LLC.  All rights reserved. */
+/* Copyright (c) 2005, 2006 by CodeSourcery, LLC.  All rights reserved. */
 
 /** @file    vsip/impl/solver-qr.hpp
     @author  Jules Bergmann
@@ -44,7 +44,9 @@
 class Qrd_impl
   : Compile_time_assert<blas::Blas_traits<T>::valid>
 {
-  typedef Dense<2, T, col2_type> data_block_type;
+  // BLAS/LAPACK require complex data to be in interleaved format.
+  typedef Layout<2, col2_type, Stride_unit_dense, Cmplx_inter_fmt> data_LP;
+  typedef Fast_block<2, T, data_LP> data_block_type;
 
   // Constructors, copies, assignments, and destructors.
 public:
@@ -412,7 +414,7 @@
     mqr_lwork = b.size(0);
   }
 
-  Matrix<T, Dense<2, T, col2_type> > b_int(b.size(0), b.size(1));
+  Matrix<T, data_block_type> b_int(b.size(0), b.size(1));
   assign_local(b_int, b);
 
   int blksize   = lapack::mqr_blksize<T>(side, trans,
@@ -421,8 +423,8 @@
   Temp_buffer<T> mqr_work(mqr_lwork);
 
   {
-    Ext_data<Dense<2, T, col2_type> > b_ext(b_int.block());
-    Ext_data<data_block_type>         a_ext(data_.block());
+    Ext_data<data_block_type> b_ext(b_int.block());
+    Ext_data<data_block_type> a_ext(data_.block());
 
     lapack::mqr(side,
 		trans,
@@ -476,13 +478,13 @@
     break;
   }
 
-  Matrix<T, Dense<2, T, col2_type> > b_int(b.size(0), b.size(1));
+  Matrix<T, data_block_type> b_int(b.size(0), b.size(1));
   assign_local(b_int, b);
   
 
   {
-    Ext_data<data_block_type>         a_ext(data_.block());
-    Ext_data<Dense<2, T, col2_type> > b_ext(b_int.block());
+    Ext_data<data_block_type> a_ext(data_.block());
+    Ext_data<data_block_type> b_ext(b_int.block());
       
     blas::trsm('l',		// R appears on [l]eft-side
 	       'u',		// R is [u]pper-triangular
@@ -523,12 +525,12 @@
   // First solve:    R' b_1 = b
   // Then solve:     R x = b_1
 
-  Matrix<T, Dense<2, T, col2_type> > b_int(b_rows, b_cols);
+  Matrix<T, data_block_type> b_int(b_rows, b_cols);
   assign_local(b_int, b);
 
   {
-    Ext_data<Dense<2, T, col2_type> > b_ext(b_int.block());
-    Ext_data<data_block_type>         a_ext(data_.block());
+    Ext_data<data_block_type> b_ext(b_int.block());
+    Ext_data<data_block_type> a_ext(data_.block());
 
     // First solve: R' b_1 = b
 
@@ -594,12 +596,12 @@
   // 1. compute C = Q'B:     R X = C
   // 2. solve for X:         R X = C
 
-  Matrix<T, Dense<2, T, col2_type> > c(c_rows, c_cols);
+  Matrix<T, data_block_type> c(c_rows, c_cols);
   assign_local(c, b);
 
   {
-    Ext_data<Dense<2, T, col2_type> > c_ext(c.block());
-    Ext_data<data_block_type>         a_ext(data_.block());
+    Ext_data<data_block_type> c_ext(c.block());
+    Ext_data<data_block_type> a_ext(data_.block());
 
     // 1. compute C = Q'B:     R X = C
 
Index: src/vsip/impl/solver-svd.hpp
===================================================================
RCS file: /home/cvs/Repository/vpp/src/vsip/impl/solver-svd.hpp,v
retrieving revision 1.2
diff -u -r1.2 solver-svd.hpp
--- src/vsip/impl/solver-svd.hpp	11 Jan 2006 16:22:45 -0000	1.2
+++ src/vsip/impl/solver-svd.hpp	3 Feb 2006 16:46:24 -0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2005 by CodeSourcery, LLC.  All rights reserved. */
+/* Copyright (c) 2005, 2006 by CodeSourcery, LLC.  All rights reserved. */
 
 /** @file    vsip/impl/solver-svd.hpp
     @author  Jules Bergmann
@@ -43,7 +43,9 @@
 class Svd_impl
   : Compile_time_assert<blas::Blas_traits<T>::valid>
 {
-  typedef Dense<2, T, col2_type> data_block_type;
+  // BLAS/LAPACK require complex data to be in interleaved format.
+  typedef Layout<2, col2_type, Stride_unit_dense, Cmplx_inter_fmt> data_LP;
+  typedef Fast_block<2, T, data_LP> data_block_type;
 
   // Constructors, copies, assignments, and destructors.
 public:
Index: src/vsip/impl/solver-toepsol.hpp
===================================================================
RCS file: /home/cvs/Repository/vpp/src/vsip/impl/solver-toepsol.hpp,v
retrieving revision 1.1
diff -u -r1.1 solver-toepsol.hpp
--- src/vsip/impl/solver-toepsol.hpp	30 Sep 2005 15:19:16 -0000	1.1
+++ src/vsip/impl/solver-toepsol.hpp	3 Feb 2006 16:46:24 -0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2005 by CodeSourcery, LLC.  All rights reserved. */
+/* Copyright (c) 2005, 2006 by CodeSourcery, LLC.  All rights reserved. */
 
 /** @file    vsip/impl/solver-svd.hpp
     @author  Jules Bergmann
@@ -78,14 +78,14 @@
   Vector<T> tmpv(n);
 
   scalar_type beta  = 1.0;
-  scalar_type scale = impl::impl_real(t(0));
-  T           alpha = impl::impl_conj(-r(0)/scale);
+  scalar_type scale = impl::impl_real(t.get(0));
+  T           alpha = impl::impl_conj(-r.get(0)/scale);
   T           tmps; 
   
-  alpha = impl::impl_conj(-r(0)/scale);
+  alpha = impl::impl_conj(-r.get(0)/scale);
   
-  y(0) = alpha;
-  x(0) = b(0) / scale;
+  y.put(0, alpha);
+  x.put(0, b.get(0) / scale);
 
   for (index_type k=1; k<n; ++k)
   {
@@ -96,22 +96,22 @@
     } 
 
     tmps = dot(impl_conj(r(Domain<1>(k))), x(Domain<1>(k-1, -1, k)));
-    T mu = (b(k) - tmps) / (scale*beta);
+    T mu = (b.get(k) - tmps) / (scale*beta);
 
     // x(Domain<1>(k)) += mu * impl_conj(y(Domain<1>(k-1, -1, k)));
     x(Domain<1>(k)) = mu * impl_conj(y(Domain<1>(k-1, -1, k)))
                     + x(Domain<1>(k));
-    x(k) = mu;
+    x.put(k, mu);
 
     if (k < (n - 1))
     {
       tmps  = dot(impl_conj(r(Domain<1>(k))), y(Domain<1>(k-1, -1, k)));
-      alpha = -(tmps + impl::impl_conj(r(k))) / (scale*beta);
+      alpha = -(tmps + impl::impl_conj(r.get(k))) / (scale*beta);
       
       tmpv(Domain<1>(k)) = alpha * impl_conj(y(Domain<1>(k-1, -1, k))) 
 	                 + y(Domain<1>(k));
       y(Domain<1>(k)) = tmpv(Domain<1>(k));
-      y(k) = alpha;
+      y.put(k, alpha);
     }
   }
 
Index: src/vsip/impl/subblock.hpp
===================================================================
RCS file: /home/cvs/Repository/vpp/src/vsip/impl/subblock.hpp,v
retrieving revision 1.37
diff -u -r1.37 subblock.hpp
--- src/vsip/impl/subblock.hpp	5 Dec 2005 19:19:19 -0000	1.37
+++ src/vsip/impl/subblock.hpp	3 Feb 2006 16:46:24 -0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2005 by CodeSourcery, LLC.  All rights reserved. */
+/* Copyright (c) 2005, 2006 by CodeSourcery, LLC.  All rights reserved. */
 
 /** @file    vsip/impl/subblock.hpp
     @author  Zack Weinberg
@@ -852,9 +852,15 @@
   typedef typename storage_type::const_type const_data_type;
 
   data_type       impl_data()       VSIP_NOTHROW
-  { return blk_->impl_data() + index_*blk_->impl_stride(Block::dim, D); }
+  {
+    return storage_type::offset(blk_->impl_data(),
+				index_*blk_->impl_stride(Block::dim, D));
+  }
   const_data_type impl_data() const VSIP_NOTHROW
-  { return blk_->impl_data() + index_*blk_->impl_stride(Block::dim, D); }
+  {
+    return storage_type::offset(blk_->impl_data(),
+				index_*blk_->impl_stride(Block::dim, D));
+  }
   stride_type impl_stride(dimension_type Dim, dimension_type d)
      const VSIP_NOTHROW
   {
@@ -1032,14 +1038,16 @@
 
   data_type       impl_data()       VSIP_NOTHROW
   {
-    return blk_->impl_data() + index1_*blk_->impl_stride(Block::dim, D1)
-                             + index2_*blk_->impl_stride(Block::dim, D2);
+    return storage_type::offset(blk_->impl_data(),
+				+ index1_*blk_->impl_stride(Block::dim, D1)
+				+ index2_*blk_->impl_stride(Block::dim, D2));
   }
 
   const_data_type impl_data() const VSIP_NOTHROW
   {
-    return blk_->impl_data() + index1_*blk_->impl_stride(Block::dim, D1)
-                             + index2_*blk_->impl_stride(Block::dim, D2);
+    return storage_type::offset(blk_->impl_data()
+				+ index1_*blk_->impl_stride(Block::dim, D1)
+				+ index2_*blk_->impl_stride(Block::dim, D2));
   }
 
   stride_type impl_stride(dimension_type Dim, dimension_type d)
@@ -1585,9 +1593,13 @@
   data_type       impl_data()       VSIP_NOTHROW
     { 
       if ( this->offset_ >= 0 )
-        return this->blk_->impl_data() + this->offset_ * this->blk_->impl_stride(2, 1);
+        return storage_type::offset(
+		this->blk_->impl_data(),
+		+ this->offset_ * this->blk_->impl_stride(2, 1));
       else
-        return this->blk_->impl_data() - this->offset_ * this->blk_->impl_stride(2, 0);
+        return storage_type::offset(
+		this->blk_->impl_data(),
+		- this->offset_ * this->blk_->impl_stride(2, 0));
     }
 
   const_data_type impl_data() const VSIP_NOTHROW
Index: src/vsip/impl/us-block.hpp
===================================================================
RCS file: src/vsip/impl/us-block.hpp
diff -N src/vsip/impl/us-block.hpp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/vsip/impl/us-block.hpp	3 Feb 2006 16:46:24 -0000
@@ -0,0 +1,420 @@
+/* Copyright (c) 2006 by CodeSourcery, LLC.  All rights reserved. */
+
+/** @file    vsip/impl/us-block.hpp
+    @author  Jules Bergmann
+    @date    2006-01-31
+    @brief   VSIPL++ Library: User-storage block class.
+
+*/
+
+#ifndef VSIP_IMPL_US_BLOCK_HPP
+#define VSIP_IMPL_US_BLOCK_HPP
+
+/***********************************************************************
+  Included Files
+***********************************************************************/
+
+#include <vsip/support.hpp>
+#include <vsip/domain.hpp>
+#include <vsip/impl/refcount.hpp>
+#include <vsip/impl/local_map.hpp>
+#include <vsip/impl/layout.hpp>
+#include <vsip/impl/extdata.hpp>
+#include <vsip/impl/block-traits.hpp>
+
+
+
+/***********************************************************************
+  Declarations
+***********************************************************************/
+
+namespace vsip
+{
+
+namespace impl
+{ 
+
+template <dimension_type Dim,
+	  typename       T,
+	  typename       LayoutT = Layout<Dim, 
+					  typename impl::Row_major<Dim>::type,
+					  Stride_unit_dense,
+					  Cmplx_inter_fmt>,
+	  typename       MapT = Local_map>
+class Us_block
+  : impl::Non_copyable,
+    public impl::Ref_count<Us_block<Dim, T, LayoutT, MapT> >
+{
+  // Compile-time values and types.
+public:
+  static dimension_type const dim = Dim;
+
+  typedef T        value_type;
+  typedef T&       reference_type;
+  typedef T const& const_reference_type;
+
+  typedef typename LayoutT::order_type order_type;
+  typedef MapT                         map_type;
+
+  // Enable Direct_data access to data.
+  template <typename, typename, typename>
+  friend class impl::data_access::Low_level_data_access;
+
+  // Implementation types.
+public:
+  typedef LayoutT                                    layout_type;
+  typedef impl::Applied_layout<layout_type>          applied_layout_type;
+  typedef Storage<typename LayoutT::complex_type, T> storage_type;
+
+  // Constructors and destructor.
+public:
+  Us_block(Domain<Dim> const&          dom,
+	   typename storage_type::type ptr,
+	   MapT const&                 map = MapT())
+  VSIP_THROW((std::bad_alloc))
+    : layout_ (dom),
+      storage_(ptr),
+      map_    (map)
+  { assert(!storage_type::is_null(storage_)); }
+
+  ~Us_block() VSIP_NOTHROW {}
+
+  // Data accessors.
+public:
+
+  // 1-dimensional accessors
+  T get(index_type idx) const VSIP_NOTHROW
+  {
+    assert(idx < size());
+    return storage_type::get(storage_, idx);
+  }
+
+  void put(index_type idx, T val) VSIP_NOTHROW
+  {
+    assert(idx < size());
+    storage_type::put(storage_, idx, val);
+  }
+
+  // 2-diminsional get/put
+  T    get(index_type idx0, index_type idx1) const VSIP_NOTHROW
+    { return storage_type::get(storage_, layout_.index(idx0, idx1)); }
+  void put(index_type idx0, index_type idx1, T val) VSIP_NOTHROW
+    { storage_type::put(storage_, layout_.index(idx0, idx1), val); }
+
+  // 3-diminsional get/put
+  T    get(index_type idx0, index_type idx1, index_type idx2)
+    const VSIP_NOTHROW
+    { return storage_type::get(storage_, layout_.index(idx0, idx1, idx2)); }
+  void put(index_type idx0, index_type idx1, index_type idx2, T val)
+    VSIP_NOTHROW
+    { storage_type::put(storage_, layout_.index(idx0, idx1, idx2), val); }
+
+  // Accessors.
+public:
+  length_type size() const VSIP_NOTHROW;
+  length_type size(dimension_type D, dimension_type d) const VSIP_NOTHROW;
+  MapT const& map() const VSIP_NOTHROW { return map_;}
+
+  // Support Direct_data interface.
+public:
+  typedef typename storage_type::type       data_type;
+  typedef typename storage_type::const_type const_data_type;
+
+  data_type       impl_data()       VSIP_NOTHROW { return storage_; }
+  const_data_type impl_data() const VSIP_NOTHROW { return storage_; }
+  stride_type impl_stride(dimension_type D, dimension_type d)
+    const VSIP_NOTHROW;
+
+  // Member Data.
+public:
+  applied_layout_type layout_;
+  data_type           storage_;
+  map_type            map_;
+};
+
+
+
+/// Specialize block layout trait for Us_block blocks.
+
+template <dimension_type Dim,
+	  typename       T,
+	  typename       LayoutT,
+	  typename       Map>
+struct Block_layout<Us_block<Dim, T, LayoutT, Map> >
+{
+  static dimension_type const dim = Dim;
+
+  typedef Direct_access_tag access_type;
+  typedef typename LayoutT::order_type   order_type;
+  typedef typename LayoutT::pack_type    pack_type;
+  typedef typename LayoutT::complex_type complex_type;
+
+  typedef Layout<dim, order_type, pack_type, complex_type> layout_type;
+};
+
+/// Specialize lvalue accessor trait for Us_blocks.  Us_block provides
+/// direct lvalue accessors via impl_ref.
+
+template <typename BlockT,
+	  bool     use_proxy =
+	              Is_complex<typename BlockT::value_type>::value &&
+                      Type_equal<typename Block_layout<BlockT>::complex_type,
+				 Cmplx_split_fmt>::value>
+struct Us_block_lvalue_factory_type;
+
+template <typename BlockT>
+struct Us_block_lvalue_factory_type<BlockT, false>
+{
+  typedef True_lvalue_factory<BlockT> type;
+  template <typename OtherBlock>
+  struct Rebind {
+    typedef True_lvalue_factory<OtherBlock> type;
+  };
+};
+
+template <typename BlockT>
+struct Us_block_lvalue_factory_type<BlockT, true>
+{
+  typedef Proxy_lvalue_factory<BlockT> type;
+  template <typename OtherBlock>
+  struct Rebind {
+    typedef Proxy_lvalue_factory<OtherBlock> type;
+  };
+};
+
+template <dimension_type Dim,
+	  typename       T,
+	  typename       LayoutT>
+struct Lvalue_factory_type<Us_block<Dim, T, LayoutT, Local_map> >
+  : public Us_block_lvalue_factory_type<Us_block<Dim, T, LayoutT, Local_map> >
+{};
+
+
+
+/// Specialize Distributed_local_block traits class for Us_block.
+
+/// For a serial map, distributed block and local block are the same.
+
+template <dimension_type Dim,
+	  typename       T,
+	  typename       LayoutT>
+struct Distributed_local_block<Us_block<Dim, T, LayoutT, Local_map> >
+{
+  typedef Us_block<Dim, T, LayoutT, Local_map> type;
+};
+
+
+
+/// For a distributed map, local block has a serial map.
+
+template <dimension_type Dim,
+	  typename       T,
+	  typename       LayoutT,
+	  typename       MapT>
+struct Distributed_local_block<Us_block<Dim, T, LayoutT, MapT> >
+{
+  // We could determine the local block by just chaning the map
+  // to serial:
+  //   typedef Us_block<Dim, T, LayoutT, Local_map> type;
+
+  // However, to be safe, we'll extract it from the block itself:
+  // (local_block is set in the base class Distributed_block.)
+  typedef typename Us_block<Dim, T, LayoutT, MapT>::local_block_type type;
+};
+
+
+
+/// Overload of get_local_block for Us_block with serial map.
+
+template <dimension_type Dim,
+	  typename       T,
+	  typename       OrderT>
+Us_block<Dim, T, OrderT, Local_map>&
+get_local_block(
+  Us_block<Dim, T, OrderT, Local_map>& block)
+{
+  return block;
+}
+
+template <dimension_type Dim,
+	  typename       T,
+	  typename       OrderT>
+Us_block<Dim, T, OrderT, Local_map> const&
+get_local_block(
+  Us_block<Dim, T, OrderT, Local_map> const& block)
+{
+  return block;
+}
+
+
+
+/// Overload of get_local_block for Us_block with distributed map.
+
+template <dimension_type Dim,
+	  typename       T,
+	  typename       OrderT,
+	  typename       MapT>
+Us_block<Dim, T, OrderT, Local_map>&
+get_local_block(
+  Us_block<Dim, T, OrderT, MapT> const& block)
+{
+  return block.get_local_block();
+}
+
+
+
+/// Assert that subblock is local to block (overload).
+
+template <dimension_type Dim,
+	  typename       T,
+	  typename       OrderT>
+void
+assert_local(
+  Us_block<Dim, T, OrderT, Local_map> const& block,
+  index_type                              sb)
+{
+  assert(sb == 0);
+}
+
+
+
+/// Assert that subblock is local to block (overload).
+
+template <dimension_type Dim,
+	  typename       T,
+	  typename       OrderT,
+	  typename       MapT>
+void
+assert_local(
+  Us_block<Dim, T, OrderT, MapT> const& block,
+  index_type                         sb)
+{
+  block.assert_local(sb);
+}
+
+
+
+/// Specialize Is_simple_distributed_block traits class for Us_block.
+
+template <dimension_type Dim,
+	  typename       T,
+	  typename       OrderT,
+	  typename       MapT>
+struct Is_simple_distributed_block<Us_block<Dim, T, OrderT, MapT> >
+{
+  static bool const value = true;
+};
+
+
+
+#if VSIP_IMPL_USE_GENERIC_VISITOR_TEMPLATES==0
+
+/// Specialize Combine_return_type for Us_block block leaves.
+
+template <typename       CombineT,
+	  dimension_type Dim,
+	  typename       T,
+	  typename       OrderT,
+	  typename       MapT>
+struct Combine_return_type<CombineT, Us_block<Dim, T, OrderT, MapT> >
+{
+  typedef Us_block<Dim, T, OrderT, MapT> block_type;
+  typedef typename CombineT::template return_type<block_type>::type
+		type;
+  typedef typename CombineT::template tree_type<block_type>::type
+		tree_type;
+};
+
+
+
+/// Specialize apply_combine for Us_block block leaves.
+
+template <typename       CombineT,
+	  dimension_type Dim,
+	  typename       T,
+	  typename       OrderT,
+	  typename       MapT>
+typename Combine_return_type<CombineT, Us_block<Dim, T, OrderT, MapT> >::type
+apply_combine(
+  CombineT const&                    combine,
+  Us_block<Dim, T, OrderT, MapT> const& block)
+{
+  return combine.apply(block);
+}
+#endif
+
+
+
+/***********************************************************************
+  Definitions - Us_blocks
+***********************************************************************/
+
+/// Return the total size of the block.
+
+template <dimension_type Dim,
+	  typename       T,
+	  typename       LayoutT,
+	  typename       MapT>
+length_type
+Us_block<Dim, T, LayoutT, MapT>::size() const VSIP_NOTHROW
+{
+  length_type retval = layout_.size(0);
+  for (dimension_type d=1; d<Dim; ++d)
+    retval *= layout_.size(d);
+  return retval;
+}
+
+
+
+/// Return the size of the block in a specific dimension.
+
+/// Requires:
+///   BLOCK_DIM selects which block-dimensionality (BLOCK_DIM == 1).
+///   DIM is the dimension whose length to return (0 <= DIM < BLOCK_DIM).
+/// Returns:
+///   The size of dimension DIM.
+
+template <dimension_type Dim,
+	  typename       T,
+	  typename       LayoutT,
+	  typename       MapT>
+inline
+length_type
+Us_block<Dim, T, LayoutT, MapT>::size(
+  dimension_type block_dim,
+  dimension_type d)
+  const VSIP_NOTHROW
+{
+  assert((block_dim == 1 || block_dim == Dim) && (d < block_dim));
+  return (block_dim == 1) ? this->size() : this->layout_.size(d);
+}
+
+
+
+// Requires:
+//   DIM is a valid dimensionality supported by block (DIM == 1 or 2)
+//   D is a dimension, less than DIM.
+// Returns
+//   The stride in dimension D, for dimensionality DIM.
+
+template <dimension_type Dim,
+	  typename       T,
+	  typename       LayoutT,
+	  typename       MapT>
+inline
+stride_type
+Us_block<Dim, T, LayoutT, MapT>::impl_stride(
+  dimension_type block_dim, dimension_type d)
+  const VSIP_NOTHROW
+{
+  assert((block_dim == 1 || block_dim == Dim) && (d < block_dim));
+
+  return (block_dim == 1) ? 1 : layout_.stride(d);
+}
+
+
+} // namespace vsip::impl
+
+} // namespace vsip
+
+#endif // VSIP_IMPL_US_BLOCK_HPP
Index: tests/corr-2d.cpp
===================================================================
RCS file: /home/cvs/Repository/vpp/tests/corr-2d.cpp,v
retrieving revision 1.3
diff -u -r1.3 corr-2d.cpp
--- tests/corr-2d.cpp	17 Jan 2006 02:44:07 -0000	1.3
+++ tests/corr-2d.cpp	3 Feb 2006 16:46:24 -0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2005 by CodeSourcery, LLC.  All rights reserved. */
+/* Copyright (c) 2005, 2006 by CodeSourcery, LLC.  All rights reserved. */
 
 /** @file    corr-2d.cpp
     @author  Jules Bergmann
@@ -105,12 +105,15 @@
     double error = error_db(out, chk);
 
 #if VERBOSE
-    if (error > -120)
+    if (error > -100)
     {
-      for (index_type i=0; i<P; ++i)
+      cout << "error = " << error
+	   << "  (" << Pr << ", " << Pc << ")" << endl;
+      for (index_type r=0; r<Pr; ++r)
+      for (index_type c=0; c<Pc; ++c)
       {
-	cout << i << ":  out = " << out(i)
-	     << "  chk = " << chk(i)
+	cout << r << ", " << c << ":  out = " << out.get(r, c)
+	     << "  chk = " << chk.get(r, c)
 	     << endl;
       }
       cout << "error = " << error << endl;
Index: tests/correlation.cpp
===================================================================
RCS file: /home/cvs/Repository/vpp/tests/correlation.cpp,v
retrieving revision 1.3
diff -u -r1.3 correlation.cpp
--- tests/correlation.cpp	20 Dec 2005 12:48:40 -0000	1.3
+++ tests/correlation.cpp	3 Feb 2006 16:46:24 -0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2005 by CodeSourcery, LLC.  All rights reserved. */
+/* Copyright (c) 2005, 2006 by CodeSourcery, LLC.  All rights reserved. */
 
 /** @file    correlation.cpp
     @author  Jules Bergmann
@@ -10,6 +10,7 @@
   Included Files
 ***********************************************************************/
 
+#include <vsip/initfin.hpp>
 #include <vsip/vector.hpp>
 #include <vsip/signal.hpp>
 #include <vsip/random.hpp>
@@ -273,8 +274,10 @@
 
 
 int
-main()
+main(int argc, char** argv)
 {
+  vsipl init(argc, argv);
+
   // Test user-visible correlation
   corr_cover<float>();
   corr_cover<complex<float> >();
Index: tests/dense.cpp
===================================================================
RCS file: /home/cvs/Repository/vpp/tests/dense.cpp,v
retrieving revision 1.9
diff -u -r1.9 dense.cpp
--- tests/dense.cpp	20 Dec 2005 12:48:40 -0000	1.9
+++ tests/dense.cpp	3 Feb 2006 16:46:24 -0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2005 by CodeSourcery, LLC.  All rights reserved. */
+/* Copyright (c) 2005, 2006 by CodeSourcery, LLC.  All rights reserved. */
 
 /** @file    tests/dense.cpp
     @author  Jules Bergmann
@@ -11,8 +11,10 @@
 ***********************************************************************/
 
 #include <iostream>
+
 #include <vsip/support.hpp>
 #include <vsip/dense.hpp>
+
 #include "test.hpp"
 
 using namespace std;
@@ -156,11 +158,17 @@
 void
 check_block_at(Dense<1, T>& block)
 {
-  for (index_type i=0; i<block.size(); ++i)
-    block.impl_ref(i) = T(2*i);
+  // impl_ref() is only valid if block stores complex in interleaved
+  // format.  Otherwise lvalue_proxy's are used.
 
-  for (index_type i=0; i<block.size(); ++i)
-    test_assert(equal(block.impl_ref(i), T(2*i)));
+  if (!impl::Is_split_block<Dense<1, T> >::value)
+  {
+    for (index_type i=0; i<block.size(); ++i)
+      block.impl_ref(i) = T(2*i);
+
+    for (index_type i=0; i<block.size(); ++i)
+      test_assert(equal(block.impl_ref(i), T(2*i)));
+  }
 }
 
 
@@ -171,13 +179,16 @@
 void
 check_block_at(Dense<2, T, Order>& block)
 {
-  for (index_type i=0; i<block.size(2, 0); ++i)
-    for (index_type j=0; j<block.size(2, 1); ++j)
-      block.impl_ref(i, j) = T(100*i + j);
-
-  for (index_type i=0; i<block.size(2, 0); ++i)
-    for (index_type j=0; j<block.size(2, 1); ++j)
-      test_assert(equal(block.impl_ref(i, j), T(100*i + j)));
+  if (!impl::Is_split_block<Dense<2, T> >::value)
+  {
+    for (index_type i=0; i<block.size(2, 0); ++i)
+      for (index_type j=0; j<block.size(2, 1); ++j)
+	block.impl_ref(i, j) = T(100*i + j);
+    
+    for (index_type i=0; i<block.size(2, 0); ++i)
+      for (index_type j=0; j<block.size(2, 1); ++j)
+	test_assert(equal(block.impl_ref(i, j), T(100*i + j)));
+  }
 }
 
 
@@ -188,15 +199,18 @@
 void
 check_block_at(Dense<3, T, Order>& block)
 {
-  for (index_type i=0; i<block.size(3, 0); ++i)
-    for (index_type j=0; j<block.size(3, 1); ++j)
-      for (index_type k=0; k<block.size(3, 2); ++k)
-	block.impl_ref(i, j, k) = T(1000*i + 100*j + k);
-
-  for (index_type i=0; i<block.size(3, 0); ++i)
-    for (index_type j=0; j<block.size(3, 1); ++j)
-      for (index_type k=0; k<block.size(3, 2); ++k)
-	test_assert(equal(block.impl_ref(i, j, k), T(1000*i + 100*j + k)));
+  if (!impl::Is_split_block<Dense<3, T> >::value)
+  {
+    for (index_type i=0; i<block.size(3, 0); ++i)
+      for (index_type j=0; j<block.size(3, 1); ++j)
+	for (index_type k=0; k<block.size(3, 2); ++k)
+	  block.impl_ref(i, j, k) = T(1000*i + 100*j + k);
+    
+    for (index_type i=0; i<block.size(3, 0); ++i)
+      for (index_type j=0; j<block.size(3, 1); ++j)
+	for (index_type k=0; k<block.size(3, 2); ++k)
+	  test_assert(equal(block.impl_ref(i, j, k), T(1000*i + 100*j + k)));
+  }
 }
 
 
@@ -278,27 +292,31 @@
 int
 main()
 {
-  test_stack_dense<1, float>(Domain<1>(10));
-  test_stack_dense<1, int>  (Domain<1>(10));
-
-  test_stack_dense<2, float>(Domain<2>(10, 15));
-  test_stack_dense<2, int>  (Domain<2>(15, 10));
-
-  test_stack_dense<3, float>(Domain<3>(10, 15, 25));
-  test_stack_dense<3, int>  (Domain<3>(15, 10, 25));
-  test_stack_dense<3, int>  (Domain<3>(25, 10, 15));
-
-  test_heap_dense<1, int,   row1_type>(Domain<1>(10));
-  test_heap_dense<1, float, row1_type>(Domain<1>(10));
-
-  test_heap_dense<2, int,   row2_type>(Domain<2>(10, 10));
-  test_heap_dense<2, float, row2_type>(Domain<2>(10, 15));
-  test_heap_dense<2, int,   col2_type>(Domain<2>(10, 10));
-  test_heap_dense<2, float, col2_type>(Domain<2>(10, 15));
-  test_heap_dense<2, float, col2_type>(Domain<2>(15,  5));
-
-  test_heap_dense<2, complex<float>, col2_type>(Domain<2>(15,  5));
-
-  test_heap_dense<3, float, row3_type>(Domain<3>(15, 5, 3));
-  test_heap_dense<3, float, col3_type>(Domain<3>(5, 7, 15));
+  test_stack_dense<1, int>            (Domain<1>(10));
+  test_stack_dense<1, float>          (Domain<1>(10));
+  test_stack_dense<1, complex<float> >(Domain<1>(10));
+
+  test_stack_dense<2, int>            (Domain<2>(15, 10));
+  test_stack_dense<2, float>          (Domain<2>(10, 15));
+  test_stack_dense<2, complex<float> >(Domain<2>(10, 15));
+
+  test_stack_dense<3, int>             (Domain<3>(15, 10, 25));
+  test_stack_dense<3, float>           (Domain<3>(10, 15, 25));
+  test_stack_dense<3, complex<double> >(Domain<3>(10, 15, 25));
+
+  test_heap_dense<1, int,            row1_type>(Domain<1>(10));
+  test_heap_dense<1, float,          row1_type>(Domain<1>(10));
+  test_heap_dense<1, complex<float>, row1_type>(Domain<1>(10));
+
+  test_heap_dense<2, int,             row2_type>(Domain<2>(10, 10));
+  test_heap_dense<2, float,           row2_type>(Domain<2>(10, 15));
+  test_heap_dense<2, complex<double>, row2_type>(Domain<2>(16, 8));
+  test_heap_dense<2, int,             col2_type>(Domain<2>(10, 10));
+  test_heap_dense<2, float,           col2_type>(Domain<2>(10, 15));
+  test_heap_dense<2, complex<double>, col2_type>(Domain<2>(15,  5));
+
+  test_heap_dense<3, float,          row3_type>(Domain<3>(15, 5, 3));
+  test_heap_dense<3, float,          col3_type>(Domain<3>(5, 7, 15));
+  test_heap_dense<3, complex<float>, row3_type>(Domain<3>(5, 7, 3));
+  test_heap_dense<3, complex<float>, col3_type>(Domain<3>(3, 5, 7));
 }
Index: tests/extdata-local.cpp
===================================================================
RCS file: tests/extdata-local.cpp
diff -N tests/extdata-local.cpp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/extdata-local.cpp	3 Feb 2006 16:46:24 -0000
@@ -0,0 +1,309 @@
+/* Copyright (c) 2006 by CodeSourcery, LLC.  All rights reserved. */
+
+/** @file    extdata-local.cpp
+    @author  Jules Bergmann
+    @date    2006-01-31
+    @brief   VSIPL++ Library: Unit tests for Extdata_local.
+*/
+
+/***********************************************************************
+  Included Files
+***********************************************************************/
+
+#include <vsip/vector.hpp>
+#include <vsip/impl/extdata-local.hpp>
+#include <vsip/initfin.hpp>
+#include <vsip/map.hpp>
+#include <vsip/selgen.hpp>
+
+#include "test.hpp"
+#include "output.hpp"
+
+#define VERBOSE 1
+
+using namespace std;
+using namespace vsip;
+
+using vsip::impl::Layout;
+using vsip::impl::Stride_unit_dense;
+using vsip::impl::Cmplx_inter_fmt;
+using vsip::impl::Cmplx_split_fmt;
+using vsip::impl::Any_type;
+using vsip::impl::Fast_block;
+using vsip::impl::Block_layout;
+using vsip::impl::Adjust_layout;
+using vsip::impl::Type_equal;
+using vsip::impl::SYNC_IN;
+using vsip::impl::SYNC_INOUT;
+using vsip::impl::ITE_Type;
+using vsip::impl::As_type;
+using vsip::impl::Scalar_of;
+using vsip::impl::Aligned_allocator;
+
+
+
+/***********************************************************************
+  Definitions
+***********************************************************************/
+
+/// Test high-level data interface to 1-dimensional block.
+
+template <typename T,
+	  typename MapT,
+	  typename GivenLP,
+	  typename ReqLP>
+void
+test_1_ext(int expect_cost)
+{
+  length_type const size = 10;
+
+  typedef Fast_block<1, T, GivenLP, MapT> block_type;
+
+  typedef T value_type;
+  typedef typename Adjust_layout<value_type, ReqLP, GivenLP>::type use_LP;
+  typedef impl::Storage< typename use_LP::complex_type, T> storage_type;
+
+  block_type block(size, 0.0);
+
+  value_type val0 =  1.0f;
+  value_type val1 =  2.78f;
+  value_type val2 =  3.14f;
+  value_type val3 = -1.5f;
+
+  // Place values in block.
+  block.put(0, val0);
+  block.put(1, val1);
+
+  typedef typename
+      ITE_Type<Type_equal<typename use_LP::complex_type,
+                          Cmplx_inter_fmt>::value,
+               As_type<Aligned_allocator<T> >,
+               As_type<Aligned_allocator<typename Scalar_of<T>::type> > >
+      ::type alloc_type;
+  alloc_type alloc;
+  typename storage_type::type buffer = storage_type::allocate(alloc, size);
+
+  {
+    impl::Ext_data_local<block_type, use_LP> raw(block, SYNC_INOUT, buffer);
+
+    assert(raw.cost() == expect_cost);
+
+    // Check properties of DDI.
+    test_assert(raw.stride(0) == 1);
+    test_assert(raw.size(0) == size);
+
+    typename storage_type::type data = raw.data();
+
+    // Check that block values are reflected.
+    test_assert(equal(storage_type::get(data, 0), val0));
+    test_assert(equal(storage_type::get(data, 1), val1));
+
+    // Place values in raw data.
+    storage_type::put(data, 1, val2);
+    storage_type::put(data, 2, val3);
+  }
+
+  storage_type::deallocate(alloc, buffer, size);
+
+  // Check that raw data values are reflected.
+  test_assert(equal(block.get(1), val2));
+  test_assert(equal(block.get(2), val3));
+}
+
+
+
+template <typename T,
+	  typename OrderT,
+	  typename MapT,
+	  typename ReqLP>
+void
+test_1_dense(MapT const& map)
+{
+  length_type const size = 10;
+
+  typedef Dense<1, T, OrderT, MapT> block_type;
+
+  typedef typename Block_layout<block_type>::layout_type GivenLP;
+
+  typedef T value_type;
+  typedef typename Adjust_layout<value_type, ReqLP, GivenLP>::type use_LP;
+  typedef impl::Storage< typename use_LP::complex_type, T> storage_type;
+
+  block_type block(size, T(), map);
+
+  value_type val0 =  1.0f;
+  value_type val1 =  2.78f;
+  value_type val2 =  3.14f;
+  value_type val3 = -1.5f;
+
+  // Place values in block.
+  block.put(0, val0);
+  block.put(1, val1);
+
+  typedef typename
+      ITE_Type<Type_equal<typename use_LP::complex_type,
+                          Cmplx_inter_fmt>::value,
+               As_type<Aligned_allocator<T> >,
+               As_type<Aligned_allocator<typename Scalar_of<T>::type> > >
+      ::type alloc_type;
+
+  alloc_type alloc;
+  typename storage_type::type buffer = storage_type::allocate(alloc, size);
+
+  {
+    impl::Ext_data_local<block_type, use_LP> raw(block, SYNC_INOUT, buffer);
+
+    if (Type_equal<OrderT, typename use_LP::order_type>::value &&
+	Type_equal<typename GivenLP::complex_type,
+	           typename use_LP::complex_type>::value)
+    {
+      assert(raw.cost() == 0);
+    }
+    else
+    {
+      assert(raw.cost() == 2);
+    }
+
+    // Check properties of DDI.
+    test_assert(raw.stride(0) == 1);
+    test_assert(raw.size(0) == size);
+
+    typename storage_type::type data = raw.data();
+
+    // Check that block values are reflected.
+    test_assert(equal(storage_type::get(data, 0), val0));
+    test_assert(equal(storage_type::get(data, 1), val1));
+
+    // Place values in raw data.
+    storage_type::put(data, 1, val2);
+    storage_type::put(data, 2, val3);
+  }
+
+  storage_type::deallocate(alloc, buffer, size);
+
+  // Check that raw data values are reflected.
+  test_assert(equal(block.get(1), val2));
+  test_assert(equal(block.get(2), val3));
+}
+
+
+
+template <typename T,
+	  typename OrderT,
+	  typename MapT,
+	  typename ReqLP>
+void
+test_1_dense_const(MapT const& map)
+{
+  length_type const size = 10;
+
+  typedef Dense<1, T, OrderT, MapT> block_type;
+
+  typedef typename Block_layout<block_type>::layout_type GivenLP;
+
+  typedef T value_type;
+  typedef typename Adjust_layout<value_type, ReqLP, GivenLP>::type use_LP;
+  typedef impl::Storage< typename use_LP::complex_type, T> storage_type;
+
+  block_type block(size, T(), map);
+
+  value_type val0 =  1.0f;
+  value_type val1 =  2.78f;
+
+  // Place values in block.
+  block.put(0, val0);
+  block.put(1, val1);
+
+  typedef typename
+      ITE_Type<Type_equal<typename use_LP::complex_type,
+                          Cmplx_inter_fmt>::value,
+               As_type<Aligned_allocator<T> >,
+               As_type<Aligned_allocator<typename Scalar_of<T>::type> > >
+      ::type alloc_type;
+
+  alloc_type alloc;
+  typename storage_type::type buffer = storage_type::allocate(alloc, size);
+
+  {
+    block_type const& ref = block;
+    impl::Ext_data_local<block_type, use_LP> raw(ref, SYNC_IN, buffer);
+
+    if (Type_equal<OrderT, typename use_LP::order_type>::value &&
+	Type_equal<typename GivenLP::complex_type,
+	           typename use_LP::complex_type>::value)
+    {
+      assert(raw.cost() == 0);
+    }
+    else
+    {
+      assert(raw.cost() == 2);
+    }
+
+    // Check properties of DDI.
+    test_assert(raw.stride(0) == 1);
+    test_assert(raw.size(0) == size);
+
+    typename storage_type::type data = raw.data();
+
+    // Check that block values are reflected.
+    test_assert(equal(storage_type::get(data, 0), val0));
+    test_assert(equal(storage_type::get(data, 1), val1));
+  }
+
+  storage_type::deallocate(alloc, buffer, size);
+}
+
+
+
+void
+test()
+{
+  typedef Layout<1, row1_type, Stride_unit_dense, Cmplx_inter_fmt> LP_1rdi;
+  typedef Layout<1, row1_type, Stride_unit_dense, Cmplx_split_fmt> LP_1rds;
+
+  typedef Layout<1, Any_type, Any_type, Cmplx_inter_fmt> LP_1xxi;
+  typedef Layout<1, Any_type, Any_type, Cmplx_split_fmt> LP_1xxs;
+
+  test_1_ext<float,          Local_map, LP_1rdi, LP_1xxi >(0);
+  test_1_ext<float,          Local_map, LP_1rds, LP_1xxi >(0);
+  test_1_ext<float,          Local_map, LP_1rdi, LP_1xxs >(0);
+  test_1_ext<float,          Local_map, LP_1rds, LP_1xxs >(0);
+
+  test_1_ext<complex<float>, Local_map, LP_1rdi, LP_1xxi >(0);
+  test_1_ext<complex<float>, Local_map, LP_1rds, LP_1xxi >(2);
+  test_1_ext<complex<float>, Local_map, LP_1rdi, LP_1xxs >(2);
+  test_1_ext<complex<float>, Local_map, LP_1rds, LP_1xxs >(0);
+
+  Global_map<1> gmap;
+
+  test_1_dense<float,          row1_type, Global_map<1>, LP_1xxi >(gmap);
+  test_1_dense<float,          row1_type, Global_map<1>, LP_1xxs >(gmap);
+  test_1_dense<complex<float>, row1_type, Global_map<1>, LP_1xxi >(gmap);
+  test_1_dense<complex<float>, row1_type, Global_map<1>, LP_1xxs >(gmap);
+
+  test_1_dense_const<float,          row1_type, Global_map<1>, LP_1xxi >(gmap);
+  test_1_dense_const<float,          row1_type, Global_map<1>, LP_1xxs >(gmap);
+  test_1_dense_const<complex<float>, row1_type, Global_map<1>, LP_1xxi >(gmap);
+  test_1_dense_const<complex<float>, row1_type, Global_map<1>, LP_1xxs >(gmap);
+
+  Map<Block_dist> map(num_processors());
+
+  test_1_dense<float,          row1_type, Map<Block_dist>, LP_1xxi >(map);
+  test_1_dense<float,          row1_type, Map<Block_dist>, LP_1xxs >(map);
+  test_1_dense<complex<float>, row1_type, Map<Block_dist>, LP_1xxi >(map);
+  test_1_dense<complex<float>, row1_type, Map<Block_dist>, LP_1xxs >(map);
+
+  test_1_dense_const<float,          row1_type, Map<Block_dist>, LP_1xxi>(map);
+  test_1_dense_const<float,          row1_type, Map<Block_dist>, LP_1xxs>(map);
+  test_1_dense_const<complex<float>, row1_type, Map<Block_dist>, LP_1xxi>(map);
+  test_1_dense_const<complex<float>, row1_type, Map<Block_dist>, LP_1xxs>(map);
+}
+
+
+int
+main(int argc, char** argv)
+{
+  vsipl init(argc, argv);
+
+  test();
+}
Index: tests/extdata-subviews.cpp
===================================================================
RCS file: /home/cvs/Repository/vpp/tests/extdata-subviews.cpp,v
retrieving revision 1.7
diff -u -r1.7 extdata-subviews.cpp
--- tests/extdata-subviews.cpp	20 Dec 2005 12:48:40 -0000	1.7
+++ tests/extdata-subviews.cpp	3 Feb 2006 16:46:24 -0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2005 by CodeSourcery, LLC.  All rights reserved. */
+/* Copyright (c) 2005, 2006 by CodeSourcery, LLC.  All rights reserved. */
 
 /** @file    tests/extdata-subviews.cpp
     @author  Jules Bergmann
@@ -335,6 +335,8 @@
   typedef Matrix<T, BlockT>             view_type;
   typedef typename view_type::row_type  row_type;
   typedef typename row_type::block_type row_block_type;
+  typedef typename impl::Ext_data<row_block_type>::raw_ptr_type raw_ptr_type;
+  typedef typename impl::Ext_data<row_block_type>::storage_type storage_type;
 
   length_type rows = mat.size(0);
   length_type cols = mat.size(1);
@@ -358,13 +360,13 @@
       
       test_assert(ext.size(0) == cols);
 
-      T* ptr             = ext.data();
-      stride_type stride = ext.stride(0);
+      raw_ptr_type ptr    = ext.data();
+      stride_type  stride = ext.stride(0);
 
       for (index_type i=0; i<ext.size(0); ++i)
       {
-	test_assert(equal(ptr[i*stride], T()));
-	ptr[i*stride] = T(r*cols+i);
+	test_assert(equal(storage_type::get(ptr, i*stride), T()));
+	storage_type::put(ptr, i*stride, T(r*cols+i));
       }
     }
   }
@@ -391,11 +393,11 @@
       
       test_assert(ext.size(0) == cols);
 
-      T* ptr             = ext.data();
+      raw_ptr_type ptr   = ext.data();
       stride_type stride = ext.stride(0);
 
       for (index_type i=0; i<ext.size(0); ++i)
-	test_assert(equal(ptr[i*stride], T(r*cols+i + 1)));
+	test_assert(equal(storage_type::get(ptr, i*stride), T(r*cols+i + 1)));
     }
   }
 }
@@ -411,6 +413,8 @@
   typedef Matrix<T, BlockT>             view_type;
   typedef typename view_type::col_type  col_type;
   typedef typename col_type::block_type col_block_type;
+  typedef typename impl::Ext_data<col_block_type>::raw_ptr_type raw_ptr_type;
+  typedef typename impl::Ext_data<col_block_type>::storage_type storage_type;
 
   length_type rows = mat.size(0);
   length_type cols = mat.size(1);
@@ -434,13 +438,13 @@
       
       test_assert(ext.size(0) == rows);
 
-      T* ptr             = ext.data();
-      stride_type stride = ext.stride(0);
+      raw_ptr_type ptr    = ext.data();
+      stride_type  stride = ext.stride(0);
 
       for (index_type i=0; i<ext.size(0); ++i)
       {
-	test_assert(equal(ptr[i*stride], T()));
-	ptr[i*stride] = T(c*rows+i);
+	test_assert(equal(storage_type::get(ptr, i*stride), T()));
+	storage_type::put(ptr, i*stride, T(c*rows+i));
       }
     }
   }
@@ -467,11 +471,11 @@
       
       test_assert(ext.size(0) == rows);
 
-      T* ptr             = ext.data();
-      stride_type stride = ext.stride(0);
+      raw_ptr_type ptr    = ext.data();
+      stride_type  stride = ext.stride(0);
 
       for (index_type i=0; i<ext.size(0); ++i)
-	test_assert(equal(ptr[i*stride], T(c*rows+i + 1)));
+	test_assert(equal(storage_type::get(ptr, i*stride), T(c*rows+i + 1)));
     }
   }
 }
@@ -487,6 +491,8 @@
   typedef Matrix<T, BlockT>                  view_type;
   typedef typename view_type::diag_type      diagview_type;
   typedef typename diagview_type::block_type subblock_type;
+  typedef typename impl::Ext_data<subblock_type>::raw_ptr_type raw_ptr_type;
+  typedef typename impl::Ext_data<subblock_type>::storage_type storage_type;
 
   length_type rows = mat.size(0);
   length_type cols = mat.size(1);
@@ -515,17 +521,17 @@
     { // use a block to limit the lifetime of ext object.
       impl::Ext_data<subblock_type> ext(diagv.block());
 
-      T* ptr          = ext.data();
-      stride_type str = ext.stride(0);
+      raw_ptr_type ptr = ext.data();
+      stride_type  str = ext.stride(0);
 
       for (index_type i = 0; i < size; ++i )
       {
         if ( d >= 0 )
-          test_assert( equal(ptr[i*str], T(i * cols + i + d) ) );
+          test_assert(equal(storage_type::get(ptr, i*str), T(i * cols + i + d) ) );
         else
-          test_assert( equal(ptr[i*str], T(i * cols + i - (d * cols)) ) );
+          test_assert(equal(storage_type::get(ptr, i*str), T(i * cols + i - (d * cols)) ) );
 
-        ptr[i*str] = T(M_PI + i);
+        storage_type::put(ptr, i*str, T(M_PI + i));
       }
     } 
 
@@ -553,6 +559,8 @@
   typedef Matrix<T, BlockT>                 view_type;
   typedef typename view_type::subview_type  subview_type;
   typedef typename subview_type::block_type subblock_type;
+  typedef typename impl::Ext_data<subblock_type>::raw_ptr_type raw_ptr_type;
+  typedef typename impl::Ext_data<subblock_type>::storage_type storage_type;
 
   view = T();
 
@@ -572,15 +580,15 @@
     test_assert(ext.size(0) == subdom[0].size());
     test_assert(ext.size(1) == subdom[1].size());
 
-    T* ptr              = ext.data();
-    stride_type stride0 = ext.stride(0);
-    stride_type stride1 = ext.stride(1);
+    raw_ptr_type ptr     = ext.data();
+    stride_type  stride0 = ext.stride(0);
+    stride_type  stride1 = ext.stride(1);
     
     for (index_type i=0; i<ext.size(0); ++i)
       for (index_type j=0; j<ext.size(1); ++j)
       {
-	test_assert(equal(ptr[i*stride0 + j*stride1], T()));
-	ptr[i*stride0 + j*stride1] = T(i*ext.size(1)+j);
+	test_assert(equal(storage_type::get(ptr, i*stride0 + j*stride1), T()));
+	storage_type::put(ptr, i*stride0 + j*stride1, T(i*ext.size(1)+j));
       }
   }
 
@@ -605,14 +613,15 @@
     test_assert(ext.size(0) == subdom[0].size());
     test_assert(ext.size(1) == subdom[1].size());
 
-    T* ptr              = ext.data();
-    stride_type stride0 = ext.stride(0);
-    stride_type stride1 = ext.stride(1);
+    raw_ptr_type ptr     = ext.data();
+    stride_type  stride0 = ext.stride(0);
+    stride_type  stride1 = ext.stride(1);
     
     for (index_type i=0; i<ext.size(0); ++i)
       for (index_type j=0; j<ext.size(1); ++j)
       {
-	test_assert(equal(ptr[i*stride0 + j*stride1], T(i + j*ext.size(0) + 100)));
+	test_assert(equal(storage_type::get(ptr, i*stride0 + j*stride1),
+			  T(i + j*ext.size(0) + 100)));
       }
   }
 }
@@ -933,6 +942,8 @@
   typedef Tensor<T, BlockT>              view_type;
   typedef typename info_type::subv_type  subv_type;
   typedef typename subv_type::block_type subv_block_type;
+  typedef typename impl::Ext_data<subv_block_type>::raw_ptr_type raw_ptr_type;
+  typedef typename impl::Ext_data<subv_block_type>::storage_type storage_type;
 
   dimension_type const D1 = info_type::D1;
   dimension_type const D2 = info_type::D2;
@@ -960,13 +971,13 @@
       
       test_assert(ext.size(0) == view.size(FreeDim));
 
-      T* ptr             = ext.data();
-      stride_type stride = ext.stride(0);
+      raw_ptr_type ptr    = ext.data();
+      stride_type  stride = ext.stride(0);
 
       for (index_type i=0; i<ext.size(0); ++i)
       {
-	test_assert(equal(ptr[i*stride], T()));
-	ptr[i*stride] = info_type::value(view, i, j, k);
+	test_assert(equal(storage_type::get(ptr, i*stride), T()));
+	storage_type::put(ptr, i*stride, info_type::value(view, i, j, k));
       }
     }
   }
@@ -997,12 +1008,12 @@
       
       test_assert(ext.size(0) == view.size(FreeDim));
 
-      T* ptr             = ext.data();
-      stride_type stride = ext.stride(0);
+      raw_ptr_type ptr    = ext.data();
+      stride_type  stride = ext.stride(0);
 
       for (index_type i=0; i<ext.size(0); ++i)
       {
-	test_assert(equal(ptr[i*stride],
+	test_assert(equal(storage_type::get(ptr, i*stride),
 		     info_type::value(view, i, j, k) + T(1) ));
       }
     }
@@ -1023,6 +1034,8 @@
   typedef Tensor<T, BlockT>                 view_type;
   typedef typename view_type::subview_type  subview_type;
   typedef typename subview_type::block_type subblock_type;
+  typedef typename impl::Ext_data<subblock_type>::raw_ptr_type raw_ptr_type;
+  typedef typename impl::Ext_data<subblock_type>::storage_type storage_type;
 
   view = T();
 
@@ -1043,18 +1056,18 @@
     test_assert(ext.size(1) == subdom[1].size());
     test_assert(ext.size(2) == subdom[2].size());
 
-    T* ptr              = ext.data();
-    stride_type stride0 = ext.stride(0);
-    stride_type stride1 = ext.stride(1);
-    stride_type stride2 = ext.stride(2);
+    raw_ptr_type ptr     = ext.data();
+    stride_type  stride0 = ext.stride(0);
+    stride_type  stride1 = ext.stride(1);
+    stride_type  stride2 = ext.stride(2);
     
     for (index_type i=0; i<ext.size(0); ++i)
       for (index_type j=0; j<ext.size(1); ++j)
 	for (index_type k=0; k<ext.size(2); ++k)
 	{
-	  test_assert(equal(ptr[i*stride0 + j*stride1 + k*stride2], T()));
-	  ptr[i*stride0 + j*stride1 + k*stride2] =
-	    T(i*ext.size(1)*ext.size(2)+j*ext.size(2)+k);
+	  test_assert(equal(storage_type::get(ptr, i*stride0 + j*stride1 + k*stride2), T()));
+	  storage_type::put(ptr, i*stride0 + j*stride1 + k*stride2,
+			    T(i*ext.size(1)*ext.size(2)+j*ext.size(2)+k));
 	}
   }
 
@@ -1087,16 +1100,16 @@
     test_assert(ext.size(1) == subdom[1].size());
     test_assert(ext.size(2) == subdom[2].size());
 
-    T* ptr              = ext.data();
-    stride_type stride0 = ext.stride(0);
-    stride_type stride1 = ext.stride(1);
-    stride_type stride2 = ext.stride(2);
+    raw_ptr_type ptr     = ext.data();
+    stride_type  stride0 = ext.stride(0);
+    stride_type  stride1 = ext.stride(1);
+    stride_type  stride2 = ext.stride(2);
     
     for (index_type i=0; i<ext.size(0); ++i)
       for (index_type j=0; j<ext.size(1); ++j)
 	for (index_type k=0; k<ext.size(2); ++k)
 	{
-	  test_assert(equal(ptr[i*stride0 + j*stride1 + k*stride2],
+	  test_assert(equal(storage_type::get(ptr, i*stride0 + j*stride1 + k*stride2),
 		       T(i +
 			 j*ext.size(0) +
 			 k*ext.size(0)*ext.size(1) + 100)));
@@ -1396,4 +1409,6 @@
 
   test_for_type<float>();
   test_for_type<complex<float> >();
+
+  return 0;
 }
Index: tests/lvalue-proxy.cpp
===================================================================
RCS file: /home/cvs/Repository/vpp/tests/lvalue-proxy.cpp,v
retrieving revision 1.5
diff -u -r1.5 lvalue-proxy.cpp
--- tests/lvalue-proxy.cpp	3 Feb 2006 16:01:36 -0000	1.5
+++ tests/lvalue-proxy.cpp	3 Feb 2006 16:46:24 -0000
@@ -347,6 +347,29 @@
   typedef int const &const_reference_type;
 };
 
+
+template <typename T>
+void
+test_dense_traits()
+{
+  // For all three dimensional specializations of Dense, it should know
+  // that a true lvalue is available, unless block's storage is split
+  // complex (that is, T is complex and complex_type is Cmplx_split_fmt).
+  VSIP_IMPL_STATIC_ASSERT((
+    impl::Type_equal< typename impl::Lvalue_factory_type<Dense<1, T> >::type,
+                      impl::True_lvalue_factory<Dense<1, T> >
+    >::value == true ^ impl::Is_split_block<Dense<1, T> >::value));
+  VSIP_IMPL_STATIC_ASSERT((
+    impl::Type_equal< typename impl::Lvalue_factory_type<Dense<2, T> >::type,
+                      impl::True_lvalue_factory<Dense<2, T> >
+    >::value == true ^ impl::Is_split_block<Dense<2, T> >::value));
+  VSIP_IMPL_STATIC_ASSERT((
+    impl::Type_equal< typename impl::Lvalue_factory_type<Dense<3, T> >::type,
+                      impl::True_lvalue_factory<Dense<3, T> >
+    >::value == true ^ impl::Is_split_block<Dense<3, T> >::value));
+
+}
+
 int
 main(void)
 {
@@ -371,20 +394,8 @@
                       impl::Proxy_lvalue_factory<PseudoBlock>
     >::value == true));
 
-  // For all three dimensional specializations of Dense, it should know
-  // that a true lvalue is available.
-  VSIP_IMPL_STATIC_ASSERT((
-    impl::Type_equal< impl::Lvalue_factory_type<Dense<1> >::type,
-                      impl::True_lvalue_factory<Dense<1> >
-    >::value == true));
-  VSIP_IMPL_STATIC_ASSERT((
-    impl::Type_equal< impl::Lvalue_factory_type<Dense<2> >::type,
-                      impl::True_lvalue_factory<Dense<2> >
-    >::value == true));
-  VSIP_IMPL_STATIC_ASSERT((
-    impl::Type_equal< impl::Lvalue_factory_type<Dense<3> >::type,
-                      impl::True_lvalue_factory<Dense<3> >
-    >::value == true));
+  test_dense_traits<float>();
+  test_dense_traits<complex<float> >();
 
   test_proxy<int>            ();
   test_proxy<float>          ();
Index: tests/solver-cholesky.cpp
===================================================================
RCS file: /home/cvs/Repository/vpp/tests/solver-cholesky.cpp,v
retrieving revision 1.4
diff -u -r1.4 solver-cholesky.cpp
--- tests/solver-cholesky.cpp	20 Dec 2005 12:48:41 -0000	1.4
+++ tests/solver-cholesky.cpp	3 Feb 2006 16:46:24 -0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2005 by CodeSourcery, LLC.  All rights reserved. */
+/* Copyright (c) 2005, 2006 by CodeSourcery, LLC.  All rights reserved. */
 
 /** @file    tests/solver-cholesky.cpp
     @author  Jules Bergmann
@@ -131,22 +131,6 @@
 
 
 
-template <typename T>
-bool
-is_positive(T const& val)
-{
-  return (val > T(0));
-}
-
-template <typename T>
-bool
-is_positive(std::complex<T> const& val)
-{
-  return (val.real() > T(0)) && (val.imag() == T(0));
-}
-
-
-
 /***********************************************************************
   Covsol tests
 ***********************************************************************/
@@ -226,9 +210,9 @@
   // Check A symmetric/hermetian.
   for (index_type i=0; i<n; ++i)
   {
-    test_assert(is_positive(a(i, i)));
+    test_assert(is_positive<T>(a(i, i)));
     for (index_type j=0; j<i; ++j)
-      test_assert(equal(a(i, j), tconj(a(j, i))));
+      test_assert(equal(a(i, j), tconj<T>(a(j, i))));
   }
   
 
@@ -305,9 +289,9 @@
   // Check A symmetric/hermetian.
   for (index_type i=0; i<n; ++i)
   {
-    test_assert(is_positive(a(i, i)));
+    test_assert(is_positive<T>(a(i, i)));
     for (index_type j=0; j<i; ++j)
-      test_assert(equal(a(i, j), tconj(a(j, i))));
+      test_assert(equal(a(i, j), tconj<T>(a(j, i))));
   }
   
 
Index: tests/solver-common.hpp
===================================================================
RCS file: /home/cvs/Repository/vpp/tests/solver-common.hpp,v
retrieving revision 1.7
diff -u -r1.7 solver-common.hpp
--- tests/solver-common.hpp	11 Jan 2006 16:22:47 -0000	1.7
+++ tests/solver-common.hpp	3 Feb 2006 16:46:24 -0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2005 by CodeSourcery, LLC.  All rights reserved. */
+/* Copyright (c) 2005, 2006 by CodeSourcery, LLC.  All rights reserved. */
 
 /** @file    tests/solver-common.cpp
     @author  Jules Bergmann
@@ -65,6 +65,7 @@
   static T value2() { return T(0.5);  }
   static T value3() { return T(-0.5); }
   static T conj(T a) { return a; }
+  static bool is_positive(T a) { return (a > T(0)); }
 
   static vsip::mat_op_type const trans = vsip::mat_trans;
 };
@@ -77,6 +78,8 @@
   static vsip::complex<T> value2() { return vsip::complex<T>(0.5, 1); }
   static vsip::complex<T> value3() { return vsip::complex<T>(1, -1); }
   static vsip::complex<T> conj(vsip::complex<T> a) { return vsip::conj(a); }
+  static bool is_positive(vsip::complex<T> a)
+  { return (a.real() > T(0)) && (a.imag() == T(0)); }
 
   static vsip::mat_op_type const trans = vsip::mat_herm;
 };
@@ -84,11 +87,18 @@
 
 
 template <typename T>
-T tconj(T const val)
+T tconj(T const& val)
 {
   return Test_traits<T>::conj(val);
 }
 
+template <typename T>
+bool
+is_positive(T const& val)
+{
+  return Test_traits<T>::is_positive(val);
+}
+
 
 
 // Compute matrix-matrix produce C = A B
@@ -154,7 +164,7 @@
 	guage += mag(a.get(i, k)) * mag(b.get(k, j));
       }
 
-      float err_ij = mag(tmp - c(i, j))/ Precision_traits<scalar_type>::eps;
+      float err_ij = mag(tmp - c(i, j)) / Precision_traits<scalar_type>::eps;
       if (guage > scalar_type())
 	err_ij = err_ij/guage;
       err = std::max(err, err_ij);
Index: tests/solver-lu.cpp
===================================================================
RCS file: /home/cvs/Repository/vpp/tests/solver-lu.cpp,v
retrieving revision 1.3
diff -u -r1.3 solver-lu.cpp
--- tests/solver-lu.cpp	11 Jan 2006 16:22:47 -0000	1.3
+++ tests/solver-lu.cpp	3 Feb 2006 16:46:24 -0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2005 by CodeSourcery, LLC.  All rights reserved. */
+/* Copyright (c) 2005, 2006 by CodeSourcery, LLC.  All rights reserved. */
 
 /** @file    tests/solver-lu.cpp
     @author  Jules Bergmann
@@ -245,9 +245,9 @@
 
   // 3. Check result.
 
-  Matrix<T> chk1(n, p);
-  Matrix<T> chk2(n, p);
-  Matrix<T> chk3(n, p);
+  Matrix<T, block_type> chk1(n, p);
+  Matrix<T, block_type> chk2(n, p);
+  Matrix<T, block_type> chk3(n, p);
 
   prod(a, x1, chk1);
   prod(trans(a), x2, chk2);
Index: tests/solver-qr.cpp
===================================================================
RCS file: /home/cvs/Repository/vpp/tests/solver-qr.cpp,v
retrieving revision 1.6
diff -u -r1.6 solver-qr.cpp
--- tests/solver-qr.cpp	11 Jan 2006 16:22:47 -0000	1.6
+++ tests/solver-qr.cpp	3 Feb 2006 16:46:24 -0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2005 by CodeSourcery, LLC.  All rights reserved. */
+/* Copyright (c) 2005, 2006 by CodeSourcery, LLC.  All rights reserved. */
 
 /** @file    tests/solver-qr.cpp
     @author  Jules Bergmann
@@ -87,8 +87,7 @@
 
   for (index_type c=0; c<p; ++c)
     for (index_type r=0; r<n; ++r)
-      test_assert(equal(b(r, c),
-		   Test_traits<T>::conj(a(r, r)) * a(r, r) * x(r, c)));
+      test_assert(equal(b(r, c), tconj<T>(a(r, r)) * a(r, r) * x(r, c)));
 }
 
 
@@ -414,7 +413,7 @@
   for (index_type i=0; i<m; ++i)
     for (index_type j=0; j<m; ++j)
       if (i == j)
-	test_assert(equal(qi(i, j) * tconj(qi(i, j)), T(1)));
+	test_assert(equal(qi(i, j) * tconj<T>(qi(i, j)), T(1)));
       else
 	test_assert(equal(qi(i, j), T()));
 
@@ -427,7 +426,7 @@
     for (index_type j=0; j<m; ++j)
     {
       if (i == j)
-	test_assert(equal(iq(i, j) * tconj(qi(i, j)), T(1)));
+	test_assert(equal(iq(i, j) * tconj<T>(qi(i, j)), T(1)));
       else
 	test_assert(equal(iq(i, j), T()));
       test_assert(equal(iq(i, j), qi(i, j)));
@@ -650,8 +649,7 @@
 
   for (index_type c=0; c<p; ++c)
     for (index_type r=0; r<n; ++r)
-      test_assert(equal(b(r, c),
-		   Test_traits<T>::conj(a(r, r)) * a(r, r) * x(r, c)));
+      test_assert(equal(b(r, c), tconj<T>(a(r, r)) * a(r, r) * x(r, c)));
 }
 
 
Index: tests/solver-toepsol.cpp
===================================================================
RCS file: /home/cvs/Repository/vpp/tests/solver-toepsol.cpp,v
retrieving revision 1.3
diff -u -r1.3 solver-toepsol.cpp
--- tests/solver-toepsol.cpp	11 Jan 2006 16:22:47 -0000	1.3
+++ tests/solver-toepsol.cpp	3 Feb 2006 16:46:24 -0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2005 by CodeSourcery, LLC.  All rights reserved. */
+/* Copyright (c) 2005, 2006 by CodeSourcery, LLC.  All rights reserved. */
 
 /** @file    tests/solver-toepsol.cpp
     @author  Jules Bergmann
@@ -67,8 +67,8 @@
   aa.diag() = a(0);
   for (index_type i=1; i<size; ++i)
   {
-    aa.diag(+i) =                 a(i);
-    aa.diag(-i) = impl::impl_conj(a(i));
+    aa.diag(+i) =                    a(i);
+    aa.diag(-i) = impl::impl_conj<T>(a(i));
   }
 
 
Index: tests/test.hpp
===================================================================
RCS file: /home/cvs/Repository/vpp/tests/test.hpp,v
retrieving revision 1.13
diff -u -r1.13 test.hpp
--- tests/test.hpp	3 Feb 2006 16:01:37 -0000	1.13
+++ tests/test.hpp	3 Feb 2006 16:46:24 -0000
@@ -95,7 +95,7 @@
   vsip::impl::Lvalue_proxy<T, Block, Dim> const& val1, 
   T                                              val2)
 {
-  return val1 == val2;
+  return equal(static_cast<T>(val1), val2);
 }
 
 template <typename             T,
@@ -106,7 +106,31 @@
   T                                              val1,
   vsip::impl::Lvalue_proxy<T, Block, Dim> const& val2) 
 {
-  return val1 == val2;
+  return equal(val1, static_cast<T>(val2));
+}
+
+template <typename             T,
+	  typename             Block1,
+	  typename             Block2,
+	  vsip::dimension_type Dim1,
+	  vsip::dimension_type Dim2>
+inline bool
+equal(
+  vsip::impl::Lvalue_proxy<T, Block1, Dim1> const& val1,
+  vsip::impl::Lvalue_proxy<T, Block2, Dim2> const& val2)
+{
+  return equal(static_cast<T>(val1), static_cast<T>(val2));
+}
+
+template <typename             T,
+	  typename             Block,
+	  vsip::dimension_type Dim>
+inline bool
+equal(
+  vsip::impl::Lvalue_proxy<T, Block, Dim> const& val1,
+  vsip::impl::Lvalue_proxy<T, Block, Dim> const& val2)
+{
+  return equal(static_cast<T>(val1), static_cast<T>(val2));
 }
 
 
Index: tests/us-block.cpp
===================================================================
RCS file: tests/us-block.cpp
diff -N tests/us-block.cpp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/us-block.cpp	3 Feb 2006 16:46:24 -0000
@@ -0,0 +1,153 @@
+/* Copyright (c) 2006 by CodeSourcery, LLC.  All rights reserved. */
+
+/** @file    tests/us-block.cpp
+    @author  Jules Bergmann
+    @date    2006-01-31
+    @brief   VSIPL++ Library: Unit tests for Us_block's.
+*/
+
+/***********************************************************************
+  Included Files
+***********************************************************************/
+
+#include <iostream>
+#include <cassert>
+#include <vsip/support.hpp>
+#include <vsip/impl/point.hpp>
+#include <vsip/impl/point-fcn.hpp>
+#include <vsip/impl/us-block.hpp>
+
+#include "test.hpp"
+
+using namespace std;
+using namespace vsip;
+
+using vsip::impl::Point;
+using vsip::impl::extent_old;
+
+
+
+/***********************************************************************
+  Definitions
+***********************************************************************/
+
+template <typename T>
+inline T
+identity(
+  Point<1> /*extent*/,
+  Point<1> idx,
+  int      k)
+{
+  return static_cast<T>(k*idx[0] + 1);
+}
+
+
+
+template <typename T>
+inline T
+identity(
+  Point<2> extent,
+  Point<2> idx,
+  int      k)
+{
+  Point<2> offset;
+  index_type i = (idx[0]+offset[0])*extent[1] + (idx[1]+offset[1]);
+  return static_cast<T>(k*i+1);
+}
+
+
+
+template <dimension_type Dim,
+	  typename       Block>
+void
+fill_block(Block& blk, int k)
+{
+  typedef typename Block::value_type value_type;
+
+  Point<Dim> ex = extent_old<Dim>(blk);
+  for (Point<Dim> idx; idx != ex; next(ex, idx))
+  {
+    put(blk, idx, identity<value_type>(ex, idx, k));
+  }
+}
+
+
+
+template <dimension_type Dim,
+	  typename       Block>
+void
+check_block(Block& blk, int k)
+{
+  typedef typename Block::value_type value_type;
+
+  Point<Dim> ex = extent_old<Dim>(blk);
+  for (Point<Dim> idx; idx != ex; next(ex, idx))
+  {
+    test_assert(equal( get(blk, idx),
+		       identity<value_type>(ex, idx, k)));
+  }
+}
+
+
+
+template <dimension_type Dim,
+	  typename       BlockT>
+void
+test(Domain<Dim> const& dom)
+{
+  using vsip::impl::ITE_Type;
+  using vsip::impl::As_type;
+  using vsip::impl::Type_equal;
+  using vsip::impl::Aligned_allocator;
+  using vsip::impl::Cmplx_inter_fmt;
+  using vsip::impl::Scalar_of;
+
+  typedef typename BlockT::value_type                       value_type;
+  typedef typename impl::Block_layout<BlockT>::complex_type complex_type;
+  typedef impl::Storage<complex_type, value_type>           storage_type;
+  typedef typename storage_type::type                       ptr_type;
+
+  typedef typename
+    ITE_Type<Type_equal<complex_type, Cmplx_inter_fmt>::value,
+            As_type<Aligned_allocator<value_type> >,
+            As_type<Aligned_allocator<typename Scalar_of<value_type>::type> > >
+      ::type alloc_type;
+  alloc_type alloc;
+
+  ptr_type ptr = storage_type::allocate(alloc, dom.size());
+
+  {
+    BlockT block(dom, ptr);
+
+    assert(block.size() == dom.size());
+    for (dimension_type d=0; d<Dim; ++d)
+      assert(block.size(Dim, d) == dom[d].size());
+
+    fill_block<Dim>(block, 5);
+    check_block<Dim>(block, 5);
+  }
+
+  storage_type::deallocate(alloc, ptr, dom.size());
+}
+
+
+
+int
+main()
+{
+  using vsip::impl::Us_block;
+  using vsip::impl::Layout;
+  using vsip::impl::Stride_unit_dense;
+  using vsip::impl::Stride_unit_align;
+  using vsip::impl::Cmplx_inter_fmt;
+  using vsip::impl::Cmplx_split_fmt;
+
+  typedef Layout<1, row1_type, Stride_unit_dense, Cmplx_inter_fmt> LP_ri1;
+  typedef Layout<2, row2_type, Stride_unit_dense, Cmplx_inter_fmt> LP_ri2;
+  typedef Layout<2, row2_type, Stride_unit_dense, Cmplx_split_fmt> LP_rs2;
+
+  test<1, Us_block<1, float, LP_ri1, Local_map> >(Domain<1>(5));
+
+  test<2, Us_block<2, float, LP_ri2, Local_map> >(Domain<2>(5, 7));
+  test<2, Us_block<2, float, LP_rs2, Local_map> >(Domain<2>(5, 7));
+}
Index: tests/util.hpp
===================================================================
RCS file: /home/cvs/Repository/vpp/tests/util.hpp,v
retrieving revision 1.3
diff -u -r1.3 util.hpp
--- tests/util.hpp	16 Sep 2005 21:51:08 -0000	1.3
+++ tests/util.hpp	3 Feb 2006 16:46:24 -0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2005 by CodeSourcery, LLC.  All rights reserved. */
+/* Copyright (c) 2005, 2006 by CodeSourcery, LLC.  All rights reserved. */
 
 /** @file    tests/util.hpp
     @author  Jules Bergmann
@@ -23,42 +23,40 @@
   Definitions
 ***********************************************************************/
 
-// Utility function to generalize creation of a view from a domain.
+// Utility function to generalize creation of a view from a domain (1-dim).
 
-template <typename View,
-	  typename Map>
+template <typename View>
 inline View
-create_view(vsip::Domain<1> const& dom, Map const& map)
+create_view(
+  vsip::Domain<1> const&                     dom,
+  typename View::block_type::map_type const& map =
+		typename View::block_type::map_type())
 {
   return View(dom[0].length(), map);
 }
 
 
 
-// Utility function to generalize creation of a view from a domain.
-
-template <typename View,
-	  typename Map>
+template <typename View>
 inline View
 create_view(
-  vsip::Domain<1> const&    dom,
-  typename View::value_type val,
-  Map const&                map)
+  vsip::Domain<1> const&                     dom,
+  typename View::value_type                  val,
+  typename View::block_type::map_type const& map =
+		typename View::block_type::map_type())
 {
   return View(dom[0].length(), val, map);
 }
 
 
 
-// Utility function to generalize creation of a view from a domain.
-
-template <typename View,
-	  typename Map>
+template <typename View>
 inline View
 create_view(
-  vsip::Domain<1> const&      dom,
-  typename View::value_type * ptr,
-  Map const&                  map)
+  vsip::Domain<1> const&                     dom,
+  typename View::value_type*                 ptr,
+  typename View::block_type::map_type const& map =
+		typename View::block_type::map_type())
 {
   typedef typename View::block_type block_type;
 
@@ -70,54 +68,50 @@
 
 
 
-// Utility function to generalize creation of a view from a domain.
+// Utility function to generalize creation of a view from a domain (2-dim).
 
-template <typename View,
-	  typename Map>
+template <typename View>
 inline View
-create_view(vsip::Domain<2> const& dom, Map const& map)
+create_view(
+  vsip::Domain<2> const& dom,
+  typename View::block_type::map_type const& map =
+		typename View::block_type::map_type())
 {
   return View(dom[0].length(), dom[1].length(), map);
 }
 
-
-
-// Utility function to generalize creation of a view from a domain.
-
-template <typename View,
-	  typename Map>
+template <typename View>
 inline View
 create_view(
-  vsip::Domain<2> const&    dom,
-  typename View::value_type val,
-  Map const&                map)
+  vsip::Domain<2> const&                     dom,
+  typename View::value_type                  val,
+  typename View::block_type::map_type const& map =
+		typename View::block_type::map_type())
 {
   return View(dom[0].length(), dom[1].length(), val, map);
 }
 
 
 
-// Utility function to generalize creation of a view from a domain.
+// Utility function to generalize creation of a view from a domain (3-dim).
 
-template <typename View,
-	  typename Map>
+template <typename View>
 inline View
-create_view(vsip::Domain<3> const& dom, Map const& map)
+create_view(
+  vsip::Domain<3> const&                     dom,
+  typename View::block_type::map_type const& map =
+		typename View::block_type::map_type())
 {
   return View(dom[0].length(), dom[1].length(), dom[2].length(), map);
 }
 
-
-
-// Utility