[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[patch] Matlab IO
- To: VSIPL++ Developers List <vsipl++@xxxxxxxxxxxxxxxx>
- Subject: [patch] Matlab IO
- From: Jules Bergmann <jules@xxxxxxxxxxxxxxxx>
- Date: Wed, 31 Oct 2007 09:54:12 -0400
This patch
- Cleans up parts of the matlab IO interface. In particular,
- fixes endian issues with the iterator interface,
- fixes confusion about writing version,
- adds informative exceptions on failures
- adds comments on file format
- minor renaming for coding standards compliance
- Extends the matlab_bin_file test to also read pre-canned .mat
files in little- and big-endian format.
- Adds a lsmat utility to list contents of a matlab file through
the iterator interface.
Ok to apply?
-- Jules
--
Jules Bergmann
CodeSourcery
jules@xxxxxxxxxxxxxxxx
(650) 331-3385 x705
Index: ChangeLog
===================================================================
--- ChangeLog (revision 186104)
+++ ChangeLog (working copy)
@@ -1,3 +1,27 @@
+2007-10-31 Jules Bergmann <jules@xxxxxxxxxxxxxxxx>
+
+ Matlab IO cleanup.
+ * src/vsip_csl/matlab_file.hpp (header): New function, return file
+ header.
+ * src/vsip_csl/matlab.hpp (File_header): Rename class from 'header'.
+ Add data_type and class_type helper stringify functions.
+ * src/vsip_csl/matlab_bin_formatter.hpp: General cleanup and
+ commenting. Straighten out version handling.
+
+ Extend matlab test coverage.
+ * configure.ac (VSIP_IMPL_TEST_DATA_DIR): New AC_DEFINE.
+ * tests/matlab_bin_file.cpp: Read pre-canned matlab data files
+ for big- and little- endian.
+ * tests/matlab-ref-be.mat: Pre-canned big-endian data file.
+ * tests/matlab-ref-le.mat: Pre-canned little-endian data file.
+
+ New utility to list contents of matlab file.
+ * apps/utils/lsmat.cpp: New file, lists contents of matlab file.
+ * apps/utils/GNUmakefile.inc.in: New file, integrated makefile for
+ apps/utils.
+ * apps/utils/GNUmakefile: New file, standalong makefile for apps/utils
+ * GNUmakefile.in: Include apps/utils/GNUmakefile.inc
+
2007-10-30 Jules Bergmann <jules@xxxxxxxxxxxxxxxx>
* tests/tutorial/matlab_iter_example.cpp (test_write): New function,
Index: configure.ac
===================================================================
--- configure.ac (revision 186094)
+++ configure.ac (working copy)
@@ -2762,7 +2762,11 @@
AC_DEFINE_UNQUOTED(VSIP_IMPL_TEST_LEVEL, $with_test_level,
[Define to set test suite effort level (0, 1, or 2).])
+test_data_dir="`(cd $srcdir/tests; echo \"$PWD\")`"
+AC_DEFINE_UNQUOTED(VSIP_IMPL_TEST_DATA_DIR, ["$test_data_dir"],
+ [Define to set directory holding test data files.])
+
#
# set to allow apps to test which VSIPL++ they are using
#
Index: src/vsip_csl/matlab_file.hpp
===================================================================
--- src/vsip_csl/matlab_file.hpp (revision 186094)
+++ src/vsip_csl/matlab_file.hpp (working copy)
@@ -111,6 +111,8 @@
template <typename,typename> class View>
void read_view(View<T,Block0> view, iterator &iter);
+ Matlab_bin_hdr header() const { return matlab_header_; }
+
private:
Matlab_bin_hdr matlab_header_;
std::ifstream is_;
Index: src/vsip_csl/matlab.hpp
===================================================================
--- src/vsip_csl/matlab.hpp (revision 186094)
+++ src/vsip_csl/matlab.hpp (working copy)
@@ -190,14 +190,17 @@
}
- struct header
- {
- char description[116];
- char subsyt_data[8];
- char version[2];
- vsip::impl::uint16_type endian;
- };
+struct File_header
+{
+ static vsip::length_type const description_size = 116;
+ static vsip::length_type const subsys_data_size = 8;
+ char description[description_size];
+ char subsys_data[subsys_data_size];
+ vsip::impl::uint16_type version;
+ vsip::impl::uint16_type endian;
+};
+
// constants for matlab binary format
// data types
@@ -304,6 +307,61 @@
};
+
+// Return Matlab data type as a string.
+
+inline
+char const*
+data_type(int dt)
+{
+ switch (dt)
+ {
+ case miINT8: return "miINT8";
+ case miUINT8: return "miUINT8";
+ case miINT16: return "miINT16";
+ case miUINT16: return "miUINT16";
+ case miINT32: return "miINT32";
+ case miUINT32: return "miUINT32";
+ case miSINGLE: return "miSINGLE";
+ case miDOUBLE: return "miDOUBLE";
+ case miINT64: return "miINT64";
+ case miUINT64: return "miUINT64";
+ case miMATRIX: return "miMATRIX";
+ case miCOMPRESSED: return "miCOMPRESSED";
+ case miUTF8: return "miUTF8";
+ case miUTF16: return "miUTF16";
+ case miUTF32: return "miUTF32";
+ }
+ return "*unknown*";
+}
+
+
+
+// Return Matlab class type as a string.
+
+inline
+char const*
+class_type(int ct)
+{
+ switch(ct)
+ {
+ case mxCELL_CLASS: return "mxCELL_CLASS";
+ case mxSTRUCT_CLASS: return "mxSTRUCT_CLASS";
+ case mxOBJECT_CLASS: return "mxOBJECT_CLASS";
+ case mxCHAR_CLASS: return "mxCHAR_CLASS";
+ case mxSPARSE_CLASS: return "mxSPARSE_CLASS";
+ case mxDOUBLE_CLASS: return "mxDOUBLE_CLASS";
+ case mxSINGLE_CLASS: return "mxSINGLE_CLASS";
+ case mxINT8_CLASS: return "mxINT8_CLASS";
+ case mxUINT8_CLASS: return "mxUINT8_CLASS";
+ case mxINT16_CLASS: return "mxINT16_CLASS";
+ case mxUINT16_CLASS: return "mxUINT16_CLASS";
+ case mxINT32_CLASS: return "mxINT32_CLASS";
+ case mxUINT32_CLASS: return "mxUINT32_CLASS";
+ }
+ return "*unknown*";
+}
+
} // namesapce matlab
} // namespace vsip_csl
Index: src/vsip_csl/matlab_bin_formatter.hpp
===================================================================
--- src/vsip_csl/matlab_bin_formatter.hpp (revision 186094)
+++ src/vsip_csl/matlab_bin_formatter.hpp (working copy)
@@ -13,28 +13,37 @@
#ifndef VSIP_CSL_MATLAB_BIN_FORMATTER_HPP
#define VSIP_CSL_MATLAB_BIN_FORMATTER_HPP
+#include <sstream>
+#include <string>
+#include <limits>
+
#include <vsip_csl/matlab.hpp>
#include <vsip/core/fns_scalar.hpp>
#include <vsip/core/fns_elementwise.hpp>
#include <vsip/core/metaprogramming.hpp>
#include <vsip/core/view_traits.hpp>
#include <vsip/core/extdata.hpp>
-#include <string>
-#include <limits>
namespace vsip_csl
{
struct Matlab_bin_hdr
{
- Matlab_bin_hdr(std::string const& descr) :
- description(descr),version("MATLAB 5.0 : ") {}
- Matlab_bin_hdr() :
- description(" "),version("MATLAB 5.0 : ") {}
+ Matlab_bin_hdr(std::string const& user_descr)
+ : description ("MATLAB 5.0 : "),
+ version (0x100)
+ {
+ description.append(user_descr);
+ }
+ Matlab_bin_hdr()
+ : description ("MATLAB 5.0 : "),
+ version (0x100)
+ {}
+
// description
- std::string description;
- std::string version;
+ std::string description;
+ vsip::impl::uint16_type version;
vsip::impl::uint16_type endian;
};
@@ -75,21 +84,19 @@
namespace vsip_csl
{
-// operator to write matlab header
+// Write matlab file header.
inline
std::ostream&
operator<<(
std::ostream& o,
Matlab_bin_hdr const& h)
{
- matlab::header m_hdr;
+ matlab::File_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;
+ strncpy(m_hdr.description, h.description.data(), h.description.length());
+ m_hdr.version = 0x0100;
m_hdr.endian = 'M' << 8 | 'I';
// write header
@@ -230,35 +237,70 @@
return o;
}
-// operator to read matlab header
+
+
+// Read matlab file header.
inline
std::istream&
operator>>(
std::istream& is,
- Matlab_bin_hdr &h)
+ Matlab_bin_hdr& h)
{
- matlab::header m_hdr;
+ matlab::File_header m_hdr;
// read header
is.read(reinterpret_cast<char*>(&m_hdr),sizeof(m_hdr));
if(is.gcount() < sizeof(m_hdr))
- VSIP_IMPL_THROW(std::runtime_error("Unexpected end of file"));
+ VSIP_IMPL_THROW(std::runtime_error(
+ "Matlab_bin_hdr: Unexpected end of file"));
- h.version[1] = m_hdr.version[1];
- h.version[0] = m_hdr.version[0];
- h.endian = m_hdr.endian;
+ m_hdr.description[matlab::File_header::description_size-1] = '\0';
+ h.description = std::string(m_hdr.description);
+ h.version = m_hdr.version;
+ h.endian = m_hdr.endian;
+
return is;
}
-// a function to read a matlab view header into a Matlab_view_header class
+
+
+inline void
+skip_padding(std::istream& is, vsip::length_type length)
+{
+ is.ignore((8-length)&0x7);
+}
+
+
+
+// Read a matlab view header into a Matlab_view_header class
+//
+// On disk:
+// | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
+// |-----+-----+-----+-----+-----+-----+-----+-----|
+// | miMATRIX | <size> | < data element header
+//
+// | miUINT32 | 8 | < ARRAY FLAGS
+// | undef | <F> | <C> | undef |
+//
+// | miUINT32 | 12 | < DIMENSIONS ARRAY
+// | dim0 | dim1 | (3-dim shown)
+// | dim2 | padding |
+
+// | 3 | miINT8 | 'a' | 'r' | 'r' | pad | < ARRAY NAME
+//
+//
+// Array Data.
+//
+// Notes:
+// <C> is the class_type, i.e. mxDOUBLE_CLASS, etc.
+//
inline
std::istream&
operator>>(
std::istream& is,
- Matlab_view_header &h)
+ Matlab_view_header& h)
{
-
vsip::impl::uint32_type array_flags[2];
vsip::impl::uint32_type dims[3];
matlab::data_element temp_element;
@@ -268,11 +310,26 @@
swap_bytes = h.swap_bytes;
- // header
+ // 1. Read overall data element header for the object. Identifies:
+ // - type of data element (we can only handle miMATRIX),
+ // - overall size of data element.
is.read(reinterpret_cast<char*>(&temp_element),sizeof(temp_element));
if(is.gcount() < sizeof(temp_element))
- VSIP_IMPL_THROW(std::runtime_error("Unexpected end of file"));
+ VSIP_IMPL_THROW(std::runtime_error(
+ "Matlab_view_header(read): Unexpected end of file"));
+ matlab::swap<vsip::impl::int32_type> (&(temp_element.type),swap_bytes);
matlab::swap<vsip::impl::uint32_type>(&(temp_element.size),swap_bytes);
+
+ if (temp_element.type != matlab::miMATRIX)
+ {
+ std::ostringstream msg;
+ msg << "Matlab_view_header(read): Unsupported data_element type: ";
+ msg << "got " << matlab::data_type(temp_element.type)
+ << " (" << temp_element.type << ")"
+ << ", can only handl miMATRIX (" << matlab::miMATRIX << ")";
+ VSIP_IMPL_THROW(std::runtime_error(msg.str()));
+ }
+
// store the file position of next header
{
std::istream::pos_type curr_pos = is.tellg();
@@ -280,78 +337,127 @@
h.next_header = curr_pos;
}
- // array_flags
+
+ // 2. Read the array_flags.
is.read(reinterpret_cast<char*>(&temp_element),sizeof(temp_element));
if(is.gcount() < sizeof(temp_element))
- VSIP_IMPL_THROW(std::runtime_error("Unexpected end of file"));
+ VSIP_IMPL_THROW(std::runtime_error(
+ "Matlab_view_header(read): Unexpected end of file"));
+ matlab::swap<vsip::impl::int32_type> (&(temp_element.type),swap_bytes);
matlab::swap<vsip::impl::uint32_type>(&(temp_element.size),swap_bytes);
+
+ if (temp_element.type != matlab::miUINT32)
+ {
+ std::ostringstream msg;
+ msg << "Matlab_view_header(read): Unexpected type for array flags: ";
+ msg << "got " << temp_element.type << " bytes, expected miUINT32 (6)";
+ VSIP_IMPL_THROW(std::runtime_error(msg.str()));
+ }
+ if (temp_element.size > 8)
+ {
+ std::ostringstream msg;
+ msg << "Matlab_view_header(read): Length of array flags is too large: ";
+ msg << "got " << temp_element.size << " bytes, expected " << 8 << " bytes";
+ VSIP_IMPL_THROW(std::runtime_error(msg.str()));
+ }
if(temp_element.size > 8)
VSIP_IMPL_THROW(std::runtime_error(
"Length of array flags is too large"));
is.read(reinterpret_cast<char*>(&array_flags),temp_element.size);
if(is.gcount() < temp_element.size)
- VSIP_IMPL_THROW(std::runtime_error("Unexpected end of file"));
+ VSIP_IMPL_THROW(std::runtime_error(
+ "Matlab_view_header(read): Unexpected end of file reading array flags"));
for(index_type i=0;i<temp_element.size/4;i++)
- matlab::swap<vsip::impl::uint32_type>(&(dims[i]),swap_bytes);
+ matlab::swap<vsip::impl::uint32_type>(&(array_flags[i]),swap_bytes);
- // read dimensions
+ // is this complex?
+ h.is_complex = ((array_flags[0]&(1<<11)) == 1);
+ h.class_type = (array_flags[0]&0xff);
+
+
+ // 3. Read dimensions.
is.read(reinterpret_cast<char*>(&temp_element),sizeof(temp_element));
if(is.gcount() < sizeof(temp_element))
- VSIP_IMPL_THROW(std::runtime_error("Unexpected end of file"));
+ VSIP_IMPL_THROW(std::runtime_error(
+ "Matlab_view_header(read): Unexpected end of file reading dimensions (1)"));
+ matlab::swap<vsip::impl::int32_type> (&(temp_element.type),swap_bytes);
matlab::swap<vsip::impl::uint32_type>(&(temp_element.size),swap_bytes);
- if(temp_element.size > 12)
- VSIP_IMPL_THROW(std::runtime_error(
- "Length of dims is too large"));
+
+ if ((temp_element.type & 0x0000ffff) != matlab::miINT32)
+ {
+ std::ostringstream msg;
+ msg << "Matlab_view_header(read): Unexpected type for dimensions array: ";
+ msg << "got " << temp_element.type << ", expected miINT32 (5)";
+ VSIP_IMPL_THROW(std::runtime_error(msg.str()));
+ }
+ if (temp_element.size > 12)
+ {
+ std::ostringstream msg;
+ msg << "Matlab_view_header(read): Number of dimensions is too large: ";
+ msg << "got " << temp_element.size/4 << ", can only handle 3";
+ VSIP_IMPL_THROW(std::runtime_error(msg.str()));
+ }
+
is.read(reinterpret_cast<char*>(&dims),temp_element.size);
if(is.gcount() < temp_element.size)
- VSIP_IMPL_THROW(std::runtime_error("Unexpected end of file"));
- for(index_type i=0;i<temp_element.size/4;i++)
- matlab::swap<vsip::impl::uint32_type>(&(dims[i]),swap_bytes);
+ VSIP_IMPL_THROW(std::runtime_error(
+ "Matlab_view_header(read): Unexpected end of file reading dimensions (2)"));
+ skip_padding(is, temp_element.size);
- // read padding
- is.ignore((8-temp_element.size)&0x7);
-
h.num_dims = temp_element.size/4;
for(index_type i=0;i<temp_element.size/4;i++)
+ {
+ matlab::swap<vsip::impl::uint32_type>(&(dims[i]),swap_bytes);
h.dims[i] = dims[i];
+ }
- // is this complex?
- h.is_complex = ((array_flags[0]&(1<<11)) == 1);
- h.class_type = (array_flags[0]&0xff);
- // read array name
+ // 4. Read array name.
is.read(reinterpret_cast<char*>(&temp_element),sizeof(temp_element));
if(is.gcount() < sizeof(temp_element))
- VSIP_IMPL_THROW(std::runtime_error("Unexpected end of file"));
+ VSIP_IMPL_THROW(std::runtime_error(
+ "Matlab_view_header(read): Unexpected end of file reading array name (1)"));
matlab::swap<vsip::impl::int32_type>(&(temp_element.type),swap_bytes);
- matlab::swap<vsip::impl::uint32_type>(&(temp_element.size),swap_bytes);
+ // Don't swab the length yet, it may be a string.
+
+ if ((temp_element.type & 0x0000ffff) != matlab::miINT8)
+ {
+ std::ostringstream msg;
+ msg << "Matlab_view_header(read): Unexpected type for array name: ";
+ msg << "got " << matlab::data_type(temp_element.type)
+ << " (" << temp_element.type << "),"
+ << " expected miINT8 (" << matlab::miINT8 << ")";
+ VSIP_IMPL_THROW(std::runtime_error(msg.str()));
+ }
+
if(temp_element.type & 0xffff0000)
{
+ int length = (temp_element.type & 0xffff0000) >> 16;
// array name is short
- strcpy(h.array_name,
- reinterpret_cast<char*>(&temp_element.size));
-
+ strncpy(h.array_name, reinterpret_cast<char*>(&temp_element.size), length);
+ h.array_name[length] = 0;
}
else
{
+ matlab::swap<vsip::impl::uint32_type>(&(temp_element.size),swap_bytes);
int length = temp_element.size;
// the name is longer than 4 bytes
if(length > 128)
- VSIP_IMPL_THROW(std::runtime_error(
- "Name of view is too large"));
+ VSIP_IMPL_THROW(std::runtime_error("Name of view is too large"));
is.read(h.array_name,length);
if(is.gcount() < length)
- VSIP_IMPL_THROW(std::runtime_error("Unexpected end of file"));
+ VSIP_IMPL_THROW(std::runtime_error(
+ "Matlab_view_header(read): Unexpected end of file reading array name (2)"));
h.array_name[length] = 0;
- // read padding
- is.ignore((8-length)&0x7);
+ skip_padding(is, length);
}
return is;
}
+
// operator to read view from matlab file
template <typename T,
typename Block0,
@@ -382,7 +488,8 @@
// read header
is.read(reinterpret_cast<char*>(&m_view),sizeof(m_view));
if(is.gcount() < sizeof(m_view))
- VSIP_IMPL_THROW(std::runtime_error("Unexpected end of file"));
+ VSIP_IMPL_THROW(std::runtime_error(
+ "Matlab_bin_formatter(read): Unexpected end of file (1)"));
// do we need to swap fields?
matlab::swap_header(m_view,swap_value);
@@ -443,7 +550,8 @@
is.read(reinterpret_cast<char*>(&temp_data_element),
sizeof(temp_data_element));
if(is.gcount() < sizeof(temp_data_element))
- VSIP_IMPL_THROW(std::runtime_error("Unexpected end of file"));
+ VSIP_IMPL_THROW(std::runtime_error(
+ "Matlab_bin_formatter(read): Unexpected end of file (2)"));
// should we swap this field?
matlab::swap<vsip::impl::int32_type>(&(temp_data_element.type),swap_value);
Index: tests/matlab-ref-le.mat
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: tests/matlab-ref-le.mat
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Index: tests/matlab_bin_file.cpp
===================================================================
--- tests/matlab_bin_file.cpp (revision 185668)
+++ tests/matlab_bin_file.cpp (working copy)
@@ -26,6 +26,9 @@
#include <vsip_csl/output.hpp>
#include <vsip_csl/test.hpp>
+#define VSIP_IMPL_TEST_DATA_FILE(FILE) \
+ VSIP_IMPL_TEST_DATA_DIR "/" FILE
+
#define DEBUG 0
using namespace vsip;
@@ -161,56 +164,74 @@
#if DEBUG == 1
cout << a << endl;
#endif
-
}
-int main()
+
+void
+write_file(char const* name)
{
+ std::ofstream ofs(name);
- {
- std::ofstream ofs("temp.mat");
+ // write header
+ ofs << Matlab_bin_hdr("example");
- // write header
- ofs << Matlab_bin_hdr("example");
-
- // tests
+ // tests
+ vector_test<float> (5,ofs,"float_vector");
+ vector_test<double> (5,ofs,"double_vector");
+ vector_test<complex<float> > (5,ofs,"cplx_float_vector");
+ vector_test<complex<double> > (5,ofs,"cplx_double_vector");
- vector_test<float> (5,ofs,"float_vector");
- vector_test<double> (5,ofs,"double_vector");
- vector_test<complex<float> > (5,ofs,"cplx_float_vector");
- vector_test<complex<double> > (5,ofs,"cplx_double_vector");
+ matrix_test<float> (2,3,ofs,"float_matrix");
+ matrix_test<double> (2,3,ofs,"double_matrix");
+ matrix_test<complex<float> > (2,3,ofs,"cplx_float_matrix");
+ matrix_test<complex<double> > (2,3,ofs,"cplx_double_matrix");
- matrix_test<float> (2,3,ofs,"float_matrix");
- matrix_test<double> (2,3,ofs,"double_matrix");
- matrix_test<complex<float> > (2,3,ofs,"cplx_float_matrix");
- matrix_test<complex<double> > (2,3,ofs,"cplx_double_matrix");
+ tensor_test<float> (3,2,3,ofs,"float_tensor");
+ tensor_test<double> (3,2,3,ofs,"double_tensor");
+ tensor_test<complex<float> > (3,2,3,ofs,"cplx_float_tensor");
+ tensor_test<complex<double> > (3,2,3,ofs,"cplx_double_tensor");
+}
- tensor_test<float> (3,2,3,ofs,"float_tensor");
- tensor_test<double> (3,2,3,ofs,"double_tensor");
- tensor_test<complex<float> > (3,2,3,ofs,"cplx_float_tensor");
- tensor_test<complex<double> > (3,2,3,ofs,"cplx_double_tensor");
- }
+
+
+void
+read_file(char const* name)
+{
+ std::ifstream ifs(name);
+
+ // Skip header
+ Matlab_bin_hdr h;
+ ifs >> h;
+
+ vector_input_test<float> (5,ifs,"float_vector",h);
+ vector_input_test<double> (5,ifs,"double_vector",h);
+ vector_input_test<complex<float> > (5,ifs,"float_vector",h);
+ vector_input_test<complex<double> > (5,ifs,"double_vector",h);
+
+ matrix_input_test<float> (2,3,ifs,"float_matrix",h);
+ matrix_input_test<double> (2,3,ifs,"double_matrix",h);
+ matrix_input_test<complex<float> > (2,3,ifs,"cplx_float_matrix",h);
+ matrix_input_test<complex<double> > (2,3,ifs,"cplx_double_matrix",h);
- {
- Matlab_bin_hdr h;
+ tensor_input_test<float> (3,2,3,ifs,"float_tensor",h);
+ tensor_input_test<double> (3,2,3,ifs,"double_tensor",h);
+ tensor_input_test<complex<float> > (3,2,3,ifs,"cplx_float_tensor",h);
+ tensor_input_test<complex<double> > (3,2,3,ifs,"cplx_double_tensor",h);
+}
- std::ifstream ifs("temp.mat");
- ifs >> h;
- vector_input_test<float> (5,ifs,"float_vector",h);
- vector_input_test<double> (5,ifs,"double_vector",h);
- vector_input_test<complex<float> > (5,ifs,"float_vector",h);
- vector_input_test<complex<double> > (5,ifs,"double_vector",h);
- matrix_input_test<float> (2,3,ifs,"float_matrix",h);
- matrix_input_test<double> (2,3,ifs,"double_matrix",h);
- matrix_input_test<complex<float> > (2,3,ifs,"cplx_float_matrix",h);
- matrix_input_test<complex<double> > (2,3,ifs,"cplx_double_matrix",h);
- tensor_input_test<float> (3,2,3,ifs,"float_tensor",h);
- tensor_input_test<double> (3,2,3,ifs,"double_tensor",h);
- tensor_input_test<complex<float> > (3,2,3,ifs,"cplx_float_tensor",h);
- tensor_input_test<complex<double> > (3,2,3,ifs,"cplx_double_tensor",h);
- }
+int main()
+{
+ write_file("temp.mat");
+ read_file("temp.mat"); // Read what we just wrote.
+
+ // Reference big-endian file.
+ read_file(VSIP_IMPL_TEST_DATA_FILE("matlab-ref-be.mat"));
+
+ // Reference little-endian file.
+ read_file(VSIP_IMPL_TEST_DATA_FILE("matlab-ref-le.mat"));
+
return 0;
}
Index: tests/matlab-ref-be.mat
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: tests/matlab-ref-be.mat
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Index: apps/utils/lsmat.cpp
===================================================================
--- apps/utils/lsmat.cpp (revision 0)
+++ apps/utils/lsmat.cpp (revision 0)
@@ -0,0 +1,148 @@
+/* Copyright (c) 2007 by CodeSourcery. All rights reserved.
+
+ This file is available for license from CodeSourcery, Inc. under the terms
+ of a commercial license and under the GPL. It is not part of the VSIPL++
+ reference implementation and is not available under the BSD license.
+*/
+
+/** @file apps/utils/lsmat.cpp
+ @author Jules Bergmann
+ @date 2007-07-13
+ @brief VSIPL++ Library: List views contained in .mat file.
+*/
+
+/***********************************************************************
+ Included Files
+***********************************************************************/
+
+#include <iostream>
+#include <fstream>
+
+#include <vsip/initfin.hpp>
+#include <vsip/vector.hpp>
+#include <vsip/matrix.hpp>
+#include <vsip/tensor.hpp>
+#include <vsip/selgen.hpp>
+#include <vsip/map.hpp>
+
+#include <vsip_csl/matlab_file.hpp>
+#include <vsip_csl/output.hpp>
+
+using namespace std;
+using namespace vsip;
+using namespace vsip_csl;
+
+
+
+/***********************************************************************
+ Definitions
+***********************************************************************/
+
+template <dimension_type Dim,
+ typename T>
+void
+load_view(
+ Matlab_file& mf,
+ Matlab_file::iterator& iter,
+ Domain<Dim> const& dom)
+{
+ typedef Dense<Dim, T> block_type;
+ typedef typename impl::View_of_dim<Dim, T, block_type>::type view_type;
+
+ block_type block(dom);
+ view_type view(block);
+
+ mf.read_view(view, iter);
+
+ cout << view;
+}
+
+
+
+void
+lsmat(char const* fname)
+{
+ // Create Matlab_file object for 'sample.mat' file.
+ Matlab_file mf(fname);
+ Matlab_file::iterator cur = mf.begin();
+ Matlab_file::iterator end = mf.end();
+
+ Matlab_bin_hdr hdr = mf.header();
+
+ cout << "Matlab file: " << fname << endl;
+ cout << " descr : " << hdr.description << endl;
+ cout << " version: " << hdr.version << endl;
+ cout << " endian : " << hdr.endian
+ << " (swap: "
+ << (hdr.endian == ('I'<<8 | 'M') ? "yes" :
+ hdr.endian == ('M'<<8 | 'I') ? "no" : "*unknown*")
+ << ")" << endl;
+
+
+ // Iterate through views in file.
+ while (cur != end)
+ {
+ Matlab_view_header* hdr = *cur;
+
+ cout << "view: " << hdr->array_name << endl;
+
+ // Dump array_name out by byte
+ // for (int i=0; hdr->array_name[i] != 0 && i<128; ++i)
+ // cout << " [" << i << "]: " << (int)hdr->array_name[i] << endl;
+
+ cout << " dim : " << hdr->num_dims;
+ if (hdr->num_dims > 0)
+ {
+ char* sep = " (";
+ for (index_type i=0; i<hdr->num_dims; ++i)
+ {
+ cout << sep << hdr->dims[i];
+ sep = ", ";
+ }
+ cout << ")";
+ }
+ cout << endl;
+
+ cout << " is_complex: " << (hdr->is_complex ? "true" : "false") << endl;
+ cout << " class_type: " << vsip_csl::matlab::class_type(hdr->class_type);
+ cout << " (" << (int)hdr->class_type << ")" << endl;
+
+ if (hdr->class_type == vsip_csl::matlab::mxDOUBLE_CLASS)
+ {
+ if (hdr->num_dims == 2 && hdr->dims[0] == 1)
+ load_view<1, double>(mf, cur, Domain<1>(hdr->dims[1]));
+ else if (hdr->num_dims == 2 && hdr->dims[1] == 1)
+ load_view<1, double>(mf, cur, Domain<1>(hdr->dims[0]));
+ else if (hdr->num_dims == 2)
+ load_view<2, double>(mf, cur, Domain<2>(hdr->dims[0], hdr->dims[1]));
+// else if (hdr->num_dims == 3)
+// load_view<3, double>(mf, cur, Domain<3>(hdr->dims[0], hdr->dims[1],
+// hdr->dims[2]));
+ }
+ else if (hdr->class_type == vsip_csl::matlab::mxSINGLE_CLASS)
+ {
+ if (hdr->num_dims == 2 && hdr->dims[0] == 1)
+ load_view<1, float>(mf, cur, Domain<1>(hdr->dims[1]));
+ else if (hdr->num_dims == 2 && hdr->dims[1] == 1)
+ load_view<1, float>(mf, cur, Domain<1>(hdr->dims[0]));
+ else if (hdr->num_dims == 2)
+ load_view<2, float>(mf, cur, Domain<2>(hdr->dims[0], hdr->dims[1]));
+// else if (hdr->num_dims == 3)
+// load_view<3, float>(mf, cur, Domain<3>(hdr->dims[0], hdr->dims[1],
+// hdr->dims[2]));
+ }
+
+ ++cur; // Move to next view stored in the file.
+ }
+}
+
+
+int
+main(int argc, char** argv)
+{
+ (void)argc;
+ char* fname = argv[1];
+
+ lsmat(fname);
+}
+
Index: apps/utils/GNUmakefile.inc.in
===================================================================
--- apps/utils/GNUmakefile.inc.in (revision 0)
+++ apps/utils/GNUmakefile.inc.in (revision 0)
@@ -0,0 +1,71 @@
+######################################################### -*-Makefile-*-
+#
+# File: GNUmakefile.inc
+# Author: Jules Bergmann
+# Date: 2007-10-30
+#
+# Contents: Makefile fragment for apps/utils.
+#
+########################################################################
+
+# Files in this directory are not available under the BSD license, so
+# avoid putting them into cxx_sources, building them, installing them,
+# etc. when building the reference implementation.
+ifndef VSIP_IMPL_REF_IMPL
+
+########################################################################
+# Variables
+########################################################################
+
+apps_utils_CXXINCLUDES := -I$(srcdir)/src -I$(srcdir)/tests \
+ -I$(srcdir)/apps/utils
+apps_utils_CXXFLAGS := $(apps_utils_CXXINCLUDES)
+
+apps_utils_cxx_sources := $(wildcard $(srcdir)/apps/utils/*.cpp)
+apps_utils_cxx_headers := $(wildcard $(srcdir)/apps/utils/*.hpp)
+
+apps_utils_obj := $(patsubst $(srcdir)/%.cpp, %.$(OBJEXT), $(apps_utils_cxx_sources))
+apps_utils_exe := $(patsubst $(srcdir)/%.cpp, %$(EXEEXT), $(apps_utils_cxx_sources))
+apps_utils_targets := $(apps_utils_exe)
+
+cxx_sources += $(apps_utils_cxx_sources)
+
+apps_utils_install_sources := $(apps_utils_cxx_sources) $(apps_utils_cxx_headers)
+
+apps_utils_install_targets := $(patsubst $(srcdir)/%, %, $(apps_utils_install_sources))
+
+apps_utils_static_targets := $(patsubst %$(EXEEXT), \
+ %.static$(EXEEXT), \
+ $(apps_utils_targets))
+
+
+########################################################################
+# Rules
+########################################################################
+
+apps_utils:: $(apps_utils_targets)
+
+# Object files will be deleted by the parent clean rule.
+clean::
+ rm -f $(apps_utils_targets) $(apps_utils_static_targets)
+
+# Install benchmark source code and executables
+install-apps_utils:: apps_utils
+ $(INSTALL) -d $(DESTDIR)$(pkgdatadir)/apps/utils
+ $(INSTALL_DATA) apps/utils/GNUmakefile \
+ $(DESTDIR)$(pkgdatadir)/apps/utils/GNUmakefile
+ for sourcefile in $(apps_utils_install_targets); do \
+ $(INSTALL_DATA) $(srcdir)/$$sourcefile $(DESTDIR)$(pkgdatadir)/`dirname $$sourcefile`; \
+ done
+ $(INSTALL) -d $(DESTDIR)$(exec_prefix)/apps/utils
+ for binfile in $(apps_utils_targets); do \
+ $(INSTALL) $$binfile $(DESTDIR)$(exec_prefix)/`dirname $$binfile`; \
+ done
+
+$(apps_utils_targets): %$(EXEEXT) : %.$(OBJEXT) $(libs)
+ $(CXX) $(LDFLAGS) -o $@ $^ -Llib -lsvpp -lvsip_csl $(LIBS) || rm -f $@
+
+$(apps_utils_static_targets): %.static$(EXEEXT) : %.$(OBJEXT) $(libs)
+ $(CXX) -static $(LDFLAGS) -o $@ $^ -Llib -lsvpp -lvsip_csl $(LIBS) || rm -f $@
+
+endif # VSIP_IMPL_REF_IMPL
Index: apps/utils/GNUmakefile
===================================================================
--- apps/utils/GNUmakefile (revision 0)
+++ apps/utils/GNUmakefile (revision 0)
@@ -0,0 +1,76 @@
+########################################################################
+#
+# File: GNUmakefile
+# Author: Jules Bergmann
+# Date: 2007-07-13
+#
+# Contents: Standalone Makefile for VSIPL++ apps/utils.
+#
+########################################################################
+
+PKG = vsipl++
+
+CXX := $(shell pkg-config --variable=cxx $(PKG))
+OPT := $(shell pkg-config --variable=cxxflags $(PKG))
+CXXFLAGS := $(shell pkg-config --cflags $(PKG)) $(OPT)
+CFLAGS := $(CXXFLAGS)
+LIBS := $(shell pkg-config --libs $(PKG))
+
+OBJEXT := o
+
+cxx_sources := $(wildcard *.cpp)
+c_sources := $(wildcard *.c)
+
+objects := $(patsubst %.cpp, %.$(OBJEXT), $(cxx_sources)) \
+ $(patsubst %.c, %.$(OBJEXT), $(c_sources))
+deps := $(patsubst %.cpp, %.d, $(cxx_sources))
+
+
+
+########################################################################
+# Standard Targets
+########################################################################
+
+all::
+
+depend:: $(deps)
+
+clean::
+
+ifeq (,$(filter $(MAKECMDGOALS), depend doc clean))
+include $(deps)
+endif
+
+ifneq (,$(findstring depend, $(MAKECMDGOALS)))
+$(deps): %.d: .FORCE
+endif
+
+
+
+########################################################################
+# Application Targets
+########################################################################
+
+all:: $(APPS)
+
+lsmat: lsmat.o
+ $(CXX) $(OPT) -o $@ $^ $(LIBS)
+
+clean::
+ rm -f $(objects)
+ rm -f $(deps)
+ rm -f *.raw
+
+
+
+########################################################################
+# Implicit Rules
+########################################################################
+
+# Generate a dependency Makefile fragment for a C++ source file.
+# (This recipe is taken from the GNU Make manual.)
+%.d: %.cpp
+ $(SHELL) -ec '$(CXX) -M $(CXXFLAGS) \
+ $(call dir_var,$(dir $<),CXXFLAGS) $< \
+ | sed "s|$(*F)\\.$(OBJEXT)[ :]*|$*\\.d $*\\.$(OBJEXT) : |g" > $@'
+