-
Notifications
You must be signed in to change notification settings - Fork 174
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
[FEA]: Allow default initialization for thrust vectors #1992
Comments
The implementation takes about 32 lines. |
I think this would be a violation of principle of least surprise to have some types get value initialized and some types get default initialized. You are correct that there is a need for the functionality you describe, but it should be a different type. Design and implementation of such a type is underway. See #1502 |
I kind of disagree. I imagine the use of this facility like this. Old behavior: thrust::device_vector<T> v(100); // first write
// full guarantees are given here
thrust::fill(v.begin(). v.end(), 42);// second write (overwrites)
// full guarantees are given here
v.resize(10000); // ordinary value initialization
// full guarantees are given here New behavior: thrust::device_vector<T> v(100, thrust::i_know_what_I_am_doing::default_init); // just default init
// partial guarantees are given here, no reading of primitive types allowed
thrust::fill(v.begin(). v.end(), 42);// first write
// full guarantees are given here
v.resize(10000); // ordinary value initialization
// full guarantees are given here This behavior is btw. consistent with This behavior is not equivalent to raw allocation using I further considered whether initialization should be a property of the allocator, but this will lead exactly to the problem you described. Suddenly a vector behaves totally different on all of it's operations.
I also disagree. I don't want to have yet another vector type that only differs in the kind of initialization performed during construction, but is otherwise identical to any other thrust vectors. There is no use to make this difference in the type system: void f(thrust::device_vector<T>& vec) { ... }
void f(thrust::default_initdevice_vector<T>& vec) { ... } In both functions, I want AFAIU, the memory resources tracked in #1502 offer faciliities for uninitialized (and potentially untyped) memory, which is a different story and not the intent of my feature request. |
All of those are distinct types from Therefore, this tells me the precedence is to create a new type distinct from |
I am with @jrhemstad here. All examples above are static arrays where they follow the classical C initialization rules. However, That said, we are currently in the process of working on |
To add another example, |
This is quite dangerous to the inexperienced programmer, since you cannot, generically speaking, assign to elements of such a vector, but have to construct them first. I think that a tag to default initialize is the far safer option here, since it still omits initialization for primitive data types, but runs constructors when they exist. |
I believe the important issue is that you want to be able to completely avoid launching any operation to initialize a memory range that you will be overwriting soon. In my world those types where default initialization is actually a win are those types where assignment is also trivial, so the "danger" is not materialized |
We had a big discussion about this matter today and here is my summary: We agreed on the following:
Alternatives: The proposed By contrast, Rapid's It was noted that if One person argued that the compile time of Another argued that having a dedicated type to Since we found use cases for both, default initialized and uninitialized memory, maybe both features are justified. If we provide a tag for Further design alternatives discussed:
|
I was recently reminded about this by a WG21 reflector discussion, pointing to this paper https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p1072r10.html#tag, concluding that "LEWG should explore tags for allocator-aware containers". It also lists Boost as setting precedence for such a non-standard extension. Interestingly, it also lists |
Is this a duplicate?
Area
Thrust
Is your feature request related to a problem? Please describe.
Thrust vectors perform value-initialization, like
std::vector
. That is, non-trivially constructible class types will have their constuctors run and all primitive types are zero-initialized. This pessimizes use cases where we want to create vectors which are inteded to be overwritten entirely before any read occurs. While smart compilers can optimize unnecessary initialization away forstd::vector
, this is much more difficult for e.g.thrust::device_vector
, since it's constructor has to allocate device memory and run a kernel for initialization.Describe the solution you'd like
I would like to have a constructor overload on all thrust vector's that performs default initialization. That is, non-trivially constructible class types will have their constuctors run but all primitive data types are left uninitialized. Since thrust vectors are often used with primitive types, there is great potential to save unnecessary kernel runs and discarded writes for vectors used to provide storage for outputs from thrust algorithms.
Note that I am not proposing to skip initialization. Default constructed elements contained in thrust vector do have their lifetimes begun and assigning/writing to them is defined behavior. Only reading from default initialized and only primitive elements is undefined behavior (before C++26) / erroneous behavior (since C++26) though, so this facility requires certain care.
Describe alternatives you've considered
Calling raw
cudaMalloc
and wrapping the result in aunique_ptr
.Additional context
No response
The text was updated successfully, but these errors were encountered: