[vsipl++] Matlab IO
Jules Bergmann
jules at codesourcery.com
Tue Jun 13 02:15:49 UTC 2006
Assem Salama wrote:
> Everyone,
> This patch changes the names of mbf.v to mbf.view and mbf.view_name to
> mbf.name. Also changed unimplemented throws to errors.
Assem,
In general, there are a lot of comparisons being done between signed and
unsigned values below. Can you recompile with the '-W -Wall' options,
that will help catch these. It is a good practice to use '-W -Wall'
when developing.
I have a few more comments below, please take a look. I think this is
starting to converge.
I also have an action item for myself after reviewing this patch:
- define a column-major next()
I'll post something for this shortly.
It would also be nice to do the following, but it is not critical.
- move get_real_ptr/get_image_ptr functionality into Allocated_storage
- move Subview_helper functionality into view class
I'll capture these as issues.
-- Jules
>
> Thanks,
> Assem
>
>
> ------------------------------------------------------------------------
>
> ? .matlab.hpp.swp
> ? generic_reader.hpp
> ? matlab_temp
> ? png.cpp
> ? png.hpp
> Index: GNUmakefile.inc.in
> ===================================================================
> RCS file: /home/cvs/Repository/vpp/src/vsip_csl/GNUmakefile.inc.in,v
> retrieving revision 1.1
> diff -u -r1.1 GNUmakefile.inc.in
> --- GNUmakefile.inc.in 8 May 2006 03:49:44 -0000 1.1
> +++ GNUmakefile.inc.in 7 Jun 2006 21:06:53 -0000
> @@ -12,13 +12,36 @@
> # Variables
> ########################################################################
>
> +VSIP_CSL_HAVE_PNG := @HAVE_PNG_H@
> +
> +src_vsip_csl_CXXINCLUDES := -I$(srcdir)/src
> +src_vsip_csl_CXXFLAGS := $(src_vsip_csl_CXXINCLUDES)
> +
> +ifdef VSIP_CSL_HAVE_PNG
> +src_vsip_csl_cxx_sources += $(srcdir)/src/vsip_csl/png.cpp
> +endif
If you're not including png.cpp as part of your patch, why are you
adding it to the makefile?
> +src_vsip_csl_cxx_objects := $(patsubst $(srcdir)/%.cpp, %.$(OBJEXT),\
> + $(src_vsip_csl_cxx_sources))
> +cxx_sources += $(src_vsip_csl_cxx_sources)
> +
> +libs += lib/libvsip_csl.a
>
> ########################################################################
> # Rules
> ########################################################################
>
> +all:: lib/libvsip_csl.a
> +
> +clean::
> + rm -f lib/libvsip_csl.a
> +
> +lib/libvsip_csl.a: $(src_vsip_csl_cxx_objects)
> + $(AR) rc $@ $^ || rm -f $@
> +
> # Install the extensions library and its header files.
> install::
> + $(INSTALL) -d $(DESTDIR)$(libdir)
> + $(INSTALL_DATA) lib/libvsip_csl.a $(DESTDIR)$(libdir)/libvsip_csl$(suffix).a
> $(INSTALL) -d $(DESTDIR)$(includedir)/vsip_csl
> for header in $(wildcard $(srcdir)/src/vsip_csl/*.hpp); do \
> $(INSTALL_DATA) $$header $(DESTDIR)$(includedir)/vsip_csl; \
> Index: matlab.hpp
> ===================================================================
> RCS file: matlab.hpp
> diff -N matlab.hpp
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ matlab.hpp 7 Jun 2006 21:06:54 -0000
> @@ -0,0 +1,277 @@
> +#ifndef VSIP_CSL_MATLAB_HPP
> +#define VSIP_CSL_MATLAB_HPP
> +
What header are the types in32_t, etc getting defined in?
> +#include <iostream>
> +#include <vsip/impl/metaprogramming.hpp>
> +#include <vsip/impl/fns_elementwise.hpp>
> +#include <vsip/impl/length.hpp>
> +#include <vsip/impl/domain-utils.hpp>
> +
> +namespace vsip_csl
> +{
> +
> +namespace matlab
> +{
> + struct data_element
> + {
> + int32_t type;
> + int32_t size;
> + };
> +
> + template <int Dim>
> + struct view_header
> + {
> + data_element header;
> + data_element array_flags_header;
> + char array_flags[8];
> + data_element dim_header;
> + int32_t dim[Dim + Dim%2]; //the dim has to be aligned to an 8 byte boundary
> + data_element array_name_header;
> + };
> +
> + // helper struct to get the imaginary part of a view.
> + template <typename ViewT,
> + bool IsComplex =
> + vsip::impl::Is_complex<typename ViewT::value_type>::value>
> + struct Subview_helper;
> +
> + template <typename ViewT>
> + struct Subview_helper<ViewT,true>
> + {
> + typedef typename ViewT::realview_type realview_type;
> + typedef typename ViewT::imagview_type imagview_type;
> +
> + static realview_type real(ViewT v) { return v.real(); }
> + static imagview_type imag(ViewT v) { return v.imag(); }
> + };
> +
> + template <typename ViewT>
> + struct Subview_helper<ViewT,false>
> + {
> + typedef ViewT realview_type;
> + typedef ViewT imagview_type;
> +
> + static realview_type real(ViewT v) { return v; }
> + static imagview_type imag(ViewT v) { return v; }
> + };
> +
> +
> + // generic reader that allows us to read a generic type and cast to another
> +
> + // the read function for real or complex depending of the view that was
> + // passed in
> + template <typename T1,
> + typename T2,
> + typename ViewT>
> + void read(std::istream& is,ViewT v)
> + {
> + vsip::dimension_type const View_dim = ViewT::dim;
> + vsip::Index<View_dim> my_index;
> + vsip::impl::Length<View_dim> v_extent = extent(v);
> + typedef typename vsip::impl::Scalar_of<T2>::type scalar_type;
> + T1 data;
> +
> + // get num_points
> + vsip::length_type num_points = v.size();
> +
> + // read all the points
> + for(int i=0;i<num_points;i++) {
'i' should be an index_type. If you compile this with '-W -Wall', which
you should be doing ;), GCC will catch this.
> + is.read(reinterpret_cast<char*>(&data),sizeof(data));
Is 'sizeof(data)' the correct size to read here? Moreover, should
'data' really be of type 'T1'? If this is reading in part of a complex
array, 'v' will be either the real or imag subview, which would make the
correct type for 'data' to be 'scalar_type'. That is how write() below
appears to work.
If 'data' should be scalar_type, then instead of changing it here, it
would be more natural to have 'operator>>' call read() with
'Scalar_type<T1>::type' as a parameter.
> + put(v,my_index,scalar_type(data));
> +
> + // increment index
> + my_index = vsip::impl::next(v_extent,my_index);
> + }
> +
> + }
> +
> + // a write function to output a view to a matlab file.
> + template <typename T,
> + typename ViewT>
> + void write(std::ostream& os,ViewT v)
> + {
> + vsip::dimension_type const View_dim = ViewT::dim;
> + vsip::Index<View_dim> my_index;
> + vsip::impl::Length<View_dim> v_extent = extent(v);
> + typedef typename vsip::impl::Scalar_of<T>::type scalar_type;
Passing T as a template parameter, but than only using Scalar_of<T>
seems unintuitive. Let's perform the Scalar_of<T> at the caller of
write().
> + scalar_type data;
> +
> + // get num_points
> + vsip::length_type num_points = v.size();
> +
> + // write all the points
> + for(int i=0;i<num_points;i++) {
> + data = get(v,my_index);
> + os.write(reinterpret_cast<char*>(&data),sizeof(data));
> +
> + // increment index
> + my_index = vsip::impl::next(v_extent,my_index);
> + }
> +
> + }
> +
> + struct header
> + {
> + char description[116];
> + char subsyt_data[8];
> + char version[2];
> + char endian[2];
> + };
> +
> + // constants for matlab binary format
> +
> + // data types
> + static int const miINT8 = 1;
> + static int const miUINT8 = 2;
> + static int const miINT16 = 3;
> + static int const miUINT16 = 4;
> + static int const miINT32 = 5;
> + static int const miUINT32 = 6;
> + static int const miSINGLE = 7;
> + static int const miDOUBLE = 9;
> + static int const miINT64 = 12;
> + static int const miUINT64 = 13;
> + static int const miMATRIX = 14;
> + static int const miCOMPRESSED = 15;
> + static int const miUTF8 = 16;
> + static int const miUTF16 = 17;
> + static int const miUTF32 = 18;
> +
> + // class types
> + static int const mxCELL_CLASS = 1;
> + static int const mxSTRUCT_CLASS = 2;
> + static int const mxOBJECT_CLASS = 3;
> + static int const mxCHAR_CLASS = 4;
> + static int const mxSPARSE_CLASS = 5;
> + static int const mxDOUBLE_CLASS = 6;
> + static int const mxSINGLE_CLASS = 7;
> + static int const mxINT8_CLASS = 8;
> + static int const mxUINT8_CLASS = 9;
> + static int const mxINT16_CLASS = 10;
> + static int const mxUINT16_CLASS = 11;
> + static int const mxINT32_CLASS = 12;
> + static int const mxUINT32_CLASS = 13;
> +
> + // matlab header traits
> + template <int size,bool is_signed,bool is_int>
> + struct Matlab_header_traits;
> +
> + template <>
> + struct Matlab_header_traits<1, true, true> // char
> + {
> + static int const value_type = miINT8;
> + static int const class_type = mxINT8_CLASS;
> + };
> +
> + template <>
> + struct Matlab_header_traits<1, false, true> // unsigned char
> + {
> + static int const value_type = miUINT8;
> + static int const class_type = mxUINT8_CLASS;
> + };
> +
> + template <>
> + struct Matlab_header_traits<2, true, true> // short
> + {
> + static int const value_type = miINT16;
> + static int const class_type = mxINT16_CLASS;
> + };
> +
> + template <>
> + struct Matlab_header_traits<2, false, true> // unsigned short
> + {
> + static int const value_type = miUINT16;
> + static int const class_type = mxUINT16_CLASS;
> + };
> +
> + template <>
> + struct Matlab_header_traits<4, true, true> // int
> + {
> + static int const value_type= miINT32;
> + static int const class_type= mxINT32_CLASS;
> + };
> +
> + template <>
> + struct Matlab_header_traits<4, false, true> // unsigned int
> + {
> + static int const value_type= miUINT32;
> + static int const class_type= mxUINT32_CLASS;
> + };
> +
> + template <>
> + struct Matlab_header_traits<4, true, false> // float
> + {
> + static int const value_type= miSINGLE;
> + static int const class_type= mxSINGLE_CLASS;
> + };
> +
> + template <>
> + struct Matlab_header_traits<8, true, false> // double
> + {
> + static int const value_type= miDOUBLE;
> + static int const class_type= mxDOUBLE_CLASS;
> + };
> +
VSIPL++ has a template classes View_of_dim<> and Col_major<> that can
help us out here. Let's define Matlab_desired_LP as:
> + // matlab desired layouts
> + template <template <typename,typename> class View>
> + struct Matlab_desired_LP
{
static vsip::dimension_type const dim = vsip::Dim_of_view<View>::dim;
typedef vsip::impl::Layout<
dim,
typename vsip::Col_major<dim>::type,
vsip::impl::Stride_unit_dense,
vsip::impl::Cmplx_split_fmt> type;
};
Which lets us get rid of all these specializations.
> +
> + template<> struct Matlab_desired_LP<vsip::const_Vector>
> + { typedef vsip::impl::Layout<1,vsip::col1_type,
> + vsip::impl::Stride_unit_dense,vsip::impl::Cmplx_split_fmt>
> + type;
> + };
> +
> + template<> struct Matlab_desired_LP<vsip::const_Matrix>
> + { typedef vsip::impl::Layout<2,vsip::col2_type,
> + vsip::impl::Stride_unit_dense,vsip::impl::Cmplx_split_fmt>
> + type;
> + };
> +
> + template<> struct Matlab_desired_LP<vsip::const_Tensor>
> + { typedef vsip::impl::Layout<3,vsip::col3_type,
> + vsip::impl::Stride_unit_dense,vsip::impl::Cmplx_split_fmt>
> + type;
> + };
> +
> + template<> struct Matlab_desired_LP<vsip::Vector>
> + { typedef vsip::impl::Layout<1,vsip::col1_type,
> + vsip::impl::Stride_unit_dense,vsip::impl::Cmplx_split_fmt>
> + type;
> + };
> +
> + template<> struct Matlab_desired_LP<vsip::Matrix>
> + { typedef vsip::impl::Layout<2,vsip::col2_type,
> + vsip::impl::Stride_unit_dense,vsip::impl::Cmplx_split_fmt>
> + type;
> + };
> +
> + template<> struct Matlab_desired_LP<vsip::Tensor>
> + { typedef vsip::impl::Layout<3,vsip::col3_type,
> + vsip::impl::Stride_unit_dense,vsip::impl::Cmplx_split_fmt>
> + type;
> + };
> +
> + // helper function to return the real and imaginary part of a pointer
Let's put these function in 'Allocated_storage' instead, next to the
definitions of std::pair<T*, T*>. This will probably be useful in other
contexts, and if we ever decide to change how we store split-complex, we
don't explicit functions on std::pair<T*, T*> spread out in the library.
> +
> + template<typename T>
> + inline T* get_real_ptr(std::pair<T*,T*> ptr)
> + { return ptr.first; }
> + template<typename T>
> + inline T* get_real_ptr(T* ptr)
> + { return ptr; }
> +
> + template<typename T>
> + inline T* get_imag_ptr(std::pair<T*,T*> ptr)
> + { return ptr.second; }
> + template<typename T>
> + inline T* get_imag_ptr(T* ptr)
> + { return ptr; }
> +
> +
> +
> +} // namesapce matlab
> +
> +} // namespace vsip_csl
> +
> +#endif // VSIP_CSL_MATLAB_HPP
> Index: matlab_bin_formatter.hpp
> ===================================================================
> RCS file: matlab_bin_formatter.hpp
> diff -N matlab_bin_formatter.hpp
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ matlab_bin_formatter.hpp 7 Jun 2006 21:06:54 -0000
> @@ -0,0 +1,366 @@
> +/* Copyright (c) 2005, 2006 by CodeSourcery. All rights reserved. */
> +
> +/** @file vsip_csl/matlab_bin_formatter.hpp
> + @author Assem Salama
> + @date 2006-05-22
> + @brief VSIPL++ CodeSourcery Library: Matlab binary formatter
> +*/
> +
> +#ifndef VSIP_CSL_MATLAB_BIN_FORMATTER_HPP
> +#define VSIP_CSL_MATLAB_BIN_FORMATTER_HPP
> +
> +#include <stdint.h>
> +#include <string>
> +#include <limits>
> +#include <vsip_csl/matlab.hpp>
> +#include <vsip/impl/fns_scalar.hpp>
> +#include <vsip/impl/fns_elementwise.hpp>
> +#include <vsip/impl/metaprogramming.hpp>
> +#include <vsip/impl/view_traits.hpp>
> +#include <vsip/impl/extdata.hpp>
> +
> +namespace vsip_csl
> +{
> +
> + template <typename ViewT>
> + struct Matlab_bin_formatter
> + {
> + Matlab_bin_formatter(ViewT v,std::string const& name) :
> + view(v), name(name) {}
> +
> + ViewT view;
> + std::string name;
> +
> + };
> +
> + struct Matlab_bin_hdr
> + {
> + Matlab_bin_hdr(std::string const& descr, std::string const& end) :
> + description(descr),version("MATLAB 5.0 : "),endian(end) {}
> + Matlab_bin_hdr(std::string const& descr) :
> + description(descr),version("MATLAB 5.0 : "),endian("MI") {}
> + Matlab_bin_hdr() :
> + description(" "),version("MATLAB 5.0 : "),endian("MI") {}
> +
> + // description
> + std::string version;
> + std::string description;
> + std::string endian;
> +
> + };
> +} // namespace vsip_csl
> +
> +/****************************************************************************
> + * Definitions
> + ***************************************************************************/
> +
> +namespace vsip_csl
> +{
> +
> +// operator to write matlab header
> +inline
> +std::ostream&
> +operator<<(
> + std::ostream& o,
> + Matlab_bin_hdr const& h)
> +{
> + matlab::header m_hdr;
> +
> + // set hdr to spaces
> + memset(&(m_hdr),' ',sizeof(m_hdr));
> + strncpy(m_hdr.description, h.version.data(), h.version.length());
> + strncpy(m_hdr.description+h.version.length(), h.description.data(),
> + h.description.length());
> + m_hdr.version[1] = 0x01; m_hdr.version[0] = 0x00;
> + m_hdr.endian[0]=h.endian[0];
> + m_hdr.endian[1]=h.endian[1];
> +
> + // write header
> + o.write(reinterpret_cast<char*>(&m_hdr),sizeof(m_hdr));
> +
> + return o;
> +}
> +// operator to write a view to a matlab file
> +template <typename T,
> + typename Block0,
> + template <typename,typename> class const_View>
> +inline
> +std::ostream&
> +operator<<(
> + std::ostream& o,
> + Matlab_bin_formatter<const_View<T,Block0> > const& mbf)
> +{
> + typedef typename vsip::impl::Scalar_of<T>::type scalar_type;
> + matlab::data_element temp_data_element;
> + int sz;
The way 'sz' is being used below, it should be of type 'size_t'. For
example, sizeof() returns a size_t, and it is being used with other
unsigned types.
> + matlab::view_header<vsip::impl::Dim_of_view<const_View>::dim > m_view;
> + int num_points = 1;
should be length_type
> + int v_dims = vsip::impl::Dim_of_view<const_View>::dim;
should be dimension_type
> +
> + memset(&m_view,0,sizeof(m_view));
> +
> + // matrix data type
> + m_view.header.type = matlab::miMATRIX;
> + m_view.header.size = 1; // TEMP
> +
> + // array flags
> + m_view.array_flags_header.type = matlab::miUINT32;
> + m_view.array_flags_header.size = 8;
> + if(vsip::impl::Is_complex<T>::value)
> + m_view.array_flags[1] |= 0x8; // Complex
> +
> + // fill in class
> + m_view.array_flags[0] =
> + matlab::Matlab_header_traits<sizeof(scalar_type),
> + std::numeric_limits<scalar_type>::is_signed,
> + std::numeric_limits<scalar_type>::is_integer>::class_type;
> +
> + // make sure we found a matching trait
> + assert(m_view.array_flags[0] != 0);
> +
> + // dimension sizes
> + m_view.dim_header.type = matlab::miINT32;
> + m_view.dim_header.size = v_dims*4; // 4 bytes per dimension
> + // fill in dimension
> + for(int i =0;i<v_dims;i++)
> + {
> + m_view.dim[i] = mbf.view.size(i);
> + num_points *= mbf.view.size(i);
> + }
> +
> + // if this view is a vector, we need to make second dimension a one
> + if(v_dims == 1)
> + {
> + m_view.dim_header.size += 4;
> + m_view.dim[1] = 1;
> + }
> +
> + // array name
> + m_view.array_name_header.type = matlab::miINT8;
> + m_view.array_name_header.size = mbf.name.length();
> +
> +
> + // calculate size
> + sz = sizeof(m_view)-8;
> + sz += mbf.name.length();
> + sz += (8-mbf.name.length())&0x7;
> + sz += 8; // 8 bytes of header for real data
> + if(vsip::impl::Is_complex<T>::value) sz += 8; // 8 more for complex data
> + sz += num_points*sizeof(T);
> + m_view.header.size = sz;
Since m_view.header.size is an 'int32_t', use a cast here:
m_view.header.size = static_cast<int32_t>(sz);
> +
> + o.write(reinterpret_cast<char*>(&m_view),sizeof(m_view));
> +
> + // write array name
> + o.write(mbf.name.c_str(),mbf.name.length());
> + // pad
> + {
> + char c=0;
> + for(int i=0;i < ((8-mbf.name.length())&0x7);i++) o.write(&c,1);
> + }
> +
> + // write data
> + {
> +
> + // make sure we don't need a copy if we use Ext data
> + if(vsip::impl::Ext_data_cost<Block0,
> + typename matlab::Matlab_desired_LP<const_View>::type >::value==0)
> + {
> + vsip::impl::Ext_data<Block0,
> + typename matlab::Matlab_desired_LP<const_View>::type >
> +
> + m_ext(mbf.view.block());
> +
> + temp_data_element.type = matlab::Matlab_header_traits<sizeof(scalar_type),
> + std::numeric_limits<scalar_type>::is_signed,
> + std::numeric_limits<scalar_type>::is_integer>::value_type;
> +
> + temp_data_element.size = num_points*sizeof(scalar_type);
> + for(int i=0;i<=vsip::impl::Is_complex<T>::value;i++)
> + {
> + o.write(reinterpret_cast<char*>(&temp_data_element),
> + sizeof(temp_data_element));
> + if(i==0) o.write(reinterpret_cast<char*>
> + (matlab::get_real_ptr<scalar_type>(m_ext.data())),
> + num_points*sizeof(scalar_type));
> + else o.write(reinterpret_cast<char*>
> + (matlab::get_imag_ptr<scalar_type>(m_ext.data())),
> + num_points*sizeof(scalar_type));
> + }
> + }
> + else
> + {
> + typedef matlab::Subview_helper<const_View<T,Block0> > subview;
> + typedef typename subview::realview_type r_v;
> + typedef typename subview::imagview_type i_v;
> +
> + // conventional way
> + temp_data_element.type = matlab::Matlab_header_traits<sizeof(scalar_type),
> + std::numeric_limits<scalar_type>::is_signed,
> + std::numeric_limits<scalar_type>::is_integer>::value_type;
> +
> + temp_data_element.size = num_points*sizeof(scalar_type);
> + for(int i=0;i<=vsip::impl::Is_complex<T>::value;i++)
> + {
> + o.write(reinterpret_cast<char*>(&temp_data_element),
> + sizeof(temp_data_element));
> + if(i==0) matlab::write<T,r_v>(o,subview::real(mbf.view));
Since subview::real(mbf.view) has value type Scalar_of<SomeType>::type,
it would be cleaner to pass Scalar_of<T>::type instead of T.
> + else matlab::write<T,i_v>(o,subview::imag(mbf.view));
> + }
> + }
> + }
> +
> + return o;
> +}
> +
> +// operator to read matlab header
> +inline
> +std::istream&
> +operator>>(
> + std::istream& o,
> + Matlab_bin_hdr h)
> +{
> + matlab::header m_hdr;
> +
> + // read header
> + o.read(reinterpret_cast<char*>(&m_hdr),sizeof(m_hdr));
> +
> + h.version[1] = m_hdr.version[1];
> + h.version[0] = m_hdr.version[0];
> + h.endian[1] = m_hdr.endian[1];
> + h.endian[0] = m_hdr.endian[0];
> +
> + return o;
> +}
> +
> +// operator to read view from matlab file
> +template <typename T,
> + typename Block0,
> + template <typename,typename> class View>
> +inline
> +std::istream&
> +operator>>(
> + std::istream& is,
> + Matlab_bin_formatter<View<T,Block0> > mbf)
> +{
> + matlab::data_element temp_data_element;
> + matlab::view_header<vsip::impl::Dim_of_view<View>::dim> m_view;
> + typedef typename vsip::impl::Scalar_of<T>::type scalar_type;
> + typedef matlab::Subview_helper<View<T,Block0> > subview;
> + typedef typename subview::realview_type r_v;
> + typedef typename subview::imagview_type i_v;
> + int v_dim = vsip::impl::Dim_of_view<View>::dim;
> +
> +
> + // read header
> + is.read(reinterpret_cast<char*>(&m_view),sizeof(m_view));
> +
> + // is this complex?
> + if(vsip::impl::Is_complex<T>::value && !(m_view.array_flags[1]&0x8))
> + VSIP_IMPL_THROW(std::runtime_error(
> + "Trying to read complex matrix into a real matrix"));
> +
> +
> + // is this the same class?
> + if(!(m_view.array_flags[0] ==
> + (matlab::Matlab_header_traits<sizeof(scalar_type),
> + std::numeric_limits<scalar_type>::is_signed,
> + std::numeric_limits<scalar_type>::is_integer>::class_type)))
> + VSIP_IMPL_THROW(std::runtime_error(
> + "Trying to read a matrix of a different class"));
> +
> + // do dimensions agree?
> + if(v_dim == 1) m_view.dim_header.size -= 4; // special case for vectors
> + if(v_dim != (m_view.dim_header.size/4))
> + VSIP_IMPL_THROW(std::runtime_error(
> + "Trying to read a matrix of different dimensions"));
> +
> + for(int i=0;i<v_dim;i++)
> + if(mbf.view.size(i) != m_view.dim[i])
> + VSIP_IMPL_THROW(std::runtime_error(
> + "Matrix dimensions don't agree"));
> +
> + // read array name
> + if(m_view.array_name_header.type & 0xffff0000)
> + {
> + // array name is short
> +
> + int length = m_view.array_name_header.type >> 16;
> + }
> + else
> + {
> + int length = m_view.array_name_header.size;
> + char c;
> + char c_array[128];
> + // the name is longer than 4 bytes
> + //
> + if(length > 128)
> + VSIP_IMPL_THROW(std::runtime_error(
> + "Name of matrix is too large"));
> +
> + is.read(c_array,length);
> + c_array[length] = 0;
> + // read padding
> + for(int i=0;i<((8-length)&0x7);i++) is.read(&c,1);
> + }
> +
> + // read data, we will go in this loop twice if we have complex data
> + for (int i=0;i <= vsip::impl::Is_complex<T>::value;i++)
> + {
> +
> + // read data header
> + is.read(reinterpret_cast<char*>(&temp_data_element),
> + sizeof(temp_data_element));
> +
> + // Because we don't know how the data was stored, we need to instantiate
> + // generic_reader which can read a type and cast into a different one
> + if(temp_data_element.type == matlab::miINT8)
> + {
> + if(i==0)matlab::read<int8_t,T,r_v>(is,subview::real(mbf.view));
> + else matlab::read<int8_t,T,i_v>(is,subview::imag(mbf.view));
> + }
> + else if(temp_data_element.type == matlab::miUINT8)
> + {
> + if(i==0)matlab::read<uint8_t,T,r_v>(is,subview::real(mbf.view));
> + else matlab::read<uint8_t,T,i_v>(is,subview::imag(mbf.view));
> + }
> + else if(temp_data_element.type == matlab::miINT16)
> + {
> + if(i==0)matlab::read<int16_t,T,r_v>(is,subview::real(mbf.view));
> + else matlab::read<int16_t,T,i_v>(is,subview::imag(mbf.view));
> + }
> + else if(temp_data_element.type == matlab::miUINT16)
> + {
> + if(i==0)matlab::read<uint16_t,T,r_v>(is,subview::real(mbf.view));
> + else matlab::read<uint16_t,T,i_v>(is,subview::imag(mbf.view));
> + }
> + else if(temp_data_element.type == matlab::miINT32)
> + {
> + if(i==0)matlab::read<int32_t,T,r_v>(is,subview::real(mbf.view));
> + else matlab::read<int32_t,T,i_v>(is,subview::imag(mbf.view));
> + }
> + else if(temp_data_element.type == matlab::miUINT32)
> + {
> + if(i==0)matlab::read<uint32_t,T,r_v>(is,subview::real(mbf.view));
> + else matlab::read<uint32_t,T,i_v>(is,subview::imag(mbf.view));
> + }
> + else if(temp_data_element.type == matlab::miSINGLE)
> + {
> + if(i==0)matlab::read<float,T,r_v>(is,subview::real(mbf.view));
> + else matlab::read<float,T,i_v>(is,subview::imag(mbf.view));
> + }
> + else
> + {
> + if(i==0)matlab::read<double,T,r_v>(is,subview::real(mbf.view));
> + else matlab::read<double,T,i_v>(is,subview::imag(mbf.view));
> + }
> +
> + }
> +
> +}
> +
> +
> +
> +} // namespace vsip_csl
> +
> +#endif // VSIP_CSL_MATLAB_BIN_FORMATTER_HPP
> Index: matlab_text_formatter.hpp
> ===================================================================
> RCS file: matlab_text_formatter.hpp
Text formatter looks good.
> Index: output.hpp
> ===================================================================
> RCS file: /home/cvs/Repository/vpp/src/vsip_csl/output.hpp,v
> retrieving revision 1.1
The version of this file in CVS is 1.2, it looks like it has already
been patched.
--
Jules Bergmann
CodeSourcery
jules at codesourcery.com
(650) 331-3385 x705
More information about the vsipl++
mailing list