Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FIX] Fixes aligned allocator issue for non posix implementation of aligned_alloc. #1362

Merged
merged 4 commits into from
Dec 5, 2019

Conversation

rrahn
Copy link
Contributor

@rrahn rrahn commented Nov 7, 2019

  • Uses operator new and delete instead of aligned_alloc.

@rrahn rrahn requested a review from marehr November 7, 2019 13:40
@codecov
Copy link

codecov bot commented Nov 7, 2019

Codecov Report

Merging #1362 into master will increase coverage by 0.03%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1362      +/-   ##
==========================================
+ Coverage   97.51%   97.55%   +0.03%     
==========================================
  Files         224      226       +2     
  Lines        8731     8781      +50     
==========================================
+ Hits         8514     8566      +52     
+ Misses        217      215       -2
Impacted Files Coverage Δ
...clude/seqan3/range/container/aligned_allocator.hpp 100% <100%> (+18.18%) ⬆️
include/seqan3/alphabet/aminoacid/aa10li.hpp 100% <0%> (ø) ⬆️
include/seqan3/alphabet/mask/masked.hpp 100% <0%> (ø) ⬆️
.../seqan3/alphabet/composite/alphabet_tuple_base.hpp 100% <0%> (ø) ⬆️
include/seqan3/alphabet/concept.hpp 100% <0%> (ø) ⬆️
...ude/seqan3/alphabet/composite/alphabet_variant.hpp 100% <0%> (ø) ⬆️
...nclude/seqan3/alphabet/structure/structured_aa.hpp 77.77% <0%> (ø) ⬆️
...clude/seqan3/alphabet/aminoacid/aminoacid_base.hpp 100% <0%> (ø) ⬆️
.../pairwise/execution/alignment_executor_two_way.hpp 98.33% <0%> (ø) ⬆️
include/seqan3/alphabet/cigar/cigar.hpp 90.47% <0%> (ø) ⬆️
... and 16 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 1fa069f...e444f99. Read the comment docs.

@rrahn rrahn force-pushed the fix/allocator_bug branch 2 times, most recently from 79ed7ce to 1dd9b31 Compare November 8, 2019 09:23
*/
template <typename new_value_type>
struct rebind
{
//!\brief The alignment for the rebound allocator.
static constexpr size_t other_alignment = (alignof(new_value_type) > alignment)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

std::max ?

Copy link
Member

@marehr marehr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some questions and some suggestion and some love

@@ -80,6 +80,68 @@ TEST(aligned_allocator, memory_alignment)
alloc.deallocate(begin, size);
}

TEST(aligned_allocator, memory_alignment_new_extended)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does new_extended mean?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is language from the c++ draft. It means that it's alignment is bigger than the value of __STDCPP_DEFAULT_NEW_ALIGNMENT__

alignas(64) std::array<int32_t, 2> data{};
};

TEST(aligned_allocator, memory_alignment_new_extended_default)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does new_extended_default mean?

EXPECT_EQ(memory_alignment(begin, alignment), 0u);
EXPECT_EQ(memory_alignment(end, alignment), 0u);

EXPECT_EQ(memory_alignment(begin + 1, alignment), 0u);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is it always 0? I don't want to think :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because it does not use a larger alignment than the alignment of the type that is allocated for (which is 64 bytes). So every value starts at 64 byte boundary. Also that's why I called this test default to show the behavior of a new extended type where we use the default alignment of the type and not a larger one.

* This class allocates memory at the given alignment boundary. If the specified `alignment` is not supported by the
* used allocation method a std::bad_alloc exception will be thrown. For requested alignments larger than
* `__STDCPP_DEFAULT_NEW_ALIGNMENT__` the storage will have the alignment specified by the value `alignment`.
* Otherwise, the storage is aligned for any object that does not have new-extended alignment and is of the requested
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is new-extended? Can you link it to some cppreference page?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And is the other one not of the requested size?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you give some examples which "objects" might be effected by the else case?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

like everything up to __STDCPP_DEFAULT_NEW_ALIGNMENT__ bytes. IIRC that is 16 byte. But I look into this and extend the example with some comments. I guess it shows this already.

