Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Parborg <darkdefende@gmail.com>2020-10-19 14:03:06 +0300
committerSebastian Parborg <darkdefende@gmail.com>2020-10-19 14:06:38 +0300
commite3c76f793724cd7e0ade4dc610b104fb9996901c (patch)
tree67127d96b203b4a94e60133d7033e1469118ab6b /intern/libmv
parentb17ad27adcc016f75329c73849468a4585804fcf (diff)
Fix libmv eigen alignment issues when compiling with AVX support
There would be eigen alignment issues with the custom libmv vector class when compiling with AVX optimizations. This would lead to segfaults. Simply use the std::vector base class as suggested by the old TODO in the class header. Reviewed By: Sergey Differential Revision: http://developer.blender.org/D8968
Diffstat (limited to 'intern/libmv')
-rw-r--r--intern/libmv/libmv/base/vector.h145
-rw-r--r--intern/libmv/libmv/base/vector_test.cc17
2 files changed, 11 insertions, 151 deletions
diff --git a/intern/libmv/libmv/base/vector.h b/intern/libmv/libmv/base/vector.h
index bdc4392155c..300291c5679 100644
--- a/intern/libmv/libmv/base/vector.h
+++ b/intern/libmv/libmv/base/vector.h
@@ -25,151 +25,18 @@
#ifndef LIBMV_BASE_VECTOR_H
#define LIBMV_BASE_VECTOR_H
-#include <cstring>
-#include <new>
+#include <vector>
#include <Eigen/Core>
namespace libmv {
-// A simple container class, which guarantees 16 byte alignment needed for most
-// vectorization. Don't use this container for classes that cannot be copied
-// via memcpy.
-// FIXME: this class has some issues:
-// - doesn't support iterators.
-// - impede compatibility with code using STL.
-// - the STL already provide support for custom allocators
-// it could be replaced with a simple
-// template <T> class vector : std::vector<T, aligned_allocator> {} declaration
-// provided it doesn't break code relying on libmv::vector specific behavior
-template <typename T,
- typename Allocator = Eigen::aligned_allocator<T> >
-class vector {
- public:
- ~vector() { clear(); }
+// A simple container class, which guarantees the correct memory alignment
+// needed for most eigen vectorization. Don't use this container for classes
+// that cannot be copied via memcpy.
- vector() { init(); }
- vector(int size) { init(); resize(size); }
- vector(int size, const T & val) {
- init();
- resize(size);
- std::fill(data_, data_+size_, val); }
-
- // Copy constructor and assignment.
- vector(const vector<T, Allocator> &rhs) {
- init();
- copy(rhs);
- }
- vector<T, Allocator> &operator=(const vector<T, Allocator> &rhs) {
- if (&rhs != this) {
- copy(rhs);
- }
- return *this;
- }
-
- /// Swaps the contents of two vectors in constant time.
- void swap(vector<T, Allocator> &other) {
- std::swap(allocator_, other.allocator_);
- std::swap(size_, other.size_);
- std::swap(capacity_, other.capacity_);
- std::swap(data_, other.data_);
- }
-
- T *data() const { return data_; }
- int size() const { return size_; }
- int capacity() const { return capacity_; }
- const T& back() const { return data_[size_ - 1]; }
- T& back() { return data_[size_ - 1]; }
- const T& front() const { return data_[0]; }
- T& front() { return data_[0]; }
- const T& operator[](int n) const { return data_[n]; }
- T& operator[](int n) { return data_[n]; }
- const T& at(int n) const { return data_[n]; }
- T& at(int n) { return data_[n]; }
- const T * begin() const { return data_; }
- const T * end() const { return data_+size_; }
- T * begin() { return data_; }
- T * end() { return data_+size_; }
-
- void resize(size_t size) {
- reserve(size);
- if (size > size_) {
- construct(size_, size);
- } else if (size < size_) {
- destruct(size, size_);
- }
- size_ = size;
- }
-
- void push_back(const T &value) {
- if (size_ == capacity_) {
- reserve(size_ ? 2 * size_ : 1);
- }
- new (&data_[size_++]) T(value);
- }
-
- void pop_back() {
- resize(size_ - 1);
- }
-
- void clear() {
- destruct(0, size_);
- deallocate();
- init();
- }
-
- void reserve(unsigned int size) {
- if (size > size_) {
- T *data = static_cast<T *>(allocate(size));
- memcpy(static_cast<void *>(data), data_, sizeof(*data)*size_);
- allocator_.deallocate(data_, capacity_);
- data_ = data;
- capacity_ = size;
- }
- }
-
- bool empty() {
- return size_ == 0;
- }
-
- private:
- void construct(int start, int end) {
- for (int i = start; i < end; ++i) {
- new (&data_[i]) T;
- }
- }
- void destruct(int start, int end) {
- for (int i = start; i < end; ++i) {
- data_[i].~T();
- }
- }
- void init() {
- size_ = 0;
- data_ = 0;
- capacity_ = 0;
- }
-
- void *allocate(int size) {
- return size ? allocator_.allocate(size) : 0;
- }
-
- void deallocate() {
- allocator_.deallocate(data_, size_);
- data_ = 0;
- }
-
- void copy(const vector<T, Allocator> &rhs) {
- resize(rhs.size());
- for (int i = 0; i < rhs.size(); ++i) {
- (*this)[i] = rhs[i];
- }
- }
-
- Allocator allocator_;
- size_t size_;
- size_t capacity_;
- T *data_;
-};
+template <class ElementType>
+using vector = std::vector<ElementType, Eigen::aligned_allocator<ElementType>>;
} // namespace libmv
diff --git a/intern/libmv/libmv/base/vector_test.cc b/intern/libmv/libmv/base/vector_test.cc
index f17718c3926..44b9a152148 100644
--- a/intern/libmv/libmv/base/vector_test.cc
+++ b/intern/libmv/libmv/base/vector_test.cc
@@ -115,31 +115,24 @@ TEST_F(VectorTest, ResizeConstructsAndDestructsAsExpected) {
// Create one object.
v.resize(1);
EXPECT_EQ(1, v.size());
- EXPECT_EQ(1, v.capacity());
EXPECT_EQ(1, foo_construct_calls);
- EXPECT_EQ(0, foo_destruct_calls);
EXPECT_EQ(5, v[0].value);
// Create two more.
v.resize(3);
EXPECT_EQ(3, v.size());
- EXPECT_EQ(3, v.capacity());
EXPECT_EQ(3, foo_construct_calls);
- EXPECT_EQ(0, foo_destruct_calls);
// Delete the last one.
v.resize(2);
EXPECT_EQ(2, v.size());
EXPECT_EQ(3, v.capacity());
EXPECT_EQ(3, foo_construct_calls);
- EXPECT_EQ(1, foo_destruct_calls);
// Delete the remaining two.
v.resize(0);
EXPECT_EQ(0, v.size());
- EXPECT_EQ(3, v.capacity());
EXPECT_EQ(3, foo_construct_calls);
- EXPECT_EQ(3, foo_destruct_calls);
}
TEST_F(VectorTest, PushPopBack) {
@@ -192,15 +185,15 @@ TEST_F(VectorTest, STLFind) {
a.push_back(5);
a.push_back(3);
- // Find return an int *
+ // Find returns an int *
EXPECT_EQ(std::find(&a[0], &a[2], 1) == &a[0], true);
EXPECT_EQ(std::find(&a[0], &a[2], 5) == &a[1], true);
EXPECT_EQ(std::find(&a[0], &a[2], 3) == &a[2], true);
- // Find return a const int *
- EXPECT_EQ(std::find(a.begin(), a.end(), 1) == &a[0], true);
- EXPECT_EQ(std::find(a.begin(), a.end(), 5) == &a[1], true);
- EXPECT_EQ(std::find(a.begin(), a.end(), 3) == &a[2], true);
+ // Find returns an interator
+ EXPECT_EQ(std::find(a.begin(), a.end(), 1) == std::next(a.begin(), 0), true);
+ EXPECT_EQ(std::find(a.begin(), a.end(), 5) == std::next(a.begin(), 1), true);
+ EXPECT_EQ(std::find(a.begin(), a.end(), 3) == std::next(a.begin(), 2), true);
// Search value that are not in the vector
EXPECT_EQ(std::find(a.begin(), a.end(), 0) == a.end(), true);