Update to 3.3.7

This commit is contained in:
Sandro Mani 2018-12-26 01:15:13 +01:00
parent 90bc55365b
commit 176ab5000f
8 changed files with 40 additions and 359 deletions

1
.gitignore vendored
View File

@ -23,3 +23,4 @@
/3.3.4.tar.bz2
/3.3.5.tar.bz2
/3.3.6.tar.bz2
/3.3.7.tar.bz2

View File

@ -1,80 +0,0 @@
From 35e60f607c83056e787237b469ae96c0fe27bcf7 Mon Sep 17 00:00:00 2001
From: Christoph Hertzberg <chtz@informatik.uni-bremen.de>
Date: Tue, 24 Jul 2018 21:59:15 +0200
Subject: [PATCH 04/24] fix warnings for doc-eigen-prerequisites
---
doc/snippets/MatrixBase_cwiseEqual.cpp | 2 +-
doc/snippets/MatrixBase_cwiseNotEqual.cpp | 2 +-
unsupported/Eigen/src/IterativeSolvers/DGMRES.h | 2 +-
unsupported/doc/examples/FFT.cpp | 6 +++---
4 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/doc/snippets/MatrixBase_cwiseEqual.cpp b/doc/snippets/MatrixBase_cwiseEqual.cpp
index eb3656f4c..469af642c 100644
--- a/doc/snippets/MatrixBase_cwiseEqual.cpp
+++ b/doc/snippets/MatrixBase_cwiseEqual.cpp
@@ -3,5 +3,5 @@ m << 1, 0,
1, 1;
cout << "Comparing m with identity matrix:" << endl;
cout << m.cwiseEqual(MatrixXi::Identity(2,2)) << endl;
-int count = m.cwiseEqual(MatrixXi::Identity(2,2)).count();
+Index count = m.cwiseEqual(MatrixXi::Identity(2,2)).count();
cout << "Number of coefficients that are equal: " << count << endl;
diff --git a/doc/snippets/MatrixBase_cwiseNotEqual.cpp b/doc/snippets/MatrixBase_cwiseNotEqual.cpp
index 6a2e4fb6c..7f0a105d6 100644
--- a/doc/snippets/MatrixBase_cwiseNotEqual.cpp
+++ b/doc/snippets/MatrixBase_cwiseNotEqual.cpp
@@ -3,5 +3,5 @@ m << 1, 0,
1, 1;
cout << "Comparing m with identity matrix:" << endl;
cout << m.cwiseNotEqual(MatrixXi::Identity(2,2)) << endl;
-int count = m.cwiseNotEqual(MatrixXi::Identity(2,2)).count();
+Index count = m.cwiseNotEqual(MatrixXi::Identity(2,2)).count();
cout << "Number of coefficients that are not equal: " << count << endl;
diff --git a/unsupported/Eigen/src/IterativeSolvers/DGMRES.h b/unsupported/Eigen/src/IterativeSolvers/DGMRES.h
index eff2dc8ad..eae717aa2 100644
--- a/unsupported/Eigen/src/IterativeSolvers/DGMRES.h
+++ b/unsupported/Eigen/src/IterativeSolvers/DGMRES.h
@@ -173,7 +173,7 @@ class DGMRES : public IterativeSolverBase<DGMRES<_MatrixType,_Preconditioner> >
/**
* Set the restart value (default is 30)
*/
- Index set_restart(const Index restart) { m_restart=restart; }
+ void set_restart(const Index restart) { m_restart=restart; }
/**
* Set the number of eigenvalues to deflate at each restart
diff --git a/unsupported/doc/examples/FFT.cpp b/unsupported/doc/examples/FFT.cpp
index fcbf81276..85e8a0241 100644
--- a/unsupported/doc/examples/FFT.cpp
+++ b/unsupported/doc/examples/FFT.cpp
@@ -61,14 +61,14 @@ template <typename T>
void RandomFill(std::vector<T> & vec)
{
for (size_t k=0;k<vec.size();++k)
- vec[k] = T( rand() )/T(RAND_MAX) - .5;
+ vec[k] = T( rand() )/T(RAND_MAX) - T(.5);
}
template <typename T>
void RandomFill(std::vector<std::complex<T> > & vec)
{
for (size_t k=0;k<vec.size();++k)
- vec[k] = std::complex<T> ( T( rand() )/T(RAND_MAX) - .5, T( rand() )/T(RAND_MAX) - .5);
+ vec[k] = std::complex<T> ( T( rand() )/T(RAND_MAX) - T(.5), T( rand() )/T(RAND_MAX) - T(.5));
}
template <typename T_time,typename T_freq>
@@ -85,7 +85,7 @@ void fwd_inv(size_t nfft)
vector<T_time> timebuf2;
fft.inv(timebuf2,freqbuf);
- long double rmse = mag2(timebuf - timebuf2) / mag2(timebuf);
+ T_time rmse = mag2(timebuf - timebuf2) / mag2(timebuf);
cout << "roundtrip rmse: " << rmse << endl;
}
--
2.17.1

View File

@ -1,7 +1,7 @@
diff -rupN eigen-eigen-07105f7124f9/CMakeLists.txt eigen-eigen-07105f7124f9-new/CMakeLists.txt
--- eigen-eigen-07105f7124f9/CMakeLists.txt 2016-02-16 14:26:15.000000000 +0100
+++ eigen-eigen-07105f7124f9-new/CMakeLists.txt 2016-02-17 09:44:43.556543936 +0100
@@ -324,6 +324,11 @@ install(FILES
diff -rupN eigen-eigen-323c052e1731/CMakeLists.txt eigen-eigen-323c052e1731-new/CMakeLists.txt
--- eigen-eigen-323c052e1731/CMakeLists.txt 2018-12-11 18:57:55.000000000 +0100
+++ eigen-eigen-323c052e1731-new/CMakeLists.txt 2018-12-25 23:10:48.527420853 +0100
@@ -424,6 +424,11 @@ install(FILES
DESTINATION ${INCLUDE_INSTALL_DIR} COMPONENT Devel
)

View File

@ -1,7 +1,7 @@
diff -up ./CMakeLists.txt.fixcmake ./CMakeLists.txt
--- ./CMakeLists.txt.fixcmake 2016-12-28 11:39:51.690853423 -0500
+++ ./CMakeLists.txt 2016-12-28 11:41:06.409811065 -0500
@@ -511,7 +511,7 @@ set ( EIGEN_VERSION_MAJOR ${EIGEN_WORLD
diff -rupN eigen-eigen-323c052e1731/CMakeLists.txt eigen-eigen-323c052e1731-new/CMakeLists.txt
--- eigen-eigen-323c052e1731/CMakeLists.txt 2018-12-25 23:10:48.592420583 +0100
+++ eigen-eigen-323c052e1731-new/CMakeLists.txt 2018-12-25 23:10:48.659420305 +0100
@@ -531,7 +531,7 @@ set ( EIGEN_VERSION_MAJOR ${EIGEN_WORLD
set ( EIGEN_VERSION_MINOR ${EIGEN_MAJOR_VERSION} )
set ( EIGEN_VERSION_PATCH ${EIGEN_MINOR_VERSION} )
set ( EIGEN_DEFINITIONS "")

View File

@ -1,245 +0,0 @@
# HG changeset patch
# User Gael Guennebaud <g.gael@free.fr>
# Date 1497514590 -7200
# Node ID d781c1de98342c5ca29c2fe719d8d3c96a35dcd4
# Parent 48cd83b2b459aa9f3f5dca135d38760fe0b02a2f
Bug 1436: fix compilation of Jacobi rotations with ARM NEON, some specializations of internal::conj_helper were missing.
diff --git a/Eigen/Core b/Eigen/Core
--- a/Eigen/Core
+++ b/Eigen/Core
@@ -371,6 +371,7 @@
#include "src/Core/MathFunctions.h"
#include "src/Core/GenericPacketMath.h"
#include "src/Core/MathFunctionsImpl.h"
+#include "src/Core/arch/Default/ConjHelper.h"
#if defined EIGEN_VECTORIZE_AVX512
#include "src/Core/arch/SSE/PacketMath.h"
diff --git a/Eigen/src/Core/arch/AVX/Complex.h b/Eigen/src/Core/arch/AVX/Complex.h
--- a/Eigen/src/Core/arch/AVX/Complex.h
+++ b/Eigen/src/Core/arch/AVX/Complex.h
@@ -204,23 +204,7 @@
}
};
-template<> struct conj_helper<Packet8f, Packet4cf, false,false>
-{
- EIGEN_STRONG_INLINE Packet4cf pmadd(const Packet8f& x, const Packet4cf& y, const Packet4cf& c) const
- { return padd(c, pmul(x,y)); }
-
- EIGEN_STRONG_INLINE Packet4cf pmul(const Packet8f& x, const Packet4cf& y) const
- { return Packet4cf(Eigen::internal::pmul(x, y.v)); }
-};
-
-template<> struct conj_helper<Packet4cf, Packet8f, false,false>
-{
- EIGEN_STRONG_INLINE Packet4cf pmadd(const Packet4cf& x, const Packet8f& y, const Packet4cf& c) const
- { return padd(c, pmul(x,y)); }
-
- EIGEN_STRONG_INLINE Packet4cf pmul(const Packet4cf& x, const Packet8f& y) const
- { return Packet4cf(Eigen::internal::pmul(x.v, y)); }
-};
+EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet4cf,Packet8f)
template<> EIGEN_STRONG_INLINE Packet4cf pdiv<Packet4cf>(const Packet4cf& a, const Packet4cf& b)
{
@@ -400,23 +384,7 @@
}
};
-template<> struct conj_helper<Packet4d, Packet2cd, false,false>
-{
- EIGEN_STRONG_INLINE Packet2cd pmadd(const Packet4d& x, const Packet2cd& y, const Packet2cd& c) const
- { return padd(c, pmul(x,y)); }
-
- EIGEN_STRONG_INLINE Packet2cd pmul(const Packet4d& x, const Packet2cd& y) const
- { return Packet2cd(Eigen::internal::pmul(x, y.v)); }
-};
-
-template<> struct conj_helper<Packet2cd, Packet4d, false,false>
-{
- EIGEN_STRONG_INLINE Packet2cd pmadd(const Packet2cd& x, const Packet4d& y, const Packet2cd& c) const
- { return padd(c, pmul(x,y)); }
-
- EIGEN_STRONG_INLINE Packet2cd pmul(const Packet2cd& x, const Packet4d& y) const
- { return Packet2cd(Eigen::internal::pmul(x.v, y)); }
-};
+EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet2cd,Packet4d)
template<> EIGEN_STRONG_INLINE Packet2cd pdiv<Packet2cd>(const Packet2cd& a, const Packet2cd& b)
{
diff --git a/Eigen/src/Core/arch/AltiVec/Complex.h b/Eigen/src/Core/arch/AltiVec/Complex.h
--- a/Eigen/src/Core/arch/AltiVec/Complex.h
+++ b/Eigen/src/Core/arch/AltiVec/Complex.h
@@ -224,23 +224,7 @@
}
};
-template<> struct conj_helper<Packet4f, Packet2cf, false,false>
-{
- EIGEN_STRONG_INLINE Packet2cf pmadd(const Packet4f& x, const Packet2cf& y, const Packet2cf& c) const
- { return padd(c, pmul(x,y)); }
-
- EIGEN_STRONG_INLINE Packet2cf pmul(const Packet4f& x, const Packet2cf& y) const
- { return Packet2cf(internal::pmul<Packet4f>(x, y.v)); }
-};
-
-template<> struct conj_helper<Packet2cf, Packet4f, false,false>
-{
- EIGEN_STRONG_INLINE Packet2cf pmadd(const Packet2cf& x, const Packet4f& y, const Packet2cf& c) const
- { return padd(c, pmul(x,y)); }
-
- EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& x, const Packet4f& y) const
- { return Packet2cf(internal::pmul<Packet4f>(x.v, y)); }
-};
+EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet2cf,Packet4f)
template<> EIGEN_STRONG_INLINE Packet2cf pdiv<Packet2cf>(const Packet2cf& a, const Packet2cf& b)
{
@@ -416,23 +400,8 @@
return pconj(internal::pmul(a, b));
}
};
-template<> struct conj_helper<Packet2d, Packet1cd, false,false>
-{
- EIGEN_STRONG_INLINE Packet1cd pmadd(const Packet2d& x, const Packet1cd& y, const Packet1cd& c) const
- { return padd(c, pmul(x,y)); }
- EIGEN_STRONG_INLINE Packet1cd pmul(const Packet2d& x, const Packet1cd& y) const
- { return Packet1cd(internal::pmul<Packet2d>(x, y.v)); }
-};
-
-template<> struct conj_helper<Packet1cd, Packet2d, false,false>
-{
- EIGEN_STRONG_INLINE Packet1cd pmadd(const Packet1cd& x, const Packet2d& y, const Packet1cd& c) const
- { return padd(c, pmul(x,y)); }
-
- EIGEN_STRONG_INLINE Packet1cd pmul(const Packet1cd& x, const Packet2d& y) const
- { return Packet1cd(internal::pmul<Packet2d>(x.v, y)); }
-};
+EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet1cd,Packet2d)
template<> EIGEN_STRONG_INLINE Packet1cd pdiv<Packet1cd>(const Packet1cd& a, const Packet1cd& b)
{
diff --git a/Eigen/src/Core/arch/Default/ConjHelper.h b/Eigen/src/Core/arch/Default/ConjHelper.h
new file mode 100644
--- /dev/null
+++ b/Eigen/src/Core/arch/Default/ConjHelper.h
@@ -0,0 +1,29 @@
+
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2017 Gael Guennebaud <gael.guennebaud@inria.fr>
+//
+// 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/.
+
+#ifndef EIGEN_ARCH_CONJ_HELPER_H
+#define EIGEN_ARCH_CONJ_HELPER_H
+
+#define EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(PACKET_CPLX, PACKET_REAL) \
+ template<> struct conj_helper<PACKET_REAL, PACKET_CPLX, false,false> { \
+ EIGEN_STRONG_INLINE PACKET_CPLX pmadd(const PACKET_REAL& x, const PACKET_CPLX& y, const PACKET_CPLX& c) const \
+ { return padd(c, pmul(x,y)); } \
+ EIGEN_STRONG_INLINE PACKET_CPLX pmul(const PACKET_REAL& x, const PACKET_CPLX& y) const \
+ { return PACKET_CPLX(Eigen::internal::pmul<PACKET_REAL>(x, y.v)); } \
+ }; \
+ \
+ template<> struct conj_helper<PACKET_CPLX, PACKET_REAL, false,false> { \
+ EIGEN_STRONG_INLINE PACKET_CPLX pmadd(const PACKET_CPLX& x, const PACKET_REAL& y, const PACKET_CPLX& c) const \
+ { return padd(c, pmul(x,y)); } \
+ EIGEN_STRONG_INLINE PACKET_CPLX pmul(const PACKET_CPLX& x, const PACKET_REAL& y) const \
+ { return PACKET_CPLX(Eigen::internal::pmul<PACKET_REAL>(x.v, y)); } \
+ };
+
+#endif // EIGEN_ARCH_CONJ_HELPER_H
diff --git a/Eigen/src/Core/arch/NEON/Complex.h b/Eigen/src/Core/arch/NEON/Complex.h
--- a/Eigen/src/Core/arch/NEON/Complex.h
+++ b/Eigen/src/Core/arch/NEON/Complex.h
@@ -265,6 +265,8 @@
}
};
+EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet2cf,Packet4f)
+
template<> EIGEN_STRONG_INLINE Packet2cf pdiv<Packet2cf>(const Packet2cf& a, const Packet2cf& b)
{
// TODO optimize it for NEON
@@ -456,6 +458,8 @@
}
};
+EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet1cd,Packet2d)
+
template<> EIGEN_STRONG_INLINE Packet1cd pdiv<Packet1cd>(const Packet1cd& a, const Packet1cd& b)
{
// TODO optimize it for NEON
diff --git a/Eigen/src/Core/arch/SSE/Complex.h b/Eigen/src/Core/arch/SSE/Complex.h
--- a/Eigen/src/Core/arch/SSE/Complex.h
+++ b/Eigen/src/Core/arch/SSE/Complex.h
@@ -229,23 +229,7 @@
}
};
-template<> struct conj_helper<Packet4f, Packet2cf, false,false>
-{
- EIGEN_STRONG_INLINE Packet2cf pmadd(const Packet4f& x, const Packet2cf& y, const Packet2cf& c) const
- { return padd(c, pmul(x,y)); }
-
- EIGEN_STRONG_INLINE Packet2cf pmul(const Packet4f& x, const Packet2cf& y) const
- { return Packet2cf(Eigen::internal::pmul<Packet4f>(x, y.v)); }
-};
-
-template<> struct conj_helper<Packet2cf, Packet4f, false,false>
-{
- EIGEN_STRONG_INLINE Packet2cf pmadd(const Packet2cf& x, const Packet4f& y, const Packet2cf& c) const
- { return padd(c, pmul(x,y)); }
-
- EIGEN_STRONG_INLINE Packet2cf pmul(const Packet2cf& x, const Packet4f& y) const
- { return Packet2cf(Eigen::internal::pmul<Packet4f>(x.v, y)); }
-};
+EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet2cf,Packet4f)
template<> EIGEN_STRONG_INLINE Packet2cf pdiv<Packet2cf>(const Packet2cf& a, const Packet2cf& b)
{
@@ -430,23 +414,7 @@
}
};
-template<> struct conj_helper<Packet2d, Packet1cd, false,false>
-{
- EIGEN_STRONG_INLINE Packet1cd pmadd(const Packet2d& x, const Packet1cd& y, const Packet1cd& c) const
- { return padd(c, pmul(x,y)); }
-
- EIGEN_STRONG_INLINE Packet1cd pmul(const Packet2d& x, const Packet1cd& y) const
- { return Packet1cd(Eigen::internal::pmul<Packet2d>(x, y.v)); }
-};
-
-template<> struct conj_helper<Packet1cd, Packet2d, false,false>
-{
- EIGEN_STRONG_INLINE Packet1cd pmadd(const Packet1cd& x, const Packet2d& y, const Packet1cd& c) const
- { return padd(c, pmul(x,y)); }
-
- EIGEN_STRONG_INLINE Packet1cd pmul(const Packet1cd& x, const Packet2d& y) const
- { return Packet1cd(Eigen::internal::pmul<Packet2d>(x.v, y)); }
-};
+EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet1cd,Packet2d)
template<> EIGEN_STRONG_INLINE Packet1cd pdiv<Packet1cd>(const Packet1cd& a, const Packet1cd& b)
{
diff --git a/Eigen/src/Core/arch/ZVector/Complex.h b/Eigen/src/Core/arch/ZVector/Complex.h
--- a/Eigen/src/Core/arch/ZVector/Complex.h
+++ b/Eigen/src/Core/arch/ZVector/Complex.h
@@ -336,6 +336,9 @@
}
};
+EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet2cf,Packet4f)
+EIGEN_MAKE_CONJ_HELPER_CPLX_REAL(Packet1cd,Packet2d)
+
template<> EIGEN_STRONG_INLINE Packet1cd pdiv<Packet1cd>(const Packet1cd& a, const Packet1cd& b)
{
// TODO optimize it for AltiVec

View File

@ -4,10 +4,10 @@
# debuginfo package for the empty main package.
%global debug_package %{nil}
%global commit b70bf4fad467
%global commit 323c052e1731
Name: eigen3
Version: 3.3.6
Version: 3.3.7
Release: 1%{?dist}
Summary: A lightweight C++ template library for vector and matrix math
@ -49,38 +49,34 @@ BuildRequires: tex(latex)
%description
%{summary}.
%package devel
Summary: A lightweight C++ template library for vector and matrix math
Group: Development/Libraries
BuildArch: noarch
Summary: A lightweight C++ template library for vector and matrix math
BuildArch: noarch
# -devel subpkg only atm, compat with other distros
Provides: %{name} = %{version}-%{release}
Provides: %{name} = %{version}-%{release}
# not *strictly* a -static pkg, but the results are the same
Provides: %{name}-static = %{version}-%{release}
Provides: %{name}-static = %{version}-%{release}
%description devel
%{summary}.
%package doc
Summary: Developer documentation for Eigen
Requires: %{name}-devel = %{version}-%{release}
BuildArch: noarch
Summary: Developer documentation for Eigen
Requires: %{name}-devel = %{version}-%{release}
BuildArch: noarch
%description doc
Developer documentation for Eigen.
%prep
%setup -q -n eigen-eigen-%{commit}
%patch0 -p1
%patch1 -p1
%patch2 -p0 -b .fixcmake
%autosetup -p1 -n eigen-eigen-%{commit}
%build
mkdir %{_target_platform}
pushd %{_target_platform}
#%ifarch ppc64
# Currently get a compiler ICE, work around it
# https://bugzilla.redhat.com/show_bug.cgi?id=1063999
#export CXXFLAGS="%{optflags} -mno-vsx"
#%endif
%cmake .. -DINCLUDE_INSTALL_DIR=%{_includedir}/eigen3 \
-DBLAS_LIBRARIES="cblas" \
-DSUPERLU_INCLUDES=%{_includedir}/SuperLU \
@ -95,14 +91,17 @@ popd
rm -f %{_target_platform}/doc/html/installdox
rm -f %{_target_platform}/doc/html/unsupported/installdox
%install
%make_install -C %{_target_platform}
%check
# Run tests but make failures non-fatal. Note that upstream doesn't expect the
# tests to pass consistently since they're seeded randomly.
#make -C %{_target_platform} %{?_smp_mflags} buildtests
#make -C %{_target_platform} %{?_smp_mflags} test ARGS="-V" || exit 0
#make_build buildtests -C %{_target_platform}
#make_build test -C %{_target_platform} test ARGS="-V" || :
%files devel
%license COPYING.README COPYING.BSD COPYING.MPL2 COPYING.LGPL
@ -112,9 +111,15 @@ rm -f %{_target_platform}/doc/html/unsupported/installdox
%{_datadir}/cmake/Modules/*.cmake
%files doc
#doc %{_target_platform}/doc/html
%doc %{_target_platform}/doc/html
%changelog
* Tue Dec 25 2018 Sandro Mani <manisandro@gmail.com> - 3.3.7-1
- Update to 3.3.7
- Modernize spec
- Add doc
* Mon Dec 10 2018 Sandro Mani <manisandro@gmail.com> - 3.3.6-1
- Update to 3.3.6

View File

@ -1,6 +1,6 @@
diff -rupN eigen-eigen-07105f7124f9/eigen3.pc.in eigen-eigen-07105f7124f9-new/eigen3.pc.in
--- eigen-eigen-07105f7124f9/eigen3.pc.in 2016-02-16 14:26:15.000000000 +0100
+++ eigen-eigen-07105f7124f9-new/eigen3.pc.in 2016-02-20 19:13:19.816842461 +0100
diff -rupN eigen-eigen-323c052e1731/eigen3.pc.in eigen-eigen-323c052e1731-new/eigen3.pc.in
--- eigen-eigen-323c052e1731/eigen3.pc.in 2018-12-11 18:57:55.000000000 +0100
+++ eigen-eigen-323c052e1731-new/eigen3.pc.in 2018-12-25 23:10:48.594420575 +0100
@@ -6,4 +6,4 @@ Description: A C++ template library for
Requires:
Version: @EIGEN_VERSION_NUMBER@

View File

@ -1 +1 @@
SHA512 (3.3.6.tar.bz2) = 5fbd2ae1b9f0b4ee5ae691f011c80adffee9b6e360ac6fc41f54e630a613270d63ea51db121d3cc537f0b136b1cd985b04cb5063e8a4fbb8bf9bbe7d358f1f6b
SHA512 (3.3.7.tar.bz2) = c12bfd034d0a1112bf2df3f773ad98f36b2b53fbbfceac5f143ee1793322746fb8a6546d7db7da2a1000da6a535bd8cea0c4125b549afc90a6570743b02dcf3d