include/seqan3/range/container/aligned_allocator.hpp Outdated Show resolved Hide resolved
* [__STDCPP_DEFAULT_NEW_ALIGNMENT__](https://en.cppreference.com/w/cpp/memory/new/align_val_t) the alignment
* aware operator new that takes as second argument the alignment as std::align_val_t. The allocation methods
* used by the global operator new functions is unspecified, e.g. std::malloc or std::aligned_alloc. Accordingly,
* the requirements on the alignment and the size of allocated bytes is implementation defined.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this has any impact on the intended behaviour of this class?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand you question. Could you be more specific? I mean this is the same problem when to use std::aligned_alloc. Depending on how operator new is implemented and depending on the platform different things are possible. So for example it might still be a problem in the future, that on an architecture that uses posix mem_align arbitrary sizes of bytes to allocate can be used, while on others this might be restricted to sizes that are a multiple of the alignment. But that is implementation defined and beyond the scope of this class. It only makes sure that it calls aligned memory, where it uses whatever ::operator new(n) uses to align up to alignments of __STDCPP_DEFAULT_NEW_ALIGNMENT__ and beyond that aligns the memory depending on whatever ::operator new(n, alignment) uses.

Copy link
Member

@marehr marehr Nov 27, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: We call the new operator with the semantic requirements that the c++ standard specifies/demands, but be aware that users can overload any (global) ::operator new that might not adhere to the standard and might cause std::bad_alloc or unaligned pointers.

…ligned_alloc.

* Uses operator new and delete instead.
Copy link
Member

@marehr marehr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! One thing left.

@@ -28,6 +28,12 @@ namespace seqan3
*
* \details
*
* This class allocates memory at the given alignment boundary. If the specified `alignment` is not supported by the
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you always use the term memory-alignment instead of just alignment like in the documentation below? It helps to know up front that this has nothing to do with our pairwise alignment

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will add a section about what memory alignment is.

* used allocation method a std::bad_alloc exception will be thrown. For requested alignments larger than
* `__STDCPP_DEFAULT_NEW_ALIGNMENT__`, also called new-extended alignments, the storage will have the alignment
* specified by the value `alignment`. Otherwise, the storage is aligned for any object that does not have new-extended
* alignment, e.g. int or double, and is of the requested size.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From this text, I do not understand what a memory alignment is.
If you think this is common knowledge, can you give just me an explanation? If not, one or few sentences would be great since this is a public interface.

Side note: I see that the number is always a multiple of the word size. Is this required and if so do you static_assert this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Side note: I see that the number is always a multiple of the word size. Is this required and if so do you static_assert this?

I am not sure I understand what do you mean?

* [operator new](https://en.cppreference.com/w/cpp/memory/new/operator_new).
* If the given `alignment` is bigger than
* [__STDCPP_DEFAULT_NEW_ALIGNMENT__](https://en.cppreference.com/w/cpp/memory/new/align_val_t) the alignment
* aware operator new that takes as second argument the alignment as std::align_val_t.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this sentence is mal formatted... at least I cannot make sense of it

* \details
*
* The argument n must be equal to the first argument of the call to allocate() that originally produced p;
* otherwise, the behavior is undefined.
* The argument `n` must be equal to the first argument of the call to seqan3::aligned_allocator::allocate that
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems error prone? Can't we cache n and remove the parameter from this function?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is defined and documented according to the allocator interface requirements: https://en.cppreference.com/w/cpp/named_req/Allocator, and I am afraid we need to keep this interface.

@@ -47,6 +48,12 @@ TEST(aligned_allocator, conversion_constructor)
[[maybe_unused]] aligned_allocator<float, 16> float_alloc{int_alloc};
}

TEST(aligned_allocator, request_to_much_memory)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
TEST(aligned_allocator, request_to_much_memory)
TEST(aligned_allocator, request_too_much_memory)

💅

@rrahn rrahn requested a review from smehringer December 3, 2019 15:06
@smehringer smehringer merged commit cfcc96e into seqan:master Dec 5, 2019
mr-c pushed a commit to mr-c/seqan3 that referenced this pull request Dec 9, 2019
…ligned_alloc. (seqan#1362)

* [FIX] Fixes aligned allocator issue for non posix implementation of aligned_alloc.

* Uses operator new and delete instead.
@rrahn rrahn deleted the fix/allocator_bug branch January 16, 2020 14:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants