From 10bd43dc8d48171100cba4f3bd3e66bd8da56e17 Mon Sep 17 00:00:00 2001 From: Matthias Peschke Date: Tue, 8 Dec 2020 09:48:42 +0100 Subject: [PATCH 01/29] Reimplemented the Tensor stream output. The implementation structure is based on the IO for Eigen::Matrix. Predefined formats in namespace Eigen::IOFormats are defined for numpy-like output, native output and short output. More can be added. Rebase. --- unsupported/Eigen/CXX11/Tensor | 4 +- .../Eigen/CXX11/src/Tensor/TensorBase.h | 6 + unsupported/Eigen/CXX11/src/Tensor/TensorIO.h | 403 ++++++++++++++++-- 3 files changed, 366 insertions(+), 47 deletions(-) diff --git a/unsupported/Eigen/CXX11/Tensor b/unsupported/Eigen/CXX11/Tensor index 1b8b33f89..f88ddc514 100644 --- a/unsupported/Eigen/CXX11/Tensor +++ b/unsupported/Eigen/CXX11/Tensor @@ -76,6 +76,8 @@ #include "src/Tensor/TensorIntDiv.h" #include "src/Tensor/TensorGlobalFunctions.h" +#include "src/Tensor/TensorIO.h" + #include "src/Tensor/TensorBase.h" #include "src/Tensor/TensorBlock.h" @@ -129,7 +131,7 @@ #include "src/Tensor/TensorMap.h" #include "src/Tensor/TensorRef.h" -#include "src/Tensor/TensorIO.h" + #include "../../../Eigen/src/Core/util/ReenableStupidWarnings.h" diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorBase.h b/unsupported/Eigen/CXX11/src/Tensor/TensorBase.h index 68aced516..5ede21914 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/TensorBase.h +++ b/unsupported/Eigen/CXX11/src/Tensor/TensorBase.h @@ -962,6 +962,12 @@ class TensorBase return TensorForcedEvalOp(derived()); } + // Returns a formatted tensor ready for printing to a stream + inline const TensorWithFormat format(const TensorIOFormat& fmt) const + { + return TensorWithFormat(derived(), fmt); + } + #ifdef EIGEN_READONLY_TENSORBASE_PLUGIN #include EIGEN_READONLY_TENSORBASE_PLUGIN #endif diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h b/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h index f47973b74..cc21b2965 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h +++ b/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h @@ -14,68 +14,379 @@ namespace Eigen { +struct TensorIOFormat; + namespace internal { +template struct TensorPrinter; +} -// Print the tensor as a 2d matrix -template -struct TensorPrinter { - static void run (std::ostream& os, const Tensor& tensor) { - typedef typename internal::remove_const::type Scalar; - typedef typename Tensor::Index Index; - const Index total_size = internal::array_prod(tensor.dimensions()); - if (total_size > 0) { - const Index first_dim = Eigen::internal::array_get<0>(tensor.dimensions()); - static const int layout = Tensor::Layout; - Map > matrix(const_cast(tensor.data()), first_dim, total_size/first_dim); - os << matrix; +struct TensorIOFormat +{ + TensorIOFormat(const std::vector& _separator, const std::vector& _prefix, const std::vector& _suffix, + int _precision = StreamPrecision, int _flags = 0, const std::string& _tenPrefix="", const std::string& _tenSuffix="", const char _fill=' ') + : tenPrefix(_tenPrefix), tenSuffix(_tenSuffix), prefix(_prefix), suffix(_suffix), separator(_separator), + fill(_fill), precision(_precision), flags(_flags) { + init_spacer(); + } + + TensorIOFormat(int _precision = StreamPrecision, int _flags = 0, const std::string& _tenPrefix="", const std::string& _tenSuffix="", const char _fill=' ') + : tenPrefix(_tenPrefix), tenSuffix(_tenSuffix), fill(_fill), precision(_precision), flags(_flags) { + // default values of prefix, suffix and separator + prefix = {"", "["}; + suffix = {"", "]"}; + separator = {", ", "\n"}; + + init_spacer(); + } + + void init_spacer() { + if((flags & DontAlignCols)) + return; + spacer.resize(prefix.size()); + spacer[0] = ""; + int i = int(tenPrefix.length())-1; + while (i>=0 && tenPrefix[i]!='\n') { + spacer[0] += ' '; + i--; + } + + for (std::size_t k=1; k=0 && prefix[k][i]!='\n') { + spacer[k] += ' '; + i--; + } + } } - } + + std::string tenPrefix; + std::string tenSuffix; + std::vector prefix; + std::vector suffix; + std::vector separator; + char fill; + int precision; + int flags; + std::vector spacer{}; + bool legacy_bit = false; }; +namespace internal { + TensorIOFormat gen_numpy_format() { + return TensorIOFormat(StreamPrecision, 0, "array([" , "])"); + } -// Print the tensor as a vector -template -struct TensorPrinter { - static void run (std::ostream& os, const Tensor& tensor) { - typedef typename internal::remove_const::type Scalar; - typedef typename Tensor::Index Index; - const Index total_size = internal::array_prod(tensor.dimensions()); - if (total_size > 0) { - Map > array(const_cast(tensor.data()), total_size); - os << array; + TensorIOFormat gen_short_format() { + std::vector separator = {", "}; + std::vector prefix = {""}; + std::vector suffix = {""}; + + TensorIOFormat ShortFormat(separator, prefix, suffix, StreamPrecision, 1, " << " , ";"); + return ShortFormat; + } + + TensorIOFormat gen_plain_format() { + std::vector separator = {" ", "\n", "\n", ""}; + std::vector prefix = {""}; + std::vector suffix = {""}; + + TensorIOFormat PlainFormat(separator, prefix, suffix, StreamPrecision, 0, "" , "", ' '); + return PlainFormat; + } + + TensorIOFormat gen_native_format() { + std::vector separator = {", ", ""}; + std::vector prefix = {"", "{"}; + std::vector suffix = {"", "}"}; + + TensorIOFormat EigenFormat(separator, prefix, suffix, StreamPrecision, 0, "{" , "}", ' '); + return EigenFormat; + } + + TensorIOFormat gen_legacy_format() { + TensorIOFormat LegacyFormat(StreamPrecision, 0, "", "", ' '); + LegacyFormat.legacy_bit = true; + return LegacyFormat; + } +} // namespace internal + +namespace IOFormats { + const TensorIOFormat Numpy = internal::gen_numpy_format(); + + const TensorIOFormat Short = internal::gen_short_format(); + + const TensorIOFormat Plain = internal::gen_plain_format(); + + const TensorIOFormat Native = internal::gen_native_format(); + + const TensorIOFormat Legacy = internal::gen_legacy_format(); +} + +template class TensorWithFormat; +//specialize for Layout=ColMajor, Layout=RowMajor and rank=0. +template +class TensorWithFormat +{ +public: + + TensorWithFormat(const T& tensor, const TensorIOFormat& format) + : t_tensor(tensor), t_format(format) {} + + friend std::ostream & operator << (std::ostream & os, const TensorWithFormat& wf) { + // Evaluate the expression if needed + typedef TensorEvaluator, DefaultDevice> Evaluator; + TensorForcedEvalOp eval = wf.t_tensor.eval(); + Evaluator tensor(eval, DefaultDevice()); + tensor.evalSubExprsIfNeeded(NULL); + internal::TensorPrinter::run(os, tensor, wf.t_format); + // Cleanup. + tensor.cleanup(); + return os; } - } + +protected: + T t_tensor; + TensorIOFormat t_format; }; +template +class TensorWithFormat +{ +public: + TensorWithFormat(const T& tensor, const TensorIOFormat& format) + : t_tensor(tensor), t_format(format) {} -// Print the tensor as a scalar -template -struct TensorPrinter { - static void run (std::ostream& os, const Tensor& tensor) { - os << tensor.coeff(0); - } + friend std::ostream & operator << (std::ostream & os, const TensorWithFormat& wf) { + // Switch to RowMajor storage and print afterwards + typedef typename T::Index Index; + std::array shuffle; + std::array id; std::iota(id.begin(), id.end(), Index(0)); + std::copy(id.begin(), id.end(), shuffle.rbegin()); + auto tensor_row_major = wf.t_tensor.swap_layout().shuffle(shuffle); + + // Evaluate the expression if needed + typedef TensorEvaluator, DefaultDevice> Evaluator; + TensorForcedEvalOp eval = tensor_row_major.eval(); + Evaluator tensor(eval, DefaultDevice()); + tensor.evalSubExprsIfNeeded(NULL); + internal::TensorPrinter::run(os, tensor, wf.t_format); + // Cleanup. + tensor.cleanup(); + return os; + } + +protected: + T t_tensor; + TensorIOFormat t_format; }; -} -template -std::ostream& operator << (std::ostream& os, const TensorBase& expr) { - typedef TensorEvaluator, DefaultDevice> Evaluator; - typedef typename Evaluator::Dimensions Dimensions; +template +class TensorWithFormat +{ +public: + TensorWithFormat(const T& tensor, const TensorIOFormat& format) + : t_tensor(tensor), t_format(format) {} + + friend std::ostream & operator << (std::ostream & os, const TensorWithFormat& wf) { + // Evaluate the expression if needed + typedef TensorEvaluator, DefaultDevice> Evaluator; + TensorForcedEvalOp eval = wf.t_tensor.eval(); + Evaluator tensor(eval, DefaultDevice()); + tensor.evalSubExprsIfNeeded(NULL); + internal::TensorPrinter::run(os, tensor, wf.t_format); + // Cleanup. + tensor.cleanup(); + return os; + } + +protected: + T t_tensor; + TensorIOFormat t_format; +}; + +namespace internal { +template +struct TensorPrinter { + static void run (std::ostream& s, const Tensor& _t, const TensorIOFormat& fmt) { + typedef typename Tensor::Scalar Scalar; + typedef typename Tensor::Index Index; + static const int layout = Tensor::Layout; + // backwards compatibility case: print tensor after reshaping to matrix of size dim(0) x (dim(1)*dim(2)*...*dim(rank-1)). + if (fmt.legacy_bit) { + const Index total_size = internal::array_prod(_t.dimensions()); + if (total_size > 0) { + const Index first_dim = Eigen::internal::array_get<0>(_t.dimensions()); + Map > matrix(const_cast(_t.data()), first_dim, total_size/first_dim); + s << matrix; + return; + } + } + + assert(layout == RowMajor); + //from here on we have a tensor in RowMajor storage - // Evaluate the expression if needed - TensorForcedEvalOp eval = expr.eval(); - Evaluator tensor(eval, DefaultDevice()); - tensor.evalSubExprsIfNeeded(NULL); + typedef typename + conditional< + is_same::value || + is_same::value || + is_same::value || + is_same::value, + int, + typename conditional< + is_same >::value || + is_same >::value || + is_same >::value || + is_same >::value, + std::complex, + const Scalar& + >::type + >::type PrintType; - // Print the result - static const int rank = internal::array_size::value; - internal::TensorPrinter::run(os, tensor); + const Index total_size = array_prod(_t.dimensions()); - // Cleanup. - tensor.cleanup(); - return os; -} + std::streamsize explicit_precision; + if(fmt.precision == StreamPrecision) { + explicit_precision = 0; + } + else if(fmt.precision == FullPrecision) { + if (NumTraits::IsInteger) { + explicit_precision = 0; + } + else { + explicit_precision = significant_decimals_impl::run(); + } + } + else { + explicit_precision = fmt.precision; + } + + std::streamsize old_precision = 0; + if(explicit_precision) old_precision = s.precision(explicit_precision); + + Index width = 0; + + bool align_cols = !(fmt.flags & DontAlignCols); + if(align_cols) { + // compute the largest width + for (Index i=0; i(_t.data()[i]); + width = std::max(width, Index(sstr.str().length())); + } + } + std::streamsize old_width = s.width(); + char old_fill_character = s.fill(); + + s << fmt.tenPrefix; + for (Index i = 0; i is_at_end{}; + std::array is_at_begin{}; + //is the ith element the end of an coeff (always true), of a row, of a matrix, ...? + for (std::size_t k=0; k())) == 0) { + is_at_end[k] = true; + } + } + + //is the ith element the begin of an coeff (always true), of a row, of a matrix, ...? + for (std::size_t k=0; k())) == 0) { + is_at_begin[k] = true; + } + } + + //do we have a line break? + bool is_at_begin_after_newline = false; + for (std::size_t k=0; k=0; k--) { + std::size_t prefix_index = (static_cast(k) < fmt.prefix.size()) ? k : fmt.prefix.size()-1; + if (is_at_begin[k]) {prefix << fmt.prefix[prefix_index];} + } + + s << prefix.str(); + if(width) { + s.fill(fmt.fill); + s.width(width); + s << std::left; + } + s << _t.data()[i]; + s << suffix.str(); + if (i < total_size -1) {s << separator.str();} + } + s << fmt.tenSuffix; + if(explicit_precision) s.precision(old_precision); + if(width) { + s.fill(old_fill_character); + s.width(old_width); + } + } +}; + +template +struct TensorPrinter { + static void run (std::ostream& s, const Tensor& _t, const TensorIOFormat& fmt) { + typedef typename Tensor::Scalar Scalar; + + std::streamsize explicit_precision; + if(fmt.precision == StreamPrecision) { + explicit_precision = 0; + } + else if(fmt.precision == FullPrecision) { + if (NumTraits::IsInteger) { + explicit_precision = 0; + } + else { + explicit_precision = significant_decimals_impl::run(); + } + } + else { + explicit_precision = fmt.precision; + } + + std::streamsize old_precision = 0; + if(explicit_precision) old_precision = s.precision(explicit_precision); + + s << fmt.tenPrefix << _t.coeff(0) << fmt.tenSuffix; + if(explicit_precision) s.precision(old_precision); + } +}; + +} // end namespace internal +template +std::ostream & operator <<(std::ostream & s, const TensorBase & t) +{ + s << t.format(IOFormats::Legacy); + return s; +} } // end namespace Eigen #endif // EIGEN_CXX11_TENSOR_TENSOR_IO_H -- GitLab From cd416a8d1871dee4381dde407fdd3677ad252b63 Mon Sep 17 00:00:00 2001 From: Matthias Peschke Date: Wed, 3 Mar 2021 10:26:41 +0100 Subject: [PATCH 02/29] Improved the new Tensor stream operator, implementation is now fully c++11 compliant. Added test case for the Tensor stream operator. Added documentation for the Tensor stream operator. Rebase. --- unsupported/Eigen/CXX11/src/Tensor/README.md | 39 ++++ .../Eigen/CXX11/src/Tensor/TensorBase.h | 3 +- unsupported/test/cxx11_tensor_io.cpp | 212 ++++++++---------- 3 files changed, 138 insertions(+), 116 deletions(-) diff --git a/unsupported/Eigen/CXX11/src/Tensor/README.md b/unsupported/Eigen/CXX11/src/Tensor/README.md index d4d3d5986..38426bb1a 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/README.md +++ b/unsupported/Eigen/CXX11/src/Tensor/README.md @@ -1794,6 +1794,45 @@ but you can easily cast the tensors to floats to do the division: TODO +## Tensor Printing +Tensors can be printed into a stream object (e.g. `std::cout`) using different formatting options. + + Eigen::Tensor a = {4, 3, 2}; + tensor3d.setValues( {{{1, 2}, {3, 4}, {5, 6}}, {{7, 8}, {9, 10}, {11, 12}}, {{13, 14}, {15, 16}, {17, 18}}, {{19, 20}, {21, 22}, {23, 24}}} ); + std::cout << a.format(Eigen::IOFormats::Plain) << std::endl; + ==> + 1 2 + 3 4 + 5 6 + + 7 8 + 9 10 + 11 12 + + 13 14 + 15 16 + 17 18 + + 19 20 + 21 22 + 23 24 + + +In the example, we used the predefined format `Eigen::IOFormats::Plain`. Here is the list of all predefined formats from which you can choose: +- `Eigen::IOFormats::Plain` for a plain output without braces. Different submatrices are separated by a blank line. +- `Eigen::IOFormats::Numpy` for numpy-like output. +- `Eigen::IOFormats::Native` for a `c++` like output which can be directly copy-pasted to setValues(). +- `Eigen::IOFormats::Short` for a stream like output. +- `Eigen::IOFormats::Legacy` for a backwards compatible printing of tensors. + +If you send the tensor directly to the stream the default format is called which is currently `Eigen::IOFormats::Legacy`. + +You can define your own format by explicitly providing a `Eigen::TensorIOFormat` class instance. Here, you can specify: +- The overall prefix and suffix with `std::string tenPrefix` and `std::string tenSuffix` +- The prefix, separator and suffix for each new element, row, matrix, 3d subtensor, ... with `std::vector prefix`, `std::vector separator` and `std::vector suffix`. Note that the first entry in each of the vectors refer to the last dimension of the tensor, e.g. `separator[0]` will be printed between adjacent elements, `separator[1]` will be printed between adjacent matrices, ... +- `char fill`: character which will be placed if the elements are aligned. +- `int precision` +- `int flags`: an OR-ed combination of flags, the default value is 0, the only currently available flag is `Eigen::DontAlignCols` which allows to disable the alignment of columns, resulting in faster code. ## Representation of scalar values diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorBase.h b/unsupported/Eigen/CXX11/src/Tensor/TensorBase.h index 5ede21914..9c356f497 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/TensorBase.h +++ b/unsupported/Eigen/CXX11/src/Tensor/TensorBase.h @@ -963,8 +963,7 @@ class TensorBase } // Returns a formatted tensor ready for printing to a stream - inline const TensorWithFormat format(const TensorIOFormat& fmt) const - { + inline const TensorWithFormat format(const TensorIOFormat& fmt) const { return TensorWithFormat(derived(), fmt); } diff --git a/unsupported/test/cxx11_tensor_io.cpp b/unsupported/test/cxx11_tensor_io.cpp index 2c638f9bf..87745a4d0 100644 --- a/unsupported/test/cxx11_tensor_io.cpp +++ b/unsupported/test/cxx11_tensor_io.cpp @@ -1,136 +1,120 @@ // This file is part of Eigen, a lightweight C++ template library // for linear algebra. // -// Copyright (C) 2014 Benoit Steiner +// Copyright (C) 2016 Dmitry Vyukov +// Copyright (C) 2016 Benoit Steiner // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - #include "main.h" + #include -#include #include +template struct test_tensor_ostream_impl {}; -template -static void test_output_0d() -{ - Tensor tensor; - tensor() = 123; - - std::stringstream os; - os << tensor; - - std::string expected("123"); - VERIFY_IS_EQUAL(std::string(os.str()), expected); -} - - -template -static void test_output_1d() -{ - Tensor tensor(5); - for (int i = 0; i < 5; ++i) { - tensor(i) = i; +template +struct test_tensor_ostream_impl { + static void run() { + Eigen::Tensor t; t.setValues(1); + std::ostringstream os; + os << t.format(Eigen::IOFormats::Plain); + VERIFY(os.str() == "1"); } - - std::stringstream os; - os << tensor; - - std::string expected("0\n1\n2\n3\n4"); - VERIFY_IS_EQUAL(std::string(os.str()), expected); - - Eigen::Tensor empty_tensor(0); - std::stringstream empty_os; - empty_os << empty_tensor; - std::string empty_string; - VERIFY_IS_EQUAL(std::string(empty_os.str()), empty_string); -} - - -template -static void test_output_2d() -{ - Tensor tensor(5, 3); - for (int i = 0; i < 5; ++i) { - for (int j = 0; j < 3; ++j) { - tensor(i, j) = i*j; - } +}; + +template +struct test_tensor_ostream_impl { + static void run() { + Eigen::Tensor t = {3}; t.setValues({1,2,3}); + std::ostringstream os; + os << t.format(Eigen::IOFormats::Plain); + VERIFY(os.str() == "1 2 3"); } - - std::stringstream os; - os << tensor; - - std::string expected("0 0 0\n0 1 2\n0 2 4\n0 3 6\n0 4 8"); - VERIFY_IS_EQUAL(std::string(os.str()), expected); -} - - -template -static void test_output_expr() -{ - Tensor tensor1(5); - Tensor tensor2(5); - for (int i = 0; i < 5; ++i) { - tensor1(i) = i; - tensor2(i) = 7; +}; + +template +struct test_tensor_ostream_impl { + static void run() { + Eigen::Tensor t = {3, 2}; t.setValues({{1, 2}, {3, 4}, {5, 6}}); + std::ostringstream os; + os << t.format(Eigen::IOFormats::Plain); + VERIFY(os.str() == "1 2\n3 4\n5 6"); } - - std::stringstream os; - os << tensor1 + tensor2; - - std::string expected(" 7\n 8\n 9\n10\n11"); - VERIFY_IS_EQUAL(std::string(os.str()), expected); -} - - -template -static void test_output_string() -{ - Tensor tensor(5, 3); - tensor.setConstant(std::string("foo")); - - std::cout << tensor << std::endl; - - std::stringstream os; - os << tensor; - - std::string expected("foo foo foo\nfoo foo foo\nfoo foo foo\nfoo foo foo\nfoo foo foo"); - VERIFY_IS_EQUAL(std::string(os.str()), expected); -} - - -template -static void test_output_const() -{ - Tensor tensor(5); - for (int i = 0; i < 5; ++i) { - tensor(i) = i; +}; + +template +struct test_tensor_ostream_impl { + static void run() { + Eigen::Tensor t = {4, 3, 2}; t.setValues( {{{1, 2}, {3, 4}, {5, 6}}, {{7, 8}, {9, 10}, {11, 12}}, {{13, 14}, {15, 16}, {17, 18}}, {{19, 20}, {21, 22}, {23, 24}}} ); + std::ostringstream os; + os << t.format(Eigen::IOFormats::Plain); + VERIFY(os.str() == "1 2 \n3 4 \n5 6 \n\n7 8 \n9 10\n11 12\n\n13 14\n15 16\n17 18\n\n19 20\n21 22\n23 24"); } +}; + +template +struct test_tensor_ostream_impl { + static void run() { + Eigen::Tensor t = {3,2}; t.setValues({{false, true}, {true, false}, {false, false}}); + std::ostringstream os; + os << t.format(Eigen::IOFormats::Plain); + VERIFY(os.str() == "0 1\n1 0\n0 0"); + } +}; + +template +struct test_tensor_ostream_impl, 2, Layout> { + static void run() { + Eigen::Tensor, 2> t = {3,2}; t.setValues({{std::complex(1,2), std::complex(12,3)}, {std::complex(-4,2), std::complex(0,5)}, {std::complex(-1,4), std::complex(5,27)}}); + std::ostringstream os; + os << t.format(Eigen::IOFormats::Plain); + VERIFY(os.str() == "(1,2) (12,3)\n(-4,2) (0,5) \n(-1,4) (5,27)"); + } +}; - TensorMap > tensor_map(tensor.data(), 5); - - std::stringstream os; - os << tensor_map; - - std::string expected("0\n1\n2\n3\n4"); - VERIFY_IS_EQUAL(std::string(os.str()), expected); +template +void test_tensor_ostream() +{ + test_tensor_ostream_impl::run(); } - EIGEN_DECLARE_TEST(cxx11_tensor_io) { - CALL_SUBTEST(test_output_0d()); - CALL_SUBTEST(test_output_0d()); - CALL_SUBTEST(test_output_1d()); - CALL_SUBTEST(test_output_1d()); - CALL_SUBTEST(test_output_2d()); - CALL_SUBTEST(test_output_2d()); - CALL_SUBTEST(test_output_expr()); - CALL_SUBTEST(test_output_expr()); - CALL_SUBTEST(test_output_string()); - CALL_SUBTEST(test_output_string()); - CALL_SUBTEST(test_output_const()); - CALL_SUBTEST(test_output_const()); + CALL_SUBTEST((test_tensor_ostream())); + CALL_SUBTEST((test_tensor_ostream())); + CALL_SUBTEST((test_tensor_ostream())); + CALL_SUBTEST((test_tensor_ostream())); + + CALL_SUBTEST((test_tensor_ostream())); + CALL_SUBTEST((test_tensor_ostream())); + CALL_SUBTEST((test_tensor_ostream())); + CALL_SUBTEST((test_tensor_ostream())); + + CALL_SUBTEST((test_tensor_ostream())); + CALL_SUBTEST((test_tensor_ostream())); + CALL_SUBTEST((test_tensor_ostream())); + CALL_SUBTEST((test_tensor_ostream())); + + CALL_SUBTEST((test_tensor_ostream())); + CALL_SUBTEST((test_tensor_ostream())); + CALL_SUBTEST((test_tensor_ostream())); + CALL_SUBTEST((test_tensor_ostream())); + + CALL_SUBTEST((test_tensor_ostream())); + CALL_SUBTEST((test_tensor_ostream())); + CALL_SUBTEST((test_tensor_ostream())); + CALL_SUBTEST((test_tensor_ostream())); + + CALL_SUBTEST((test_tensor_ostream())); + CALL_SUBTEST((test_tensor_ostream())); + CALL_SUBTEST((test_tensor_ostream())); + CALL_SUBTEST((test_tensor_ostream())); + + CALL_SUBTEST((test_tensor_ostream())); + CALL_SUBTEST((test_tensor_ostream())); + + CALL_SUBTEST((test_tensor_ostream,2,Eigen::ColMajor>())); + CALL_SUBTEST((test_tensor_ostream,2,Eigen::ColMajor>())); } -- GitLab From f000a4ac0fc2db3538c926d59beb42a44ab8817e Mon Sep 17 00:00:00 2001 From: Matthias Peschke Date: Tue, 8 Dec 2020 09:48:42 +0100 Subject: [PATCH 03/29] Reimplemented the Tensor stream output. The implementation structure is based on the IO for Eigen::Matrix. Predefined formats in namespace Eigen::IOFormats are defined for numpy-like output, native output and short output. More can be added. Rebase. --- unsupported/Eigen/CXX11/src/Tensor/TensorIO.h | 1 + 1 file changed, 1 insertion(+) diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h b/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h index cc21b2965..572d62b80 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h +++ b/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h @@ -2,6 +2,7 @@ // for linear algebra. // // Copyright (C) 2014 Benoit Steiner +// Copyright (C) 2020 Matthias Peschke // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -- GitLab From 890273b5e2a7aa72a9bfb21f24035dcc0be302c6 Mon Sep 17 00:00:00 2001 From: Matthias Peschke Date: Wed, 3 Mar 2021 10:26:41 +0100 Subject: [PATCH 04/29] Improved the new Tensor stream operator, implementation is now fully c++11 compliant. Added test case for the Tensor stream operator. Added documentation for the Tensor stream operator. Rebase. --- unsupported/Eigen/CXX11/src/Tensor/TensorIO.h | 1 - 1 file changed, 1 deletion(-) diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h b/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h index 572d62b80..cc21b2965 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h +++ b/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h @@ -2,7 +2,6 @@ // for linear algebra. // // Copyright (C) 2014 Benoit Steiner -// Copyright (C) 2020 Matthias Peschke // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -- GitLab From 5498b0818b44532c6e197f1a142b7455148129c8 Mon Sep 17 00:00:00 2001 From: Matthias Peschke Date: Thu, 2 Sep 2021 11:42:30 +0200 Subject: [PATCH 05/29] Refactored tensor printing. Removed namespace IOFormats and put predefined format as static functions into struct TensorIOFormat. Aligned output is now rightaligned. Adapted predefined Numpy format to resemble `print(numpy.array())`. Adapted documentation. Adapted tests. --- unsupported/Eigen/CXX11/src/Tensor/README.md | 28 +++--- unsupported/Eigen/CXX11/src/Tensor/TensorIO.h | 74 ++++++---------- unsupported/test/cxx11_tensor_io.cpp | 86 +++++++++++-------- 3 files changed, 89 insertions(+), 99 deletions(-) diff --git a/unsupported/Eigen/CXX11/src/Tensor/README.md b/unsupported/Eigen/CXX11/src/Tensor/README.md index 38426bb1a..b6abf2f87 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/README.md +++ b/unsupported/Eigen/CXX11/src/Tensor/README.md @@ -1797,16 +1797,16 @@ TODO ## Tensor Printing Tensors can be printed into a stream object (e.g. `std::cout`) using different formatting options. - Eigen::Tensor a = {4, 3, 2}; + Eigen::Tensor tensor3d = {4, 3, 2}; tensor3d.setValues( {{{1, 2}, {3, 4}, {5, 6}}, {{7, 8}, {9, 10}, {11, 12}}, {{13, 14}, {15, 16}, {17, 18}}, {{19, 20}, {21, 22}, {23, 24}}} ); - std::cout << a.format(Eigen::IOFormats::Plain) << std::endl; + std::cout << tensor3d.format(Eigen::TensorIOFormat::Plain()) << std::endl; ==> - 1 2 - 3 4 - 5 6 + 1 2 + 3 4 + 5 6 - 7 8 - 9 10 + 7 8 + 9 10 11 12 13 14 @@ -1818,14 +1818,14 @@ Tensors can be printed into a stream object (e.g. `std::cout`) using different f 23 24 -In the example, we used the predefined format `Eigen::IOFormats::Plain`. Here is the list of all predefined formats from which you can choose: -- `Eigen::IOFormats::Plain` for a plain output without braces. Different submatrices are separated by a blank line. -- `Eigen::IOFormats::Numpy` for numpy-like output. -- `Eigen::IOFormats::Native` for a `c++` like output which can be directly copy-pasted to setValues(). -- `Eigen::IOFormats::Short` for a stream like output. -- `Eigen::IOFormats::Legacy` for a backwards compatible printing of tensors. +In the example, we used the predefined format `Eigen::TensorIOFormat::Plain`. +Here is the list of all predefined formats from which you can choose: +- `Eigen::TensorIOFormat::Plain()` for a plain output without braces. Different submatrices are separated by a blank line. +- `Eigen::TensorIOFormat::Numpy()` for numpy-like output. +- `Eigen::TensorIOFormat::Native()` for a `c++` like output which can be directly copy-pasted to setValues(). +- `Eigen::TensorIOFormat::Legacy()` for a backwards compatible printing of tensors. -If you send the tensor directly to the stream the default format is called which is currently `Eigen::IOFormats::Legacy`. +If you send the tensor directly to the stream the default format is called which is `Eigen::IOFormats::Plain()`. You can define your own format by explicitly providing a `Eigen::TensorIOFormat` class instance. Here, you can specify: - The overall prefix and suffix with `std::string tenPrefix` and `std::string tenSuffix` diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h b/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h index cc21b2965..82a33ea2e 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h +++ b/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h @@ -58,69 +58,45 @@ struct TensorIOFormat } } } - - std::string tenPrefix; - std::string tenSuffix; - std::vector prefix; - std::vector suffix; - std::vector separator; - char fill; - int precision; - int flags; - std::vector spacer{}; - bool legacy_bit = false; -}; -namespace internal { - TensorIOFormat gen_numpy_format() { - return TensorIOFormat(StreamPrecision, 0, "array([" , "])"); + static inline const TensorIOFormat Numpy() { + std::vector prefix = {"", "["}; + std::vector suffix = {"", "]"}; + std::vector separator = {", ", "\n"}; + return TensorIOFormat(separator, prefix, suffix, StreamPrecision, 0, "[" , "]"); } - TensorIOFormat gen_short_format() { - std::vector separator = {", "}; - std::vector prefix = {""}; - std::vector suffix = {""}; - - TensorIOFormat ShortFormat(separator, prefix, suffix, StreamPrecision, 1, " << " , ";"); - return ShortFormat; - } - - TensorIOFormat gen_plain_format() { + static inline const TensorIOFormat Plain() { std::vector separator = {" ", "\n", "\n", ""}; std::vector prefix = {""}; std::vector suffix = {""}; - - TensorIOFormat PlainFormat(separator, prefix, suffix, StreamPrecision, 0, "" , "", ' '); - return PlainFormat; + return TensorIOFormat(separator, prefix, suffix, StreamPrecision, 0, "" , "", ' '); } - TensorIOFormat gen_native_format() { - std::vector separator = {", ", ""}; + static inline const TensorIOFormat Native() { + std::vector separator = {", ", "\n"}; std::vector prefix = {"", "{"}; std::vector suffix = {"", "}"}; - - TensorIOFormat EigenFormat(separator, prefix, suffix, StreamPrecision, 0, "{" , "}", ' '); - return EigenFormat; + return TensorIOFormat(separator, prefix, suffix, StreamPrecision, 0, "{" , "}", ' '); } - TensorIOFormat gen_legacy_format() { + static inline const TensorIOFormat Legacy() { TensorIOFormat LegacyFormat(StreamPrecision, 0, "", "", ' '); LegacyFormat.legacy_bit = true; return LegacyFormat; } -} // namespace internal - -namespace IOFormats { - const TensorIOFormat Numpy = internal::gen_numpy_format(); - - const TensorIOFormat Short = internal::gen_short_format(); - - const TensorIOFormat Plain = internal::gen_plain_format(); - - const TensorIOFormat Native = internal::gen_native_format(); - - const TensorIOFormat Legacy = internal::gen_legacy_format(); -} + + std::string tenPrefix; + std::string tenSuffix; + std::vector prefix; + std::vector suffix; + std::vector separator; + char fill; + int precision; + int flags; + std::vector spacer{}; + bool legacy_bit = false; +}; template class TensorWithFormat; //specialize for Layout=ColMajor, Layout=RowMajor and rank=0. @@ -336,7 +312,7 @@ struct TensorPrinter { if(width) { s.fill(fmt.fill); s.width(width); - s << std::left; + s << std::right; } s << _t.data()[i]; s << suffix.str(); @@ -384,7 +360,7 @@ struct TensorPrinter { template std::ostream & operator <<(std::ostream & s, const TensorBase & t) { - s << t.format(IOFormats::Legacy); + s << t.format(TensorIOFormat::Plain()); return s; } } // end namespace Eigen diff --git a/unsupported/test/cxx11_tensor_io.cpp b/unsupported/test/cxx11_tensor_io.cpp index 87745a4d0..5de154443 100644 --- a/unsupported/test/cxx11_tensor_io.cpp +++ b/unsupported/test/cxx11_tensor_io.cpp @@ -16,62 +16,76 @@ template struct test_tensor_ostream_impl template struct test_tensor_ostream_impl { - static void run() { - Eigen::Tensor t; t.setValues(1); - std::ostringstream os; - os << t.format(Eigen::IOFormats::Plain); - VERIFY(os.str() == "1"); - } + static void run() + { + Eigen::Tensor t; + t.setValues(1); + std::ostringstream os; + os << t.format(Eigen::TensorIOFormat::Plain()); + VERIFY(os.str() == "1"); + } }; template struct test_tensor_ostream_impl { - static void run() { - Eigen::Tensor t = {3}; t.setValues({1,2,3}); - std::ostringstream os; - os << t.format(Eigen::IOFormats::Plain); - VERIFY(os.str() == "1 2 3"); - } + static void run() + { + Eigen::Tensor t = {3}; + t.setValues({1, 2, 3}); + std::ostringstream os; + os << t.format(Eigen::TensorIOFormat::Plain()); + VERIFY(os.str() == "1 2 3"); + } }; template struct test_tensor_ostream_impl { - static void run() { - Eigen::Tensor t = {3, 2}; t.setValues({{1, 2}, {3, 4}, {5, 6}}); - std::ostringstream os; - os << t.format(Eigen::IOFormats::Plain); - VERIFY(os.str() == "1 2\n3 4\n5 6"); - } + static void run() + { + Eigen::Tensor t = {3, 2}; + t.setValues({{1, 2}, {3, 4}, {5, 6}}); + std::ostringstream os; + os << t.format(Eigen::TensorIOFormat::Plain()); + VERIFY(os.str() == "1 2\n3 4\n5 6"); + } }; template struct test_tensor_ostream_impl { - static void run() { - Eigen::Tensor t = {4, 3, 2}; t.setValues( {{{1, 2}, {3, 4}, {5, 6}}, {{7, 8}, {9, 10}, {11, 12}}, {{13, 14}, {15, 16}, {17, 18}}, {{19, 20}, {21, 22}, {23, 24}}} ); - std::ostringstream os; - os << t.format(Eigen::IOFormats::Plain); - VERIFY(os.str() == "1 2 \n3 4 \n5 6 \n\n7 8 \n9 10\n11 12\n\n13 14\n15 16\n17 18\n\n19 20\n21 22\n23 24"); - } + static void run() + { + Eigen::Tensor t = {4, 3, 2}; + t.setValues({{{1, 2}, {3, 4}, {5, 6}}, {{7, 8}, {9, 10}, {11, 12}}, {{13, 14}, {15, 16}, {17, 18}}, {{19, 20}, {21, 22}, {23, 24}}}); + std::ostringstream os; + os << t.format(Eigen::TensorIOFormat::Plain()); + VERIFY(os.str() == " 1 2\n 3 4\n 5 6\n\n 7 8\n 9 10\n11 12\n\n13 14\n15 16\n17 18\n\n19 20\n21 22\n23 24"); + } }; template struct test_tensor_ostream_impl { - static void run() { - Eigen::Tensor t = {3,2}; t.setValues({{false, true}, {true, false}, {false, false}}); - std::ostringstream os; - os << t.format(Eigen::IOFormats::Plain); - VERIFY(os.str() == "0 1\n1 0\n0 0"); - } + static void run() + { + Eigen::Tensor t = {3, 2}; + t.setValues({{false, true}, {true, false}, {false, false}}); + std::ostringstream os; + os << t.format(Eigen::TensorIOFormat::Plain()); + VERIFY(os.str() == "0 1\n1 0\n0 0"); + } }; template struct test_tensor_ostream_impl, 2, Layout> { - static void run() { - Eigen::Tensor, 2> t = {3,2}; t.setValues({{std::complex(1,2), std::complex(12,3)}, {std::complex(-4,2), std::complex(0,5)}, {std::complex(-1,4), std::complex(5,27)}}); - std::ostringstream os; - os << t.format(Eigen::IOFormats::Plain); - VERIFY(os.str() == "(1,2) (12,3)\n(-4,2) (0,5) \n(-1,4) (5,27)"); - } + static void run() + { + Eigen::Tensor, 2> t = {3, 2}; + t.setValues({{std::complex(1, 2), std::complex(12, 3)}, + {std::complex(-4, 2), std::complex(0, 5)}, + {std::complex(-1, 4), std::complex(5, 27)}}); + std::ostringstream os; + os << t.format(Eigen::TensorIOFormat::Plain()); + VERIFY(os.str() == " (1,2) (12,3)\n(-4,2) (0,5)\n(-1,4) (5,27)"); + } }; template -- GitLab From 60b7c2f58ad99f40c149ccfdd28f42679dc754a6 Mon Sep 17 00:00:00 2001 From: Matthias Peschke Date: Tue, 8 Dec 2020 09:48:42 +0100 Subject: [PATCH 06/29] Reimplemented the Tensor stream output. The implementation structure is based on the IO for Eigen::Matrix. Predefined formats in namespace Eigen::IOFormats are defined for numpy-like output, native output and short output. More can be added. --- unsupported/Eigen/CXX11/src/Tensor/TensorIO.h | 1 + 1 file changed, 1 insertion(+) diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h b/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h index 82a33ea2e..a1d2e3666 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h +++ b/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h @@ -2,6 +2,7 @@ // for linear algebra. // // Copyright (C) 2014 Benoit Steiner +// Copyright (C) 2020 Matthias Peschke // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -- GitLab From 2a18a6d4d9379d6663f2598fc7f2c162cdd6f2cd Mon Sep 17 00:00:00 2001 From: Matthias Peschke Date: Wed, 3 Mar 2021 10:26:41 +0100 Subject: [PATCH 07/29] Improved the new Tensor stream operator, implementation is now fully c++11 compliant. Added test case for the Tensor stream operator. Added documentation for the Tensor stream operator. --- unsupported/Eigen/CXX11/src/Tensor/TensorIO.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h b/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h index a1d2e3666..4589dff81 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h +++ b/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h @@ -2,7 +2,6 @@ // for linear algebra. // // Copyright (C) 2014 Benoit Steiner -// Copyright (C) 2020 Matthias Peschke // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed @@ -200,8 +199,6 @@ struct TensorPrinter { } assert(layout == RowMajor); - //from here on we have a tensor in RowMajor storage - typedef typename conditional< is_same::value || -- GitLab From 4fe6cabb8aeb56c3330b37c589c0a278ee25c4b3 Mon Sep 17 00:00:00 2001 From: Matthias Peschke Date: Thu, 15 Apr 2021 11:45:22 +0200 Subject: [PATCH 08/29] Changed uppercase names to lowercase names. Changed Eigen::IOFormats::Eigen to Eigen::IOFormats::Plain and adapted documentation and tests accordingly. --- unsupported/test/cxx11_tensor_io.cpp | 30 +++++++++++++++++----------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/unsupported/test/cxx11_tensor_io.cpp b/unsupported/test/cxx11_tensor_io.cpp index 5de154443..dbd306f0b 100644 --- a/unsupported/test/cxx11_tensor_io.cpp +++ b/unsupported/test/cxx11_tensor_io.cpp @@ -14,8 +14,9 @@ template struct test_tensor_ostream_impl {}; -template -struct test_tensor_ostream_impl { +template +struct test_tensor_ostream_impl +{ static void run() { Eigen::Tensor t; @@ -26,8 +27,9 @@ struct test_tensor_ostream_impl { } }; -template -struct test_tensor_ostream_impl { +template +struct test_tensor_ostream_impl +{ static void run() { Eigen::Tensor t = {3}; @@ -38,8 +40,9 @@ struct test_tensor_ostream_impl { } }; -template -struct test_tensor_ostream_impl { +template +struct test_tensor_ostream_impl +{ static void run() { Eigen::Tensor t = {3, 2}; @@ -50,8 +53,9 @@ struct test_tensor_ostream_impl { } }; -template -struct test_tensor_ostream_impl { +template +struct test_tensor_ostream_impl +{ static void run() { Eigen::Tensor t = {4, 3, 2}; @@ -62,8 +66,9 @@ struct test_tensor_ostream_impl { } }; -template -struct test_tensor_ostream_impl { +template +struct test_tensor_ostream_impl +{ static void run() { Eigen::Tensor t = {3, 2}; @@ -74,8 +79,9 @@ struct test_tensor_ostream_impl { } }; -template -struct test_tensor_ostream_impl, 2, Layout> { +template +struct test_tensor_ostream_impl, 2, Layout> +{ static void run() { Eigen::Tensor, 2> t = {3, 2}; -- GitLab From 7f1236e4c8bcc82a207f076999400e31671c273a Mon Sep 17 00:00:00 2001 From: Matthias Peschke Date: Tue, 8 Dec 2020 09:48:42 +0100 Subject: [PATCH 09/29] Reimplemented the Tensor stream output. The implementation structure is based on the IO for Eigen::Matrix. Predefined formats in namespace Eigen::IOFormats are defined for numpy-like output, native output and short output. More can be added. --- unsupported/Eigen/CXX11/src/Tensor/TensorIO.h | 1 + 1 file changed, 1 insertion(+) diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h b/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h index 4589dff81..aa1bcebfb 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h +++ b/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h @@ -2,6 +2,7 @@ // for linear algebra. // // Copyright (C) 2014 Benoit Steiner +// Copyright (C) 2020 Matthias Peschke // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -- GitLab From 5773d0264eceee834ea91e10694b32c022bb99fe Mon Sep 17 00:00:00 2001 From: Matthias Peschke Date: Wed, 3 Mar 2021 10:26:41 +0100 Subject: [PATCH 10/29] Improved the new Tensor stream operator, implementation is now fully c++11 compliant. Added test case for the Tensor stream operator. Added documentation for the Tensor stream operator. --- unsupported/Eigen/CXX11/src/Tensor/TensorIO.h | 1 - 1 file changed, 1 deletion(-) diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h b/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h index aa1bcebfb..4589dff81 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h +++ b/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h @@ -2,7 +2,6 @@ // for linear algebra. // // Copyright (C) 2014 Benoit Steiner -// Copyright (C) 2020 Matthias Peschke // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -- GitLab From 24d1b5e531be2c9349b4be1c669901ab7657fe4b Mon Sep 17 00:00:00 2001 From: Matthias Peschke Date: Thu, 2 Sep 2021 11:58:43 +0200 Subject: [PATCH 11/29] Restore correct formatting of cxx11_tensor_io test. --- unsupported/test/cxx11_tensor_io.cpp | 30 +++++++++++----------------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/unsupported/test/cxx11_tensor_io.cpp b/unsupported/test/cxx11_tensor_io.cpp index dbd306f0b..5de154443 100644 --- a/unsupported/test/cxx11_tensor_io.cpp +++ b/unsupported/test/cxx11_tensor_io.cpp @@ -14,9 +14,8 @@ template struct test_tensor_ostream_impl {}; -template -struct test_tensor_ostream_impl -{ +template +struct test_tensor_ostream_impl { static void run() { Eigen::Tensor t; @@ -27,9 +26,8 @@ struct test_tensor_ostream_impl } }; -template -struct test_tensor_ostream_impl -{ +template +struct test_tensor_ostream_impl { static void run() { Eigen::Tensor t = {3}; @@ -40,9 +38,8 @@ struct test_tensor_ostream_impl } }; -template -struct test_tensor_ostream_impl -{ +template +struct test_tensor_ostream_impl { static void run() { Eigen::Tensor t = {3, 2}; @@ -53,9 +50,8 @@ struct test_tensor_ostream_impl } }; -template -struct test_tensor_ostream_impl -{ +template +struct test_tensor_ostream_impl { static void run() { Eigen::Tensor t = {4, 3, 2}; @@ -66,9 +62,8 @@ struct test_tensor_ostream_impl } }; -template -struct test_tensor_ostream_impl -{ +template +struct test_tensor_ostream_impl { static void run() { Eigen::Tensor t = {3, 2}; @@ -79,9 +74,8 @@ struct test_tensor_ostream_impl } }; -template -struct test_tensor_ostream_impl, 2, Layout> -{ +template +struct test_tensor_ostream_impl, 2, Layout> { static void run() { Eigen::Tensor, 2> t = {3, 2}; -- GitLab From e65b72ce03bce29d5eff8b3176f26dc207c97bc3 Mon Sep 17 00:00:00 2001 From: Matthias Peschke Date: Mon, 25 Oct 2021 13:25:53 +0200 Subject: [PATCH 12/29] Removed commas from Numpy format and add commas to Native format. --- unsupported/Eigen/CXX11/src/Tensor/TensorIO.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h b/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h index 4589dff81..53b65f8d2 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h +++ b/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h @@ -62,7 +62,7 @@ struct TensorIOFormat static inline const TensorIOFormat Numpy() { std::vector prefix = {"", "["}; std::vector suffix = {"", "]"}; - std::vector separator = {", ", "\n"}; + std::vector separator = {" ", "\n"}; return TensorIOFormat(separator, prefix, suffix, StreamPrecision, 0, "[" , "]"); } @@ -76,7 +76,7 @@ struct TensorIOFormat static inline const TensorIOFormat Native() { std::vector separator = {", ", "\n"}; std::vector prefix = {"", "{"}; - std::vector suffix = {"", "}"}; + std::vector suffix = {"", "},"}; return TensorIOFormat(separator, prefix, suffix, StreamPrecision, 0, "{" , "}", ' '); } -- GitLab From 765182d946dc7f328ad78ee6ac54eb03bd4db929 Mon Sep 17 00:00:00 2001 From: Matthias Peschke Date: Tue, 8 Dec 2020 09:48:42 +0100 Subject: [PATCH 13/29] Reimplemented the Tensor stream output. The implementation structure is based on the IO for Eigen::Matrix. Predefined formats in namespace Eigen::IOFormats are defined for numpy-like output, native output and short output. More can be added. Rebase. --- unsupported/Eigen/CXX11/src/Tensor/TensorIO.h | 1 + 1 file changed, 1 insertion(+) diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h b/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h index 53b65f8d2..30a0f33b5 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h +++ b/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h @@ -2,6 +2,7 @@ // for linear algebra. // // Copyright (C) 2014 Benoit Steiner +// Copyright (C) 2020 Matthias Peschke // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -- GitLab From 04459d246cd76e8cf0dd77170b3d222c0078676e Mon Sep 17 00:00:00 2001 From: Matthias Peschke Date: Wed, 3 Mar 2021 10:26:41 +0100 Subject: [PATCH 14/29] Improved the new Tensor stream operator, implementation is now fully c++11 compliant. Added test case for the Tensor stream operator. Added documentation for the Tensor stream operator. Rebase. --- unsupported/Eigen/CXX11/src/Tensor/TensorIO.h | 1 - 1 file changed, 1 deletion(-) diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h b/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h index 30a0f33b5..53b65f8d2 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h +++ b/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h @@ -2,7 +2,6 @@ // for linear algebra. // // Copyright (C) 2014 Benoit Steiner -// Copyright (C) 2020 Matthias Peschke // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -- GitLab From 92656b68c617e67efaeb67ada14d052eff44eb0d Mon Sep 17 00:00:00 2001 From: Matthias Peschke Date: Tue, 8 Dec 2020 09:48:42 +0100 Subject: [PATCH 15/29] Reimplemented the Tensor stream output. The implementation structure is based on the IO for Eigen::Matrix. Predefined formats in namespace Eigen::IOFormats are defined for numpy-like output, native output and short output. More can be added. --- unsupported/Eigen/CXX11/src/Tensor/TensorIO.h | 1 + 1 file changed, 1 insertion(+) diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h b/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h index 53b65f8d2..30a0f33b5 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h +++ b/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h @@ -2,6 +2,7 @@ // for linear algebra. // // Copyright (C) 2014 Benoit Steiner +// Copyright (C) 2020 Matthias Peschke // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -- GitLab From c8069297a37c4b7816eb551be9cda946d9b51b32 Mon Sep 17 00:00:00 2001 From: Matthias Peschke Date: Wed, 3 Mar 2021 10:26:41 +0100 Subject: [PATCH 16/29] Improved the new Tensor stream operator, implementation is now fully c++11 compliant. Added test case for the Tensor stream operator. Added documentation for the Tensor stream operator. --- unsupported/Eigen/CXX11/src/Tensor/TensorIO.h | 1 - 1 file changed, 1 deletion(-) diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h b/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h index 30a0f33b5..53b65f8d2 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h +++ b/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h @@ -2,7 +2,6 @@ // for linear algebra. // // Copyright (C) 2014 Benoit Steiner -// Copyright (C) 2020 Matthias Peschke // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -- GitLab From b0e234b9e5ce4727f5af745c8d6357e102c5b7c6 Mon Sep 17 00:00:00 2001 From: Matthias Peschke Date: Thu, 15 Apr 2021 11:45:22 +0200 Subject: [PATCH 17/29] Changed uppercase names to lowercase names. Changed Eigen::IOFormats::Eigen to Eigen::IOFormats::Plain and adapted documentation and tests accordingly. --- unsupported/test/cxx11_tensor_io.cpp | 30 +++++++++++++++++----------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/unsupported/test/cxx11_tensor_io.cpp b/unsupported/test/cxx11_tensor_io.cpp index 5de154443..dbd306f0b 100644 --- a/unsupported/test/cxx11_tensor_io.cpp +++ b/unsupported/test/cxx11_tensor_io.cpp @@ -14,8 +14,9 @@ template struct test_tensor_ostream_impl {}; -template -struct test_tensor_ostream_impl { +template +struct test_tensor_ostream_impl +{ static void run() { Eigen::Tensor t; @@ -26,8 +27,9 @@ struct test_tensor_ostream_impl { } }; -template -struct test_tensor_ostream_impl { +template +struct test_tensor_ostream_impl +{ static void run() { Eigen::Tensor t = {3}; @@ -38,8 +40,9 @@ struct test_tensor_ostream_impl { } }; -template -struct test_tensor_ostream_impl { +template +struct test_tensor_ostream_impl +{ static void run() { Eigen::Tensor t = {3, 2}; @@ -50,8 +53,9 @@ struct test_tensor_ostream_impl { } }; -template -struct test_tensor_ostream_impl { +template +struct test_tensor_ostream_impl +{ static void run() { Eigen::Tensor t = {4, 3, 2}; @@ -62,8 +66,9 @@ struct test_tensor_ostream_impl { } }; -template -struct test_tensor_ostream_impl { +template +struct test_tensor_ostream_impl +{ static void run() { Eigen::Tensor t = {3, 2}; @@ -74,8 +79,9 @@ struct test_tensor_ostream_impl { } }; -template -struct test_tensor_ostream_impl, 2, Layout> { +template +struct test_tensor_ostream_impl, 2, Layout> +{ static void run() { Eigen::Tensor, 2> t = {3, 2}; -- GitLab From 0f82128fb9848d5f6cb5b3a83d9b9bd5277e6043 Mon Sep 17 00:00:00 2001 From: Matthias Peschke Date: Tue, 8 Dec 2020 09:48:42 +0100 Subject: [PATCH 18/29] Reimplemented the Tensor stream output. The implementation structure is based on the IO for Eigen::Matrix. Predefined formats in namespace Eigen::IOFormats are defined for numpy-like output, native output and short output. More can be added. --- unsupported/Eigen/CXX11/src/Tensor/TensorIO.h | 1 + 1 file changed, 1 insertion(+) diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h b/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h index 53b65f8d2..30a0f33b5 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h +++ b/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h @@ -2,6 +2,7 @@ // for linear algebra. // // Copyright (C) 2014 Benoit Steiner +// Copyright (C) 2020 Matthias Peschke // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -- GitLab From 02aff9fa92781c82b7d4de358bff1f93a61c0505 Mon Sep 17 00:00:00 2001 From: Matthias Peschke Date: Wed, 3 Mar 2021 10:26:41 +0100 Subject: [PATCH 19/29] Improved the new Tensor stream operator, implementation is now fully c++11 compliant. Added test case for the Tensor stream operator. Added documentation for the Tensor stream operator. --- unsupported/Eigen/CXX11/src/Tensor/TensorIO.h | 1 - 1 file changed, 1 deletion(-) diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h b/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h index 30a0f33b5..53b65f8d2 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h +++ b/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h @@ -2,7 +2,6 @@ // for linear algebra. // // Copyright (C) 2014 Benoit Steiner -// Copyright (C) 2020 Matthias Peschke // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -- GitLab From 8e8880f22456abe2579a135f9759bddf8a2e06dc Mon Sep 17 00:00:00 2001 From: Matthias Peschke Date: Thu, 2 Sep 2021 11:58:43 +0200 Subject: [PATCH 20/29] Restore correct formatting of cxx11_tensor_io test. --- unsupported/test/cxx11_tensor_io.cpp | 30 +++++++++++----------------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/unsupported/test/cxx11_tensor_io.cpp b/unsupported/test/cxx11_tensor_io.cpp index dbd306f0b..5de154443 100644 --- a/unsupported/test/cxx11_tensor_io.cpp +++ b/unsupported/test/cxx11_tensor_io.cpp @@ -14,9 +14,8 @@ template struct test_tensor_ostream_impl {}; -template -struct test_tensor_ostream_impl -{ +template +struct test_tensor_ostream_impl { static void run() { Eigen::Tensor t; @@ -27,9 +26,8 @@ struct test_tensor_ostream_impl } }; -template -struct test_tensor_ostream_impl -{ +template +struct test_tensor_ostream_impl { static void run() { Eigen::Tensor t = {3}; @@ -40,9 +38,8 @@ struct test_tensor_ostream_impl } }; -template -struct test_tensor_ostream_impl -{ +template +struct test_tensor_ostream_impl { static void run() { Eigen::Tensor t = {3, 2}; @@ -53,9 +50,8 @@ struct test_tensor_ostream_impl } }; -template -struct test_tensor_ostream_impl -{ +template +struct test_tensor_ostream_impl { static void run() { Eigen::Tensor t = {4, 3, 2}; @@ -66,9 +62,8 @@ struct test_tensor_ostream_impl } }; -template -struct test_tensor_ostream_impl -{ +template +struct test_tensor_ostream_impl { static void run() { Eigen::Tensor t = {3, 2}; @@ -79,9 +74,8 @@ struct test_tensor_ostream_impl } }; -template -struct test_tensor_ostream_impl, 2, Layout> -{ +template +struct test_tensor_ostream_impl, 2, Layout> { static void run() { Eigen::Tensor, 2> t = {3, 2}; -- GitLab From c41ae32c7d7bf35eb1c872a3c15eacb84b819986 Mon Sep 17 00:00:00 2001 From: Matthias Peschke Date: Tue, 8 Dec 2020 09:48:42 +0100 Subject: [PATCH 21/29] Reimplemented the Tensor stream output. The implementation structure is based on the IO for Eigen::Matrix. Predefined formats in namespace Eigen::IOFormats are defined for numpy-like output, native output and short output. More can be added. Rebase. --- unsupported/Eigen/CXX11/src/Tensor/TensorIO.h | 1 + 1 file changed, 1 insertion(+) diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h b/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h index 53b65f8d2..30a0f33b5 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h +++ b/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h @@ -2,6 +2,7 @@ // for linear algebra. // // Copyright (C) 2014 Benoit Steiner +// Copyright (C) 2020 Matthias Peschke // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -- GitLab From 98bd879dff392d57f5097b986a44eff9a21ab2d5 Mon Sep 17 00:00:00 2001 From: Matthias Peschke Date: Wed, 3 Mar 2021 10:26:41 +0100 Subject: [PATCH 22/29] Improved the new Tensor stream operator, implementation is now fully c++11 compliant. Added test case for the Tensor stream operator. Added documentation for the Tensor stream operator. Rebase. --- unsupported/Eigen/CXX11/src/Tensor/TensorIO.h | 1 - 1 file changed, 1 deletion(-) diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h b/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h index 30a0f33b5..53b65f8d2 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h +++ b/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h @@ -2,7 +2,6 @@ // for linear algebra. // // Copyright (C) 2014 Benoit Steiner -// Copyright (C) 2020 Matthias Peschke // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -- GitLab From 8296a34a2ad42388581a6d6445720254663bd4da Mon Sep 17 00:00:00 2001 From: Matthias Peschke Date: Tue, 8 Dec 2020 09:48:42 +0100 Subject: [PATCH 23/29] Reimplemented the Tensor stream output. The implementation structure is based on the IO for Eigen::Matrix. Predefined formats in namespace Eigen::IOFormats are defined for numpy-like output, native output and short output. More can be added. --- unsupported/Eigen/CXX11/src/Tensor/TensorIO.h | 1 + 1 file changed, 1 insertion(+) diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h b/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h index 53b65f8d2..30a0f33b5 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h +++ b/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h @@ -2,6 +2,7 @@ // for linear algebra. // // Copyright (C) 2014 Benoit Steiner +// Copyright (C) 2020 Matthias Peschke // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -- GitLab From 093040b78716d7b8f0b0fb267e89d0afdaf0af41 Mon Sep 17 00:00:00 2001 From: Matthias Peschke Date: Wed, 3 Mar 2021 10:26:41 +0100 Subject: [PATCH 24/29] Improved the new Tensor stream operator, implementation is now fully c++11 compliant. Added test case for the Tensor stream operator. Added documentation for the Tensor stream operator. --- unsupported/Eigen/CXX11/src/Tensor/TensorIO.h | 1 - 1 file changed, 1 deletion(-) diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h b/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h index 30a0f33b5..53b65f8d2 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h +++ b/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h @@ -2,7 +2,6 @@ // for linear algebra. // // Copyright (C) 2014 Benoit Steiner -// Copyright (C) 2020 Matthias Peschke // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -- GitLab From 8fa699e1a0b0e4bfb07b437ba1c31d398848079a Mon Sep 17 00:00:00 2001 From: Matthias Peschke Date: Thu, 15 Apr 2021 11:45:22 +0200 Subject: [PATCH 25/29] Changed uppercase names to lowercase names. Changed Eigen::IOFormats::Eigen to Eigen::IOFormats::Plain and adapted documentation and tests accordingly. --- unsupported/test/cxx11_tensor_io.cpp | 30 +++++++++++++++++----------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/unsupported/test/cxx11_tensor_io.cpp b/unsupported/test/cxx11_tensor_io.cpp index 5de154443..dbd306f0b 100644 --- a/unsupported/test/cxx11_tensor_io.cpp +++ b/unsupported/test/cxx11_tensor_io.cpp @@ -14,8 +14,9 @@ template struct test_tensor_ostream_impl {}; -template -struct test_tensor_ostream_impl { +template +struct test_tensor_ostream_impl +{ static void run() { Eigen::Tensor t; @@ -26,8 +27,9 @@ struct test_tensor_ostream_impl { } }; -template -struct test_tensor_ostream_impl { +template +struct test_tensor_ostream_impl +{ static void run() { Eigen::Tensor t = {3}; @@ -38,8 +40,9 @@ struct test_tensor_ostream_impl { } }; -template -struct test_tensor_ostream_impl { +template +struct test_tensor_ostream_impl +{ static void run() { Eigen::Tensor t = {3, 2}; @@ -50,8 +53,9 @@ struct test_tensor_ostream_impl { } }; -template -struct test_tensor_ostream_impl { +template +struct test_tensor_ostream_impl +{ static void run() { Eigen::Tensor t = {4, 3, 2}; @@ -62,8 +66,9 @@ struct test_tensor_ostream_impl { } }; -template -struct test_tensor_ostream_impl { +template +struct test_tensor_ostream_impl +{ static void run() { Eigen::Tensor t = {3, 2}; @@ -74,8 +79,9 @@ struct test_tensor_ostream_impl { } }; -template -struct test_tensor_ostream_impl, 2, Layout> { +template +struct test_tensor_ostream_impl, 2, Layout> +{ static void run() { Eigen::Tensor, 2> t = {3, 2}; -- GitLab From 55def9495d60631261e88581d56810bf72581ab4 Mon Sep 17 00:00:00 2001 From: Matthias Peschke Date: Tue, 8 Dec 2020 09:48:42 +0100 Subject: [PATCH 26/29] Reimplemented the Tensor stream output. The implementation structure is based on the IO for Eigen::Matrix. Predefined formats in namespace Eigen::IOFormats are defined for numpy-like output, native output and short output. More can be added. --- unsupported/Eigen/CXX11/src/Tensor/TensorIO.h | 1 + 1 file changed, 1 insertion(+) diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h b/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h index 53b65f8d2..30a0f33b5 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h +++ b/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h @@ -2,6 +2,7 @@ // for linear algebra. // // Copyright (C) 2014 Benoit Steiner +// Copyright (C) 2020 Matthias Peschke // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -- GitLab From 1295c10662386eef304bfa19eeec209be654d234 Mon Sep 17 00:00:00 2001 From: Matthias Peschke Date: Wed, 3 Mar 2021 10:26:41 +0100 Subject: [PATCH 27/29] Improved the new Tensor stream operator, implementation is now fully c++11 compliant. Added test case for the Tensor stream operator. Added documentation for the Tensor stream operator. --- unsupported/Eigen/CXX11/src/Tensor/TensorIO.h | 1 - 1 file changed, 1 deletion(-) diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h b/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h index 30a0f33b5..53b65f8d2 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h +++ b/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h @@ -2,7 +2,6 @@ // for linear algebra. // // Copyright (C) 2014 Benoit Steiner -// Copyright (C) 2020 Matthias Peschke // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed -- GitLab From fdf4cd0e75987836e8edfbf1a1c3f39c9f40b9bf Mon Sep 17 00:00:00 2001 From: Matthias Peschke Date: Thu, 2 Sep 2021 11:58:43 +0200 Subject: [PATCH 28/29] Restore correct formatting of cxx11_tensor_io test. --- unsupported/test/cxx11_tensor_io.cpp | 30 +++++++++++----------------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/unsupported/test/cxx11_tensor_io.cpp b/unsupported/test/cxx11_tensor_io.cpp index dbd306f0b..5de154443 100644 --- a/unsupported/test/cxx11_tensor_io.cpp +++ b/unsupported/test/cxx11_tensor_io.cpp @@ -14,9 +14,8 @@ template struct test_tensor_ostream_impl {}; -template -struct test_tensor_ostream_impl -{ +template +struct test_tensor_ostream_impl { static void run() { Eigen::Tensor t; @@ -27,9 +26,8 @@ struct test_tensor_ostream_impl } }; -template -struct test_tensor_ostream_impl -{ +template +struct test_tensor_ostream_impl { static void run() { Eigen::Tensor t = {3}; @@ -40,9 +38,8 @@ struct test_tensor_ostream_impl } }; -template -struct test_tensor_ostream_impl -{ +template +struct test_tensor_ostream_impl { static void run() { Eigen::Tensor t = {3, 2}; @@ -53,9 +50,8 @@ struct test_tensor_ostream_impl } }; -template -struct test_tensor_ostream_impl -{ +template +struct test_tensor_ostream_impl { static void run() { Eigen::Tensor t = {4, 3, 2}; @@ -66,9 +62,8 @@ struct test_tensor_ostream_impl } }; -template -struct test_tensor_ostream_impl -{ +template +struct test_tensor_ostream_impl { static void run() { Eigen::Tensor t = {3, 2}; @@ -79,9 +74,8 @@ struct test_tensor_ostream_impl } }; -template -struct test_tensor_ostream_impl, 2, Layout> -{ +template +struct test_tensor_ostream_impl, 2, Layout> { static void run() { Eigen::Tensor, 2> t = {3, 2}; -- GitLab From ad338c51c38b099022edf2773916fa8f8c474765 Mon Sep 17 00:00:00 2001 From: Matthias Peschke Date: Fri, 12 Nov 2021 11:42:12 +0100 Subject: [PATCH 29/29] Applied clang-format, corrected Eigen::TensorIOFormats::Native(), removed unwanted copyright changes. --- unsupported/Eigen/CXX11/src/Tensor/TensorIO.h | 612 +++++++++--------- unsupported/test/cxx11_tensor_io.cpp | 183 +++--- 2 files changed, 399 insertions(+), 396 deletions(-) diff --git a/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h b/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h index 53b65f8d2..3e95f95fa 100644 --- a/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h +++ b/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h @@ -17,350 +17,358 @@ namespace Eigen { struct TensorIOFormat; namespace internal { -template struct TensorPrinter; +template +struct TensorPrinter; } -struct TensorIOFormat -{ - TensorIOFormat(const std::vector& _separator, const std::vector& _prefix, const std::vector& _suffix, - int _precision = StreamPrecision, int _flags = 0, const std::string& _tenPrefix="", const std::string& _tenSuffix="", const char _fill=' ') - : tenPrefix(_tenPrefix), tenSuffix(_tenSuffix), prefix(_prefix), suffix(_suffix), separator(_separator), - fill(_fill), precision(_precision), flags(_flags) { - init_spacer(); +struct TensorIOFormat { + TensorIOFormat(const std::vector& _separator, const std::vector& _prefix, + const std::vector& _suffix, int _precision = StreamPrecision, int _flags = 0, + const std::string& _tenPrefix = "", const std::string& _tenSuffix = "", const char _fill = ' ') + : tenPrefix(_tenPrefix), + tenSuffix(_tenSuffix), + prefix(_prefix), + suffix(_suffix), + separator(_separator), + fill(_fill), + precision(_precision), + flags(_flags) { + init_spacer(); + } + + TensorIOFormat(int _precision = StreamPrecision, int _flags = 0, const std::string& _tenPrefix = "", + const std::string& _tenSuffix = "", const char _fill = ' ') + : tenPrefix(_tenPrefix), tenSuffix(_tenSuffix), fill(_fill), precision(_precision), flags(_flags) { + // default values of prefix, suffix and separator + prefix = {"", "["}; + suffix = {"", "]"}; + separator = {", ", "\n"}; + + init_spacer(); + } + + void init_spacer() { + if ((flags & DontAlignCols)) return; + spacer.resize(prefix.size()); + spacer[0] = ""; + int i = int(tenPrefix.length()) - 1; + while (i >= 0 && tenPrefix[i] != '\n') { + spacer[0] += ' '; + i--; } - TensorIOFormat(int _precision = StreamPrecision, int _flags = 0, const std::string& _tenPrefix="", const std::string& _tenSuffix="", const char _fill=' ') - : tenPrefix(_tenPrefix), tenSuffix(_tenSuffix), fill(_fill), precision(_precision), flags(_flags) { - // default values of prefix, suffix and separator - prefix = {"", "["}; - suffix = {"", "]"}; - separator = {", ", "\n"}; - - init_spacer(); - } - - void init_spacer() { - if((flags & DontAlignCols)) - return; - spacer.resize(prefix.size()); - spacer[0] = ""; - int i = int(tenPrefix.length())-1; - while (i>=0 && tenPrefix[i]!='\n') { - spacer[0] += ' '; + for (std::size_t k = 1; k < prefix.size(); k++) { + int i = int(prefix[k].length()) - 1; + while (i >= 0 && prefix[k][i] != '\n') { + spacer[k] += ' '; i--; } - - for (std::size_t k=1; k=0 && prefix[k][i]!='\n') { - spacer[k] += ' '; - i--; - } - } - } - - static inline const TensorIOFormat Numpy() { - std::vector prefix = {"", "["}; - std::vector suffix = {"", "]"}; - std::vector separator = {" ", "\n"}; - return TensorIOFormat(separator, prefix, suffix, StreamPrecision, 0, "[" , "]"); } - - static inline const TensorIOFormat Plain() { - std::vector separator = {" ", "\n", "\n", ""}; - std::vector prefix = {""}; - std::vector suffix = {""}; - return TensorIOFormat(separator, prefix, suffix, StreamPrecision, 0, "" , "", ' '); - } - - static inline const TensorIOFormat Native() { - std::vector separator = {", ", "\n"}; - std::vector prefix = {"", "{"}; - std::vector suffix = {"", "},"}; - return TensorIOFormat(separator, prefix, suffix, StreamPrecision, 0, "{" , "}", ' '); - } - - static inline const TensorIOFormat Legacy() { - TensorIOFormat LegacyFormat(StreamPrecision, 0, "", "", ' '); - LegacyFormat.legacy_bit = true; - return LegacyFormat; - } - - std::string tenPrefix; - std::string tenSuffix; - std::vector prefix; - std::vector suffix; - std::vector separator; - char fill; - int precision; - int flags; - std::vector spacer{}; - bool legacy_bit = false; + } + + static inline const TensorIOFormat Numpy() { + std::vector prefix = {"", "["}; + std::vector suffix = {"", "]"}; + std::vector separator = {" ", "\n"}; + return TensorIOFormat(separator, prefix, suffix, StreamPrecision, 0, "[", "]"); + } + + static inline const TensorIOFormat Plain() { + std::vector separator = {" ", "\n", "\n", ""}; + std::vector prefix = {""}; + std::vector suffix = {""}; + return TensorIOFormat(separator, prefix, suffix, StreamPrecision, 0, "", "", ' '); + } + + static inline const TensorIOFormat Native() { + std::vector separator = {", ", ",\n", "\n"}; + std::vector prefix = {"", "{"}; + std::vector suffix = {"", "}"}; + return TensorIOFormat(separator, prefix, suffix, StreamPrecision, 0, "{", "}", ' '); + } + + static inline const TensorIOFormat Legacy() { + TensorIOFormat LegacyFormat(StreamPrecision, 0, "", "", ' '); + LegacyFormat.legacy_bit = true; + return LegacyFormat; + } + + std::string tenPrefix; + std::string tenSuffix; + std::vector prefix; + std::vector suffix; + std::vector separator; + char fill; + int precision; + int flags; + std::vector spacer{}; + bool legacy_bit = false; }; -template class TensorWithFormat; -//specialize for Layout=ColMajor, Layout=RowMajor and rank=0. -template -class TensorWithFormat -{ -public: - - TensorWithFormat(const T& tensor, const TensorIOFormat& format) - : t_tensor(tensor), t_format(format) {} - - friend std::ostream & operator << (std::ostream & os, const TensorWithFormat& wf) { - // Evaluate the expression if needed - typedef TensorEvaluator, DefaultDevice> Evaluator; - TensorForcedEvalOp eval = wf.t_tensor.eval(); - Evaluator tensor(eval, DefaultDevice()); - tensor.evalSubExprsIfNeeded(NULL); - internal::TensorPrinter::run(os, tensor, wf.t_format); - // Cleanup. - tensor.cleanup(); - return os; - } - -protected: - T t_tensor; - TensorIOFormat t_format; +template +class TensorWithFormat; +// specialize for Layout=ColMajor, Layout=RowMajor and rank=0. +template +class TensorWithFormat { + public: + TensorWithFormat(const T& tensor, const TensorIOFormat& format) : t_tensor(tensor), t_format(format) {} + + friend std::ostream& operator<<(std::ostream& os, const TensorWithFormat& wf) { + // Evaluate the expression if needed + typedef TensorEvaluator, DefaultDevice> Evaluator; + TensorForcedEvalOp eval = wf.t_tensor.eval(); + Evaluator tensor(eval, DefaultDevice()); + tensor.evalSubExprsIfNeeded(NULL); + internal::TensorPrinter::run(os, tensor, wf.t_format); + // Cleanup. + tensor.cleanup(); + return os; + } + + protected: + T t_tensor; + TensorIOFormat t_format; }; -template -class TensorWithFormat -{ -public: - TensorWithFormat(const T& tensor, const TensorIOFormat& format) - : t_tensor(tensor), t_format(format) {} - - friend std::ostream & operator << (std::ostream & os, const TensorWithFormat& wf) { - // Switch to RowMajor storage and print afterwards - typedef typename T::Index Index; - std::array shuffle; - std::array id; std::iota(id.begin(), id.end(), Index(0)); - std::copy(id.begin(), id.end(), shuffle.rbegin()); - auto tensor_row_major = wf.t_tensor.swap_layout().shuffle(shuffle); - - // Evaluate the expression if needed - typedef TensorEvaluator, DefaultDevice> Evaluator; - TensorForcedEvalOp eval = tensor_row_major.eval(); - Evaluator tensor(eval, DefaultDevice()); - tensor.evalSubExprsIfNeeded(NULL); - internal::TensorPrinter::run(os, tensor, wf.t_format); - // Cleanup. - tensor.cleanup(); - return os; - } - -protected: - T t_tensor; - TensorIOFormat t_format; +template +class TensorWithFormat { + public: + TensorWithFormat(const T& tensor, const TensorIOFormat& format) : t_tensor(tensor), t_format(format) {} + + friend std::ostream& operator<<(std::ostream& os, const TensorWithFormat& wf) { + // Switch to RowMajor storage and print afterwards + typedef typename T::Index Index; + std::array shuffle; + std::array id; + std::iota(id.begin(), id.end(), Index(0)); + std::copy(id.begin(), id.end(), shuffle.rbegin()); + auto tensor_row_major = wf.t_tensor.swap_layout().shuffle(shuffle); + + // Evaluate the expression if needed + typedef TensorEvaluator, DefaultDevice> Evaluator; + TensorForcedEvalOp eval = tensor_row_major.eval(); + Evaluator tensor(eval, DefaultDevice()); + tensor.evalSubExprsIfNeeded(NULL); + internal::TensorPrinter::run(os, tensor, wf.t_format); + // Cleanup. + tensor.cleanup(); + return os; + } + + protected: + T t_tensor; + TensorIOFormat t_format; }; -template -class TensorWithFormat -{ -public: - TensorWithFormat(const T& tensor, const TensorIOFormat& format) - : t_tensor(tensor), t_format(format) {} - - friend std::ostream & operator << (std::ostream & os, const TensorWithFormat& wf) { - // Evaluate the expression if needed - typedef TensorEvaluator, DefaultDevice> Evaluator; - TensorForcedEvalOp eval = wf.t_tensor.eval(); - Evaluator tensor(eval, DefaultDevice()); - tensor.evalSubExprsIfNeeded(NULL); - internal::TensorPrinter::run(os, tensor, wf.t_format); - // Cleanup. - tensor.cleanup(); - return os; - } - -protected: - T t_tensor; - TensorIOFormat t_format; +template +class TensorWithFormat { + public: + TensorWithFormat(const T& tensor, const TensorIOFormat& format) : t_tensor(tensor), t_format(format) {} + + friend std::ostream& operator<<(std::ostream& os, const TensorWithFormat& wf) { + // Evaluate the expression if needed + typedef TensorEvaluator, DefaultDevice> Evaluator; + TensorForcedEvalOp eval = wf.t_tensor.eval(); + Evaluator tensor(eval, DefaultDevice()); + tensor.evalSubExprsIfNeeded(NULL); + internal::TensorPrinter::run(os, tensor, wf.t_format); + // Cleanup. + tensor.cleanup(); + return os; + } + + protected: + T t_tensor; + TensorIOFormat t_format; }; namespace internal { template struct TensorPrinter { - static void run (std::ostream& s, const Tensor& _t, const TensorIOFormat& fmt) { - typedef typename Tensor::Scalar Scalar; - typedef typename Tensor::Index Index; - static const int layout = Tensor::Layout; - // backwards compatibility case: print tensor after reshaping to matrix of size dim(0) x (dim(1)*dim(2)*...*dim(rank-1)). - if (fmt.legacy_bit) { - const Index total_size = internal::array_prod(_t.dimensions()); - if (total_size > 0) { - const Index first_dim = Eigen::internal::array_get<0>(_t.dimensions()); - Map > matrix(const_cast(_t.data()), first_dim, total_size/first_dim); - s << matrix; - return; - } + static void run(std::ostream& s, const Tensor& _t, const TensorIOFormat& fmt) { + typedef typename Tensor::Scalar Scalar; + typedef typename Tensor::Index Index; + static const int layout = Tensor::Layout; + // backwards compatibility case: print tensor after reshaping to matrix of size dim(0) x + // (dim(1)*dim(2)*...*dim(rank-1)). + if (fmt.legacy_bit) { + const Index total_size = internal::array_prod(_t.dimensions()); + if (total_size > 0) { + const Index first_dim = Eigen::internal::array_get<0>(_t.dimensions()); + Map > matrix(const_cast(_t.data()), first_dim, + total_size / first_dim); + s << matrix; + return; } + } - assert(layout == RowMajor); - typedef typename - conditional< - is_same::value || - is_same::value || - is_same::value || - is_same::value, - int, - typename conditional< - is_same >::value || - is_same >::value || - is_same >::value || - is_same >::value, - std::complex, - const Scalar& - >::type - >::type PrintType; - - const Index total_size = array_prod(_t.dimensions()); - - std::streamsize explicit_precision; - if(fmt.precision == StreamPrecision) { - explicit_precision = 0; - } - else if(fmt.precision == FullPrecision) { - if (NumTraits::IsInteger) { - explicit_precision = 0; - } - else { - explicit_precision = significant_decimals_impl::run(); - } - } - else { - explicit_precision = fmt.precision; - } + assert(layout == RowMajor); + typedef typename conditional::value || is_same::value || + is_same::value || is_same::value, + int, + typename conditional >::value || + is_same >::value || + is_same >::value || + is_same >::value, + std::complex, const Scalar&>::type>::type PrintType; + + const Index total_size = array_prod(_t.dimensions()); + + std::streamsize explicit_precision; + if (fmt.precision == StreamPrecision) { + explicit_precision = 0; + } else if (fmt.precision == FullPrecision) { + if (NumTraits::IsInteger) { + explicit_precision = 0; + } else { + explicit_precision = significant_decimals_impl::run(); + } + } else { + explicit_precision = fmt.precision; + } - std::streamsize old_precision = 0; - if(explicit_precision) old_precision = s.precision(explicit_precision); + std::streamsize old_precision = 0; + if (explicit_precision) old_precision = s.precision(explicit_precision); - Index width = 0; + Index width = 0; - bool align_cols = !(fmt.flags & DontAlignCols); - if(align_cols) { - // compute the largest width - for (Index i=0; i(_t.data()[i]); - width = std::max(width, Index(sstr.str().length())); - } + bool align_cols = !(fmt.flags & DontAlignCols); + if (align_cols) { + // compute the largest width + for (Index i = 0; i < total_size; i++) { + std::stringstream sstr; + sstr.copyfmt(s); + sstr << static_cast(_t.data()[i]); + width = std::max(width, Index(sstr.str().length())); + } + } + std::streamsize old_width = s.width(); + char old_fill_character = s.fill(); + + s << fmt.tenPrefix; + for (Index i = 0; i < total_size; i++) { + std::array is_at_end{}; + std::array is_at_begin{}; + + // is the ith element the end of an coeff (always true), of a row, of a matrix, ...? + for (std::size_t k = 0; k < rank; k++) { + if ((i + 1) % (std::accumulate(_t.dimensions().rbegin(), _t.dimensions().rbegin() + k, 1, + std::multiplies())) == + 0) { + is_at_end[k] = true; } - std::streamsize old_width = s.width(); - char old_fill_character = s.fill(); - - s << fmt.tenPrefix; - for (Index i = 0; i is_at_end{}; - std::array is_at_begin{}; - - //is the ith element the end of an coeff (always true), of a row, of a matrix, ...? - for (std::size_t k=0; k())) == 0) { - is_at_end[k] = true; - } - } - - //is the ith element the begin of an coeff (always true), of a row, of a matrix, ...? - for (std::size_t k=0; k())) == 0) { - is_at_begin[k] = true; - } - } + } - //do we have a line break? - bool is_at_begin_after_newline = false; - for (std::size_t k=0; k())) == + 0) { + is_at_begin[k] = true; + } + } - bool is_at_end_before_newline = false; - for (std::size_t k=0; k=0; k--) { - std::size_t prefix_index = (static_cast(k) < fmt.prefix.size()) ? k : fmt.prefix.size()-1; - if (is_at_begin[k]) {prefix << fmt.prefix[prefix_index];} + bool is_at_end_before_newline = false; + for (std::size_t k = 0; k < rank; k++) { + if (is_at_end[k]) { + std::size_t separator_index = (k < fmt.separator.size()) ? k : fmt.separator.size() - 1; + if (fmt.separator[separator_index].find('\n') != std::string::npos) { + is_at_end_before_newline = true; } + } + } - s << prefix.str(); - if(width) { - s.fill(fmt.fill); - s.width(width); - s << std::right; - } - s << _t.data()[i]; - s << suffix.str(); - if (i < total_size -1) {s << separator.str();} + std::stringstream suffix, prefix, separator; + for (std::size_t k = 0; k < rank; k++) { + std::size_t suffix_index = (k < fmt.suffix.size()) ? k : fmt.suffix.size() - 1; + if (is_at_end[k]) { + suffix << fmt.suffix[suffix_index]; } - s << fmt.tenSuffix; - if(explicit_precision) s.precision(old_precision); - if(width) { - s.fill(old_fill_character); - s.width(old_width); + } + for (std::size_t k = 0; k < rank; k++) { + std::size_t separator_index = (k < fmt.separator.size()) ? k : fmt.separator.size() - 1; + if (is_at_end[k] and + (!is_at_end_before_newline or fmt.separator[separator_index].find('\n') != std::string::npos)) { + separator << fmt.separator[separator_index]; + } + } + for (std::size_t k = 0; k < rank; k++) { + std::size_t spacer_index = (k < fmt.spacer.size()) ? k : fmt.spacer.size() - 1; + if (i != 0 and is_at_begin_after_newline and (!is_at_begin[k] or k == 0)) { + prefix << fmt.spacer[spacer_index]; + } + } + for (int k = rank - 1; k >= 0; k--) { + std::size_t prefix_index = (static_cast(k) < fmt.prefix.size()) ? k : fmt.prefix.size() - 1; + if (is_at_begin[k]) { + prefix << fmt.prefix[prefix_index]; } + } + + s << prefix.str(); + if (width) { + s.fill(fmt.fill); + s.width(width); + s << std::right; + } + s << _t.data()[i]; + s << suffix.str(); + if (i < total_size - 1) { + s << separator.str(); + } + } + s << fmt.tenSuffix; + if (explicit_precision) s.precision(old_precision); + if (width) { + s.fill(old_fill_character); + s.width(old_width); } + } }; template struct TensorPrinter { - static void run (std::ostream& s, const Tensor& _t, const TensorIOFormat& fmt) { - typedef typename Tensor::Scalar Scalar; - - std::streamsize explicit_precision; - if(fmt.precision == StreamPrecision) { + static void run(std::ostream& s, const Tensor& _t, const TensorIOFormat& fmt) { + typedef typename Tensor::Scalar Scalar; + + std::streamsize explicit_precision; + if (fmt.precision == StreamPrecision) { + explicit_precision = 0; + } else if (fmt.precision == FullPrecision) { + if (NumTraits::IsInteger) { explicit_precision = 0; + } else { + explicit_precision = significant_decimals_impl::run(); } - else if(fmt.precision == FullPrecision) { - if (NumTraits::IsInteger) { - explicit_precision = 0; - } - else { - explicit_precision = significant_decimals_impl::run(); - } - } - else { - explicit_precision = fmt.precision; - } + } else { + explicit_precision = fmt.precision; + } - std::streamsize old_precision = 0; - if(explicit_precision) old_precision = s.precision(explicit_precision); + std::streamsize old_precision = 0; + if (explicit_precision) old_precision = s.precision(explicit_precision); - s << fmt.tenPrefix << _t.coeff(0) << fmt.tenSuffix; - if(explicit_precision) s.precision(old_precision); - } + s << fmt.tenPrefix << _t.coeff(0) << fmt.tenSuffix; + if (explicit_precision) s.precision(old_precision); + } }; -} // end namespace internal -template -std::ostream & operator <<(std::ostream & s, const TensorBase & t) -{ - s << t.format(TensorIOFormat::Plain()); - return s; +} // end namespace internal +template +std::ostream& operator<<(std::ostream& s, const TensorBase& t) { + s << t.format(TensorIOFormat::Plain()); + return s; } -} // end namespace Eigen +} // end namespace Eigen -#endif // EIGEN_CXX11_TENSOR_TENSOR_IO_H +#endif // EIGEN_CXX11_TENSOR_TENSOR_IO_H diff --git a/unsupported/test/cxx11_tensor_io.cpp b/unsupported/test/cxx11_tensor_io.cpp index 5de154443..34fcbc3ff 100644 --- a/unsupported/test/cxx11_tensor_io.cpp +++ b/unsupported/test/cxx11_tensor_io.cpp @@ -1,8 +1,7 @@ // This file is part of Eigen, a lightweight C++ template library // for linear algebra. // -// Copyright (C) 2016 Dmitry Vyukov -// Copyright (C) 2016 Benoit Steiner +// Copyright (C) 2014 Benoit Steiner // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed @@ -12,123 +11,119 @@ #include #include -template struct test_tensor_ostream_impl {}; +template +struct test_tensor_ostream_impl {}; template struct test_tensor_ostream_impl { - static void run() - { - Eigen::Tensor t; - t.setValues(1); - std::ostringstream os; - os << t.format(Eigen::TensorIOFormat::Plain()); - VERIFY(os.str() == "1"); - } + static void run() { + Eigen::Tensor t; + t.setValues(1); + std::ostringstream os; + os << t.format(Eigen::TensorIOFormat::Plain()); + VERIFY(os.str() == "1"); + } }; template struct test_tensor_ostream_impl { - static void run() - { - Eigen::Tensor t = {3}; - t.setValues({1, 2, 3}); - std::ostringstream os; - os << t.format(Eigen::TensorIOFormat::Plain()); - VERIFY(os.str() == "1 2 3"); - } + static void run() { + Eigen::Tensor t = {3}; + t.setValues({1, 2, 3}); + std::ostringstream os; + os << t.format(Eigen::TensorIOFormat::Plain()); + VERIFY(os.str() == "1 2 3"); + } }; template struct test_tensor_ostream_impl { - static void run() - { - Eigen::Tensor t = {3, 2}; - t.setValues({{1, 2}, {3, 4}, {5, 6}}); - std::ostringstream os; - os << t.format(Eigen::TensorIOFormat::Plain()); - VERIFY(os.str() == "1 2\n3 4\n5 6"); - } + static void run() { + Eigen::Tensor t = {3, 2}; + t.setValues({{1, 2}, {3, 4}, {5, 6}}); + std::ostringstream os; + os << t.format(Eigen::TensorIOFormat::Plain()); + VERIFY(os.str() == "1 2\n3 4\n5 6"); + } }; template struct test_tensor_ostream_impl { - static void run() - { - Eigen::Tensor t = {4, 3, 2}; - t.setValues({{{1, 2}, {3, 4}, {5, 6}}, {{7, 8}, {9, 10}, {11, 12}}, {{13, 14}, {15, 16}, {17, 18}}, {{19, 20}, {21, 22}, {23, 24}}}); - std::ostringstream os; - os << t.format(Eigen::TensorIOFormat::Plain()); - VERIFY(os.str() == " 1 2\n 3 4\n 5 6\n\n 7 8\n 9 10\n11 12\n\n13 14\n15 16\n17 18\n\n19 20\n21 22\n23 24"); - } + static void run() { + Eigen::Tensor t = {4, 3, 2}; + t.setValues({{{1, 2}, {3, 4}, {5, 6}}, + {{7, 8}, {9, 10}, {11, 12}}, + {{13, 14}, {15, 16}, {17, 18}}, + {{19, 20}, {21, 22}, {23, 24}}}); + std::ostringstream os; + os << t.format(Eigen::TensorIOFormat::Plain()); + VERIFY(os.str() == " 1 2\n 3 4\n 5 6\n\n 7 8\n 9 10\n11 12\n\n13 14\n15 16\n17 18\n\n19 20\n21 22\n23 24"); + } }; template struct test_tensor_ostream_impl { - static void run() - { - Eigen::Tensor t = {3, 2}; - t.setValues({{false, true}, {true, false}, {false, false}}); - std::ostringstream os; - os << t.format(Eigen::TensorIOFormat::Plain()); - VERIFY(os.str() == "0 1\n1 0\n0 0"); - } + static void run() { + Eigen::Tensor t = {3, 2}; + t.setValues({{false, true}, {true, false}, {false, false}}); + std::ostringstream os; + os << t.format(Eigen::TensorIOFormat::Plain()); + VERIFY(os.str() == "0 1\n1 0\n0 0"); + } }; template struct test_tensor_ostream_impl, 2, Layout> { - static void run() - { - Eigen::Tensor, 2> t = {3, 2}; - t.setValues({{std::complex(1, 2), std::complex(12, 3)}, - {std::complex(-4, 2), std::complex(0, 5)}, - {std::complex(-1, 4), std::complex(5, 27)}}); - std::ostringstream os; - os << t.format(Eigen::TensorIOFormat::Plain()); - VERIFY(os.str() == " (1,2) (12,3)\n(-4,2) (0,5)\n(-1,4) (5,27)"); - } + static void run() { + Eigen::Tensor, 2> t = {3, 2}; + t.setValues({{std::complex(1, 2), std::complex(12, 3)}, + {std::complex(-4, 2), std::complex(0, 5)}, + {std::complex(-1, 4), std::complex(5, 27)}}); + std::ostringstream os; + os << t.format(Eigen::TensorIOFormat::Plain()); + VERIFY(os.str() == " (1,2) (12,3)\n(-4,2) (0,5)\n(-1,4) (5,27)"); + } }; -template -void test_tensor_ostream() -{ - test_tensor_ostream_impl::run(); +template +void test_tensor_ostream() { + test_tensor_ostream_impl::run(); } -EIGEN_DECLARE_TEST(cxx11_tensor_io) -{ - CALL_SUBTEST((test_tensor_ostream())); - CALL_SUBTEST((test_tensor_ostream())); - CALL_SUBTEST((test_tensor_ostream())); - CALL_SUBTEST((test_tensor_ostream())); - - CALL_SUBTEST((test_tensor_ostream())); - CALL_SUBTEST((test_tensor_ostream())); - CALL_SUBTEST((test_tensor_ostream())); - CALL_SUBTEST((test_tensor_ostream())); - - CALL_SUBTEST((test_tensor_ostream())); - CALL_SUBTEST((test_tensor_ostream())); - CALL_SUBTEST((test_tensor_ostream())); - CALL_SUBTEST((test_tensor_ostream())); - - CALL_SUBTEST((test_tensor_ostream())); - CALL_SUBTEST((test_tensor_ostream())); - CALL_SUBTEST((test_tensor_ostream())); - CALL_SUBTEST((test_tensor_ostream())); - - CALL_SUBTEST((test_tensor_ostream())); - CALL_SUBTEST((test_tensor_ostream())); - CALL_SUBTEST((test_tensor_ostream())); - CALL_SUBTEST((test_tensor_ostream())); - - CALL_SUBTEST((test_tensor_ostream())); - CALL_SUBTEST((test_tensor_ostream())); - CALL_SUBTEST((test_tensor_ostream())); - CALL_SUBTEST((test_tensor_ostream())); - - CALL_SUBTEST((test_tensor_ostream())); - CALL_SUBTEST((test_tensor_ostream())); - - CALL_SUBTEST((test_tensor_ostream,2,Eigen::ColMajor>())); - CALL_SUBTEST((test_tensor_ostream,2,Eigen::ColMajor>())); +EIGEN_DECLARE_TEST(cxx11_tensor_io) { + CALL_SUBTEST((test_tensor_ostream())); + CALL_SUBTEST((test_tensor_ostream())); + CALL_SUBTEST((test_tensor_ostream())); + CALL_SUBTEST((test_tensor_ostream())); + + CALL_SUBTEST((test_tensor_ostream())); + CALL_SUBTEST((test_tensor_ostream())); + CALL_SUBTEST((test_tensor_ostream())); + CALL_SUBTEST((test_tensor_ostream())); + + CALL_SUBTEST((test_tensor_ostream())); + CALL_SUBTEST((test_tensor_ostream())); + CALL_SUBTEST((test_tensor_ostream())); + CALL_SUBTEST((test_tensor_ostream())); + + CALL_SUBTEST((test_tensor_ostream())); + CALL_SUBTEST((test_tensor_ostream())); + CALL_SUBTEST((test_tensor_ostream())); + CALL_SUBTEST((test_tensor_ostream())); + + CALL_SUBTEST((test_tensor_ostream())); + CALL_SUBTEST((test_tensor_ostream())); + CALL_SUBTEST((test_tensor_ostream())); + CALL_SUBTEST((test_tensor_ostream())); + + CALL_SUBTEST((test_tensor_ostream())); + CALL_SUBTEST((test_tensor_ostream())); + CALL_SUBTEST((test_tensor_ostream())); + CALL_SUBTEST((test_tensor_ostream())); + + CALL_SUBTEST((test_tensor_ostream())); + CALL_SUBTEST((test_tensor_ostream())); + + CALL_SUBTEST((test_tensor_ostream, 2, Eigen::ColMajor>())); + CALL_SUBTEST((test_tensor_ostream, 2, Eigen::ColMajor>())); } -- GitLab