mirror of
https://gitlab.com/libeigen/eigen.git
synced 2024-12-21 07:19:46 +08:00
Merge.
This commit is contained in:
commit
86d6201d7b
@ -130,7 +130,7 @@ template<typename Derived> class MapBase<Derived, ReadOnlyAccessors>
|
||||
explicit inline MapBase(PointerType dataPtr) : m_data(dataPtr), m_rows(RowsAtCompileTime), m_cols(ColsAtCompileTime)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
|
||||
checkSanity();
|
||||
checkSanity<Derived>();
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
@ -142,7 +142,7 @@ template<typename Derived> class MapBase<Derived, ReadOnlyAccessors>
|
||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||
eigen_assert(vecSize >= 0);
|
||||
eigen_assert(dataPtr == 0 || SizeAtCompileTime == Dynamic || SizeAtCompileTime == vecSize);
|
||||
checkSanity();
|
||||
checkSanity<Derived>();
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
@ -152,7 +152,7 @@ template<typename Derived> class MapBase<Derived, ReadOnlyAccessors>
|
||||
eigen_assert( (dataPtr == 0)
|
||||
|| ( rows >= 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
|
||||
&& cols >= 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols)));
|
||||
checkSanity();
|
||||
checkSanity<Derived>();
|
||||
}
|
||||
|
||||
#ifdef EIGEN_MAPBASE_PLUGIN
|
||||
@ -161,14 +161,21 @@ template<typename Derived> class MapBase<Derived, ReadOnlyAccessors>
|
||||
|
||||
protected:
|
||||
|
||||
template<typename T>
|
||||
EIGEN_DEVICE_FUNC
|
||||
void checkSanity() const
|
||||
void checkSanity(typename internal::enable_if<(internal::traits<T>::Alignment>0),void*>::type = 0) const
|
||||
{
|
||||
#if EIGEN_MAX_ALIGN_BYTES>0
|
||||
eigen_assert(((size_t(m_data) % EIGEN_PLAIN_ENUM_MAX(1,internal::traits<Derived>::Alignment)) == 0) && "data is not aligned");
|
||||
eigen_assert(( ((size_t(m_data) % internal::traits<Derived>::Alignment) == 0)
|
||||
|| (cols() * rows() * innerStride() * sizeof(Scalar)) < internal::traits<Derived>::Alignment ) && "data is not aligned");
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
EIGEN_DEVICE_FUNC
|
||||
void checkSanity(typename internal::enable_if<internal::traits<T>::Alignment==0,void*>::type = 0) const
|
||||
{}
|
||||
|
||||
PointerType m_data;
|
||||
const internal::variable_if_dynamic<Index, RowsAtCompileTime> m_rows;
|
||||
const internal::variable_if_dynamic<Index, ColsAtCompileTime> m_cols;
|
||||
|
@ -59,28 +59,6 @@
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef EIGEN_HAS_POSIX_MEMALIGN
|
||||
// See bug 554 (http://eigen.tuxfamily.org/bz/show_bug.cgi?id=554)
|
||||
// It seems to be unsafe to check _POSIX_ADVISORY_INFO without including unistd.h first.
|
||||
// Currently, let's include it only on unix systems:
|
||||
#if EIGEN_OS_UNIX && !(EIGEN_OS_SUN || EIGEN_OS_SOLARIS)
|
||||
#include <unistd.h>
|
||||
#if (EIGEN_OS_QNX || (defined _GNU_SOURCE) || EIGEN_COMP_PGI || ((defined _XOPEN_SOURCE) && (_XOPEN_SOURCE >= 600))) && (defined _POSIX_ADVISORY_INFO) && (_POSIX_ADVISORY_INFO > 0)
|
||||
#define EIGEN_HAS_POSIX_MEMALIGN 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef EIGEN_HAS_POSIX_MEMALIGN
|
||||
#define EIGEN_HAS_POSIX_MEMALIGN 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined EIGEN_VECTORIZE_SSE || defined EIGEN_VECTORIZE_AVX
|
||||
#define EIGEN_HAS_MM_MALLOC 1
|
||||
#else
|
||||
#define EIGEN_HAS_MM_MALLOC 0
|
||||
#endif
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
namespace internal {
|
||||
@ -122,7 +100,7 @@ inline void handmade_aligned_free(void *ptr)
|
||||
|
||||
/** \internal
|
||||
* \brief Reallocates aligned memory.
|
||||
* Since we know that our handmade version is based on std::realloc
|
||||
* Since we know that our handmade version is based on std::malloc
|
||||
* we can use std::realloc to implement efficient reallocation.
|
||||
*/
|
||||
inline void* handmade_aligned_realloc(void* ptr, std::size_t size, std::size_t = 0)
|
||||
@ -141,47 +119,6 @@ inline void* handmade_aligned_realloc(void* ptr, std::size_t size, std::size_t =
|
||||
return aligned;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*** Implementation of generic aligned realloc (when no realloc can be used)***
|
||||
*****************************************************************************/
|
||||
|
||||
EIGEN_DEVICE_FUNC void* aligned_malloc(std::size_t size);
|
||||
EIGEN_DEVICE_FUNC void aligned_free(void *ptr);
|
||||
|
||||
/** \internal
|
||||
* \brief Reallocates aligned memory.
|
||||
* Allows reallocation with aligned ptr types. This implementation will
|
||||
* always create a new memory chunk and copy the old data.
|
||||
*/
|
||||
inline void* generic_aligned_realloc(void* ptr, size_t size, size_t old_size)
|
||||
{
|
||||
if (ptr==0)
|
||||
return aligned_malloc(size);
|
||||
|
||||
if (size==0)
|
||||
{
|
||||
aligned_free(ptr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* newptr = aligned_malloc(size);
|
||||
if (newptr == 0)
|
||||
{
|
||||
#ifdef EIGEN_HAS_ERRNO
|
||||
errno = ENOMEM; // according to the standard
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ptr != 0)
|
||||
{
|
||||
std::memcpy(newptr, ptr, (std::min)(size,old_size));
|
||||
aligned_free(ptr);
|
||||
}
|
||||
|
||||
return newptr;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*** Implementation of portable aligned versions of malloc/free/realloc ***
|
||||
*****************************************************************************/
|
||||
@ -218,16 +155,11 @@ EIGEN_DEVICE_FUNC inline void* aligned_malloc(size_t size)
|
||||
check_that_malloc_is_allowed();
|
||||
|
||||
void *result;
|
||||
#if EIGEN_DEFAULT_ALIGN_BYTES==0
|
||||
#if (EIGEN_DEFAULT_ALIGN_BYTES==0) || EIGEN_MALLOC_ALREADY_ALIGNED
|
||||
result = std::malloc(size);
|
||||
#elif EIGEN_MALLOC_ALREADY_ALIGNED
|
||||
result = std::malloc(size);
|
||||
#elif EIGEN_HAS_POSIX_MEMALIGN
|
||||
if(posix_memalign(&result, EIGEN_DEFAULT_ALIGN_BYTES, size)) result = 0;
|
||||
#elif EIGEN_HAS_MM_MALLOC
|
||||
result = _mm_malloc(size, EIGEN_DEFAULT_ALIGN_BYTES);
|
||||
#elif EIGEN_OS_WIN_STRICT
|
||||
result = _aligned_malloc(size, EIGEN_DEFAULT_ALIGN_BYTES);
|
||||
#if EIGEN_DEFAULT_ALIGN_BYTES==16
|
||||
eigen_assert((size<16 || (std::size_t(result)%16)==0) && "System's malloc returned an unaligned pointer. Compile with EIGEN_MALLOC_ALREADY_ALIGNED=0 to fallback to handmade alignd memory allocator.");
|
||||
#endif
|
||||
#else
|
||||
result = handmade_aligned_malloc(size);
|
||||
#endif
|
||||
@ -241,48 +173,25 @@ EIGEN_DEVICE_FUNC inline void* aligned_malloc(size_t size)
|
||||
/** \internal Frees memory allocated with aligned_malloc. */
|
||||
EIGEN_DEVICE_FUNC inline void aligned_free(void *ptr)
|
||||
{
|
||||
#if EIGEN_DEFAULT_ALIGN_BYTES==0
|
||||
#if (EIGEN_DEFAULT_ALIGN_BYTES==0) || EIGEN_MALLOC_ALREADY_ALIGNED
|
||||
std::free(ptr);
|
||||
#elif EIGEN_MALLOC_ALREADY_ALIGNED
|
||||
std::free(ptr);
|
||||
#elif EIGEN_HAS_POSIX_MEMALIGN
|
||||
std::free(ptr);
|
||||
#elif EIGEN_HAS_MM_MALLOC
|
||||
_mm_free(ptr);
|
||||
#elif EIGEN_OS_WIN_STRICT
|
||||
_aligned_free(ptr);
|
||||
#else
|
||||
handmade_aligned_free(ptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* \internal
|
||||
* \brief Reallocates an aligned block of memory.
|
||||
* \throws std::bad_alloc on allocation failure
|
||||
**/
|
||||
* \internal
|
||||
* \brief Reallocates an aligned block of memory.
|
||||
* \throws std::bad_alloc on allocation failure
|
||||
*/
|
||||
inline void* aligned_realloc(void *ptr, size_t new_size, size_t old_size)
|
||||
{
|
||||
EIGEN_UNUSED_VARIABLE(old_size);
|
||||
|
||||
void *result;
|
||||
#if EIGEN_DEFAULT_ALIGN_BYTES==0
|
||||
#if (EIGEN_DEFAULT_ALIGN_BYTES==0) || EIGEN_MALLOC_ALREADY_ALIGNED
|
||||
result = std::realloc(ptr,new_size);
|
||||
#elif EIGEN_MALLOC_ALREADY_ALIGNED
|
||||
result = std::realloc(ptr,new_size);
|
||||
#elif EIGEN_HAS_POSIX_MEMALIGN
|
||||
result = generic_aligned_realloc(ptr,new_size,old_size);
|
||||
#elif EIGEN_HAS_MM_MALLOC
|
||||
// The defined(_mm_free) is just here to verify that this MSVC version
|
||||
// implements _mm_malloc/_mm_free based on the corresponding _aligned_
|
||||
// functions. This may not always be the case and we just try to be safe.
|
||||
#if EIGEN_OS_WIN_STRICT && defined(_mm_free)
|
||||
result = _aligned_realloc(ptr,new_size,EIGEN_DEFAULT_ALIGN_BYTES);
|
||||
#else
|
||||
result = generic_aligned_realloc(ptr,new_size,old_size);
|
||||
#endif
|
||||
#elif EIGEN_OS_WIN_STRICT
|
||||
result = _aligned_realloc(ptr,new_size,EIGEN_DEFAULT_ALIGN_BYTES);
|
||||
#else
|
||||
result = handmade_aligned_realloc(ptr,new_size,old_size);
|
||||
#endif
|
||||
|
@ -59,6 +59,8 @@ namespace Eigen {
|
||||
\ingroup DenseMatrixManipulation_chapter */
|
||||
/** \addtogroup TutorialMapClass
|
||||
\ingroup DenseMatrixManipulation_chapter */
|
||||
/** \addtogroup TutorialReshapeSlicing
|
||||
\ingroup DenseMatrixManipulation_chapter */
|
||||
/** \addtogroup TopicAliasing
|
||||
\ingroup DenseMatrixManipulation_chapter */
|
||||
/** \addtogroup TopicStorageOrders
|
||||
|
@ -87,9 +87,6 @@ run time. However, these assertions do cost time and can thus be turned off.
|
||||
- \b EIGEN_STACK_ALLOCATION_LIMIT - defines the maximum bytes for a buffer to be allocated on the stack. For internal
|
||||
temporary buffers, dynamic memory allocation is employed as a fall back. For fixed-size matrices or arrays, exceeding
|
||||
this threshold raises a compile time assertion. Use 0 to set no limit. Default is 128 KB.
|
||||
- \b EIGEN_HAS_POSIX_MEMALIGN - defines whether aligned memory allocation can be performed through the \c posix_memalign
|
||||
function. The availability of \c posix_memalign is automatically checked on most platform, but this option allows to
|
||||
by-pass %Eigen's built-in rules.
|
||||
|
||||
|
||||
\section TopicPreprocessorDirectivesPlugins Plugins
|
||||
|
65
doc/TutorialReshapeSlicing.dox
Normal file
65
doc/TutorialReshapeSlicing.dox
Normal file
@ -0,0 +1,65 @@
|
||||
namespace Eigen {
|
||||
|
||||
/** \eigenManualPage TutorialReshapeSlicing Reshape and Slicing
|
||||
|
||||
%Eigen does not expose convenient methods to take slices or to reshape a matrix yet.
|
||||
Nonetheless, such features can easily be emulated using the Map class.
|
||||
|
||||
\eigenAutoToc
|
||||
|
||||
\section TutorialReshape Reshape
|
||||
|
||||
A reshape operation consists in modifying the sizes of a matrix while keeping the same coefficients.
|
||||
Instead of modifying the input matrix itself, which is not possible for compile-time sizes, the approach consist in creating a different \em view on the storage using class Map.
|
||||
Here is a typical example creating a 1D linear view of a matrix:
|
||||
|
||||
<table class="example">
|
||||
<tr><th>Example:</th><th>Output:</th></tr>
|
||||
<tr><td>
|
||||
\include Tutorial_ReshapeMat2Vec.cpp
|
||||
</td>
|
||||
<td>
|
||||
\verbinclude Tutorial_ReshapeMat2Vec.out
|
||||
</td></tr></table>
|
||||
|
||||
Remark how the storage order of the input matrix modifies the order of the coefficients in the linear view.
|
||||
Here is another example reshaping a 2x6 matrix to a 6x2 one:
|
||||
<table class="example">
|
||||
<tr><th>Example:</th><th>Output:</th></tr>
|
||||
<tr><td>
|
||||
\include Tutorial_ReshapeMat2Mat.cpp
|
||||
</td>
|
||||
<td>
|
||||
\verbinclude Tutorial_ReshapeMat2Mat.out
|
||||
</td></tr></table>
|
||||
|
||||
|
||||
|
||||
\section TutorialSlicing Slicing
|
||||
|
||||
Slicing consists in taking a set of rows, or columns, or elements, uniformly spaced within a matrix.
|
||||
Again, the class Map allows to easily mimic this feature.
|
||||
|
||||
For instance, one can take skip every P elements in a vector:
|
||||
<table class="example">
|
||||
<tr><th>Example:</th><th>Output:</th></tr>
|
||||
<tr><td>
|
||||
\include Tutorial_SlicingVec.cpp
|
||||
</td>
|
||||
<td>
|
||||
\verbinclude Tutorial_SlicingVec.out
|
||||
</td></tr></table>
|
||||
|
||||
One can olso take one column over three using an adequate outer-stride or inner-stride depending on the actual storage order:
|
||||
<table class="example">
|
||||
<tr><th>Example:</th><th>Output:</th></tr>
|
||||
<tr><td>
|
||||
\include Tutorial_SlicingCol.cpp
|
||||
</td>
|
||||
<td>
|
||||
\verbinclude Tutorial_SlicingCol.out
|
||||
</td></tr></table>
|
||||
|
||||
*/
|
||||
|
||||
}
|
6
doc/snippets/Tutorial_ReshapeMat2Mat.cpp
Normal file
6
doc/snippets/Tutorial_ReshapeMat2Mat.cpp
Normal file
@ -0,0 +1,6 @@
|
||||
MatrixXf M1(2,6); // Column-major storage
|
||||
M1 << 1, 2, 3, 4, 5, 6,
|
||||
7, 8, 9, 10, 11, 12;
|
||||
|
||||
Map<MatrixXf> M2(M1.data(), 6,2);
|
||||
cout << "M2:" << endl << M2 << endl;
|
11
doc/snippets/Tutorial_ReshapeMat2Vec.cpp
Normal file
11
doc/snippets/Tutorial_ReshapeMat2Vec.cpp
Normal file
@ -0,0 +1,11 @@
|
||||
MatrixXf M1(3,3); // Column-major storage
|
||||
M1 << 1, 2, 3,
|
||||
4, 5, 6,
|
||||
7, 8, 9;
|
||||
|
||||
Map<RowVectorXf> v1(M1.data(), M1.size());
|
||||
cout << "v1:" << endl << v1 << endl;
|
||||
|
||||
Matrix<float,Dynamic,Dynamic,RowMajor> M2(M1);
|
||||
Map<RowVectorXf> v2(M2.data(), M2.size());
|
||||
cout << "v2:" << endl << v2 << endl;
|
11
doc/snippets/Tutorial_SlicingCol.cpp
Normal file
11
doc/snippets/Tutorial_SlicingCol.cpp
Normal file
@ -0,0 +1,11 @@
|
||||
MatrixXf M1 = MatrixXf::Random(3,8);
|
||||
cout << "Column major input:" << endl << M1 << "\n";
|
||||
Map<MatrixXf,0,OuterStride<> > M2(M1.data(), M1.rows(), (M1.cols()+2)/3, OuterStride<>(M1.outerStride()*3));
|
||||
cout << "1 column over 3:" << endl << M2 << "\n";
|
||||
|
||||
typedef Matrix<float,Dynamic,Dynamic,RowMajor> RowMajorMatrixXf;
|
||||
RowMajorMatrixXf M3(M1);
|
||||
cout << "Row major input:" << endl << M3 << "\n";
|
||||
Map<RowMajorMatrixXf,0,Stride<Dynamic,3> > M4(M3.data(), M3.rows(), (M3.cols()+2)/3,
|
||||
Stride<Dynamic,3>(M3.outerStride(),3));
|
||||
cout << "1 column over 3:" << endl << M4 << "\n";
|
4
doc/snippets/Tutorial_SlicingVec.cpp
Normal file
4
doc/snippets/Tutorial_SlicingVec.cpp
Normal file
@ -0,0 +1,4 @@
|
||||
RowVectorXf v = RowVectorXf::LinSpaced(20,0,19);
|
||||
cout << "Input:" << endl << v << endl;
|
||||
Map<RowVectorXf,0,InnerStride<2> > v2(v.data(), v.size()/2);
|
||||
cout << "Even:" << v2 << endl;
|
@ -31,7 +31,7 @@ void check_handmade_aligned_malloc()
|
||||
|
||||
void check_aligned_malloc()
|
||||
{
|
||||
for(int i = 1; i < 1000; i++)
|
||||
for(int i = ALIGNMENT; i < 1000; i++)
|
||||
{
|
||||
char *p = (char*)internal::aligned_malloc(i);
|
||||
VERIFY(size_t(p)%ALIGNMENT==0);
|
||||
@ -43,7 +43,7 @@ void check_aligned_malloc()
|
||||
|
||||
void check_aligned_new()
|
||||
{
|
||||
for(int i = 1; i < 1000; i++)
|
||||
for(int i = ALIGNMENT; i < 1000; i++)
|
||||
{
|
||||
float *p = internal::aligned_new<float>(i);
|
||||
VERIFY(size_t(p)%ALIGNMENT==0);
|
||||
@ -55,7 +55,7 @@ void check_aligned_new()
|
||||
|
||||
void check_aligned_stack_alloc()
|
||||
{
|
||||
for(int i = 1; i < 400; i++)
|
||||
for(int i = ALIGNMENT; i < 400; i++)
|
||||
{
|
||||
ei_declare_aligned_stack_constructed_variable(float,p,i,0);
|
||||
VERIFY(size_t(p)%ALIGNMENT==0);
|
||||
|
@ -40,7 +40,7 @@ template<typename VectorType> void map_class_vector(const VectorType& m)
|
||||
VERIFY_IS_EQUAL(ma1, ma3);
|
||||
VERIFY_IS_EQUAL(ma1, ma4);
|
||||
#ifdef EIGEN_VECTORIZE
|
||||
if(internal::packet_traits<Scalar>::Vectorizable)
|
||||
if(internal::packet_traits<Scalar>::Vectorizable && size>=AlignedMax)
|
||||
VERIFY_RAISES_ASSERT((Map<VectorType,AlignedMax>(array3unaligned, size)))
|
||||
#endif
|
||||
|
||||
|
@ -49,8 +49,8 @@ template<typename MatrixType> void zeroSizedMatrix()
|
||||
|
||||
if(MatrixType::MaxColsAtCompileTime!=0 && MatrixType::MaxRowsAtCompileTime!=0)
|
||||
{
|
||||
Index rows = MatrixType::RowsAtCompileTime==Dynamic ? internal::random<Index>(1,10) : MatrixType::RowsAtCompileTime;
|
||||
Index cols = MatrixType::ColsAtCompileTime==Dynamic ? internal::random<Index>(1,10) : MatrixType::ColsAtCompileTime;
|
||||
Index rows = MatrixType::RowsAtCompileTime==Dynamic ? internal::random<Index>(1,10) : Index(MatrixType::RowsAtCompileTime);
|
||||
Index cols = MatrixType::ColsAtCompileTime==Dynamic ? internal::random<Index>(1,10) : Index(MatrixType::ColsAtCompileTime);
|
||||
MatrixType m(rows,cols);
|
||||
zeroReduction(m.template block<0,MatrixType::ColsAtCompileTime>(0,0,0,cols));
|
||||
zeroReduction(m.template block<MatrixType::RowsAtCompileTime,0>(0,0,rows,0));
|
||||
|
@ -206,7 +206,7 @@ struct TensorEvaluator<const TensorFFTOp<FFT, ArgType, FFTResultType, FFTDir>, D
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < m_fft.size(); ++i) {
|
||||
int dim = m_fft[i];
|
||||
Index dim = m_fft[i];
|
||||
eigen_assert(dim >= 0 && dim < NumDims);
|
||||
Index line_len = m_dimensions[dim];
|
||||
eigen_assert(line_len >= 1);
|
||||
|
@ -117,7 +117,6 @@ if(EIGEN_TEST_CXX11)
|
||||
ei_add_test(cxx11_tensor_of_const_values "-std=c++0x")
|
||||
ei_add_test(cxx11_tensor_of_complex "-std=c++0x")
|
||||
ei_add_test(cxx11_tensor_of_strings "-std=c++0x")
|
||||
ei_add_test(cxx11_tensor_uint128 "-std=c++0x")
|
||||
ei_add_test(cxx11_tensor_intdiv "-std=c++0x")
|
||||
ei_add_test(cxx11_tensor_lvalue "-std=c++0x")
|
||||
ei_add_test(cxx11_tensor_map "-std=c++0x")
|
||||
@ -149,6 +148,11 @@ if(EIGEN_TEST_CXX11)
|
||||
ei_add_test(cxx11_tensor_ifft "-std=c++0x")
|
||||
ei_add_test(cxx11_tensor_empty "-std=c++0x")
|
||||
|
||||
if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
|
||||
# This test requires __uint128_t which is only available on 64bit systems
|
||||
ei_add_test(cxx11_tensor_uint128 "-std=c++0x")
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
# These tests needs nvcc
|
||||
|
@ -14,7 +14,7 @@ using Eigen::Tensor;
|
||||
|
||||
template <int DataLayout>
|
||||
static void test_fft_2D_golden() {
|
||||
Tensor<float, 2, DataLayout, long> input(2, 3);
|
||||
Tensor<float, 2, DataLayout> input(2, 3);
|
||||
input(0, 0) = 1;
|
||||
input(0, 1) = 2;
|
||||
input(0, 2) = 3;
|
||||
@ -22,11 +22,11 @@ static void test_fft_2D_golden() {
|
||||
input(1, 1) = 5;
|
||||
input(1, 2) = 6;
|
||||
|
||||
array<int, 2> fft;
|
||||
array<ptrdiff_t, 2> fft;
|
||||
fft[0] = 0;
|
||||
fft[1] = 1;
|
||||
|
||||
Tensor<std::complex<float>, 2, DataLayout, long> output = input.template fft<Eigen::BothParts, Eigen::FFT_FORWARD>(fft);
|
||||
Tensor<std::complex<float>, 2, DataLayout> output = input.template fft<Eigen::BothParts, Eigen::FFT_FORWARD>(fft);
|
||||
|
||||
std::complex<float> output_golden[6]; // in ColMajor order
|
||||
output_golden[0] = std::complex<float>(21, 0);
|
||||
@ -57,24 +57,24 @@ static void test_fft_2D_golden() {
|
||||
}
|
||||
|
||||
static void test_fft_complex_input_golden() {
|
||||
Tensor<std::complex<float>, 1, ColMajor, long> input(5);
|
||||
Tensor<std::complex<float>, 1, ColMajor> input(5);
|
||||
input(0) = std::complex<float>(1, 1);
|
||||
input(1) = std::complex<float>(2, 2);
|
||||
input(2) = std::complex<float>(3, 3);
|
||||
input(3) = std::complex<float>(4, 4);
|
||||
input(4) = std::complex<float>(5, 5);
|
||||
|
||||
array<int, 1> fft;
|
||||
array<ptrdiff_t, 1> fft;
|
||||
fft[0] = 0;
|
||||
|
||||
Tensor<std::complex<float>, 1, ColMajor, long> forward_output_both_parts = input.fft<BothParts, FFT_FORWARD>(fft);
|
||||
Tensor<std::complex<float>, 1, ColMajor, long> reverse_output_both_parts = input.fft<BothParts, FFT_REVERSE>(fft);
|
||||
Tensor<std::complex<float>, 1, ColMajor> forward_output_both_parts = input.fft<BothParts, FFT_FORWARD>(fft);
|
||||
Tensor<std::complex<float>, 1, ColMajor> reverse_output_both_parts = input.fft<BothParts, FFT_REVERSE>(fft);
|
||||
|
||||
Tensor<float, 1, ColMajor, long> forward_output_real_part = input.fft<RealPart, FFT_FORWARD>(fft);
|
||||
Tensor<float, 1, ColMajor, long> reverse_output_real_part = input.fft<RealPart, FFT_REVERSE>(fft);
|
||||
Tensor<float, 1, ColMajor> forward_output_real_part = input.fft<RealPart, FFT_FORWARD>(fft);
|
||||
Tensor<float, 1, ColMajor> reverse_output_real_part = input.fft<RealPart, FFT_REVERSE>(fft);
|
||||
|
||||
Tensor<float, 1, ColMajor, long> forward_output_imag_part = input.fft<ImagPart, FFT_FORWARD>(fft);
|
||||
Tensor<float, 1, ColMajor, long> reverse_output_imag_part = input.fft<ImagPart, FFT_REVERSE>(fft);
|
||||
Tensor<float, 1, ColMajor> forward_output_imag_part = input.fft<ImagPart, FFT_FORWARD>(fft);
|
||||
Tensor<float, 1, ColMajor> reverse_output_imag_part = input.fft<ImagPart, FFT_REVERSE>(fft);
|
||||
|
||||
VERIFY_IS_EQUAL(forward_output_both_parts.dimension(0), input.dimension(0));
|
||||
VERIFY_IS_EQUAL(reverse_output_both_parts.dimension(0), input.dimension(0));
|
||||
@ -114,24 +114,24 @@ static void test_fft_complex_input_golden() {
|
||||
}
|
||||
|
||||
static void test_fft_real_input_golden() {
|
||||
Tensor<float, 1, ColMajor, long> input(5);
|
||||
Tensor<float, 1, ColMajor> input(5);
|
||||
input(0) = 1.0;
|
||||
input(1) = 2.0;
|
||||
input(2) = 3.0;
|
||||
input(3) = 4.0;
|
||||
input(4) = 5.0;
|
||||
|
||||
array<int, 1> fft;
|
||||
array<ptrdiff_t, 1> fft;
|
||||
fft[0] = 0;
|
||||
|
||||
Tensor<std::complex<float>, 1, ColMajor, long> forward_output_both_parts = input.fft<BothParts, FFT_FORWARD>(fft);
|
||||
Tensor<std::complex<float>, 1, ColMajor, long> reverse_output_both_parts = input.fft<BothParts, FFT_REVERSE>(fft);
|
||||
Tensor<std::complex<float>, 1, ColMajor> forward_output_both_parts = input.fft<BothParts, FFT_FORWARD>(fft);
|
||||
Tensor<std::complex<float>, 1, ColMajor> reverse_output_both_parts = input.fft<BothParts, FFT_REVERSE>(fft);
|
||||
|
||||
Tensor<float, 1, ColMajor, long> forward_output_real_part = input.fft<RealPart, FFT_FORWARD>(fft);
|
||||
Tensor<float, 1, ColMajor, long> reverse_output_real_part = input.fft<RealPart, FFT_REVERSE>(fft);
|
||||
Tensor<float, 1, ColMajor> forward_output_real_part = input.fft<RealPart, FFT_FORWARD>(fft);
|
||||
Tensor<float, 1, ColMajor> reverse_output_real_part = input.fft<RealPart, FFT_REVERSE>(fft);
|
||||
|
||||
Tensor<float, 1, ColMajor, long> forward_output_imag_part = input.fft<ImagPart, FFT_FORWARD>(fft);
|
||||
Tensor<float, 1, ColMajor, long> reverse_output_imag_part = input.fft<ImagPart, FFT_REVERSE>(fft);
|
||||
Tensor<float, 1, ColMajor> forward_output_imag_part = input.fft<ImagPart, FFT_FORWARD>(fft);
|
||||
Tensor<float, 1, ColMajor> reverse_output_imag_part = input.fft<ImagPart, FFT_REVERSE>(fft);
|
||||
|
||||
VERIFY_IS_EQUAL(forward_output_both_parts.dimension(0), input.dimension(0));
|
||||
VERIFY_IS_EQUAL(reverse_output_both_parts.dimension(0), input.dimension(0));
|
||||
@ -178,21 +178,21 @@ static void test_fft_real_input_golden() {
|
||||
template <int DataLayout, typename RealScalar, bool isComplexInput, int FFTResultType, int FFTDirection, int TensorRank>
|
||||
static void test_fft_real_input_energy() {
|
||||
|
||||
Eigen::DSizes<long, TensorRank> dimensions;
|
||||
int total_size = 1;
|
||||
Eigen::DSizes<ptrdiff_t, TensorRank> dimensions;
|
||||
ptrdiff_t total_size = 1;
|
||||
for (int i = 0; i < TensorRank; ++i) {
|
||||
dimensions[i] = rand() % 20 + 1;
|
||||
total_size *= dimensions[i];
|
||||
}
|
||||
const DSizes<long, TensorRank> arr = dimensions;
|
||||
const DSizes<ptrdiff_t, TensorRank> arr = dimensions;
|
||||
|
||||
typedef typename internal::conditional<isComplexInput == true, std::complex<RealScalar>, RealScalar>::type InputScalar;
|
||||
|
||||
Tensor<InputScalar, TensorRank, DataLayout, long> input;
|
||||
Tensor<InputScalar, TensorRank, DataLayout> input;
|
||||
input.resize(arr);
|
||||
input.setRandom();
|
||||
|
||||
array<int, TensorRank> fft;
|
||||
array<ptrdiff_t, TensorRank> fft;
|
||||
for (int i = 0; i < TensorRank; ++i) {
|
||||
fft[i] = i;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user