diff options
| author | Ellie Hermaszewska <ellieh@nvidia.com> | 2024-10-21 23:09:01 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-10-21 08:09:01 -0700 |
| commit | 20fa42e82dfa8398c9c818773fa40817883fb7ec (patch) | |
| tree | 8fcd52a0c33fe82c35267c80f328b770b3ca570a /source/slang/core.meta.slang | |
| parent | 0e8e8cb9750f3c6de183ae981097481950099e0c (diff) | |
Stdlib documentation for Atomic, Optional, Tuple (#5358)
Diffstat (limited to 'source/slang/core.meta.slang')
| -rw-r--r-- | source/slang/core.meta.slang | 106 |
1 files changed, 97 insertions, 9 deletions
diff --git a/source/slang/core.meta.slang b/source/slang/core.meta.slang index 8fae1f519..aea9cf4d6 100644 --- a/source/slang/core.meta.slang +++ b/source/slang/core.meta.slang @@ -1095,17 +1095,32 @@ struct ConstRef typealias __Addr<T> = Ptr<T, $( (uint64_t)AddressSpace::Generic)ULL>; //@public: + +/// `Optional<T>` is a type with one extra value than `T`, this extra value is +/// used to represent a "missing" or "invalid" `T`. This extra value is called +/// `none`. +/// +/// `none` can be compared against with the operators `==` or `!=`. +/// +/// An `Optional<T>` value can also be implicitly or explicitly constructed from +/// a value of type `T` +/// +/// `Optional<T>` values can be deconstructed with `if(let myT = myOptionalT) ...` +/// where this branch will only be taken if `myOptionalT` contains a value +/// of type `T` (to be put into scope as `myT`). __generic<T> __magic_type(OptionalType) __intrinsic_type($(kIROp_OptionalType)) struct Optional { + /// Return `true` iff this `Optional` contains a value of type `T` property bool hasValue { __intrinsic_op($(kIROp_OptionalHasValue)) get; } + /// If this `Optional` contains a value of type `T` return that. property T value { __intrinsic_op($(kIROp_GetOptionalValue)) @@ -1144,6 +1159,19 @@ bool operator!=(__none_t noneVal, Optional<T> val) } //@public: + +/// A variadic generic storing the product of several types. +/// +/// The member names of individual values are `_0`, `_1`, `_2`, ... +/// +/// New tuples can also be constructed by swizzling an existing tuple with the +/// concatenation of these names, for example `x._2_1_0` will return the first +/// three members of the tuple `x` in reverse order. +/// +/// When all tuple elements conform to `IComparable` tuples can themselves be +/// compared according to a lexicographic ordering. +/// +/// The number of elements in a tuple is given by the `countof` function. __generic<each T> __magic_type(TupleType) struct Tuple @@ -1152,9 +1180,11 @@ struct Tuple __init(expand each T); } +/// Construct a tuple from several values in order __intrinsic_op($(kIROp_MakeTuple)) Tuple<T> makeTuple<each T>(T v); +/// Return a tuple containing the values of both input tuples in order Tuple<T, U> concat<each T, each U>(Tuple<T> t, Tuple<U> u) { return makeTuple(expand each t, expand each u); @@ -3035,10 +3065,15 @@ void __requireComputeDerivative(); /// @category misc_types enum MemoryOrder { + /// No memory operation ordering constraints Relaxed = $(kIRMemoryOrder_Relaxed), + /// Ensures that all subsequent memory operations in the same thread are not reordered before it Acquire = $(kIRMemoryOrder_Acquire), + /// Ensures that all prior memory operations in the same thread are not reordered after it Release = $(kIRMemoryOrder_Release), + /// Combines both acquire and release semantics AcquireRelease = $(kIRMemoryOrder_AcquireRelease), + /// Provides the strongest ordering: total order exists between all SeqCst operations SeqCst = $(kIRMemoryOrder_SeqCst), } @@ -3062,20 +3097,45 @@ extension double : IArithmeticAtomicable {} extension float : IArithmeticAtomicable {} extension half : IArithmeticAtomicable {} +/// A wrapper for `IAtomicable` types to introduce atomic load and store +/// operations. Values of this type are to be stored in buffers or groupshared +/// memory. +/// +/// All operations take a `MemoryOrder` parameter which influenced the +/// semantics of the performed operation +/// +/// All operations take place at the device scope. +/// +/// Operators `+=`, `-=`, `&=`, `|=`, `^=`, `++`, `--` are overloaded to +/// operate on `Atomic<T>`. __magic_type(AtomicType) __intrinsic_type($(kIROp_AtomicType)) [require(cuda_glsl_hlsl_metal_spirv_wgsl)] struct Atomic<T : IAtomicable> { + /// Atomically load the stored `T` value __intrinsic_op($(kIROp_AtomicLoad)) [__ref] T load(MemoryOrder order = MemoryOrder.Relaxed); + /// Atomically store a new `T` value __intrinsic_op($(kIROp_AtomicStore)) [__ref] void store(T newValue, MemoryOrder order = MemoryOrder.Relaxed); + /// Atomically replace the stored `T` value with a new `T` value and return + /// replaced value __intrinsic_op($(kIROp_AtomicExchange)) [__ref] T exchange(T newValue, MemoryOrder order = MemoryOrder.Relaxed); // returns old value + /// Atomically replace and return the stored `T` value with a new `T` value + /// only if the stored value is equal to the specified comparison value. + /// + /// If the comparison value is equal to the stored value, then the + /// `successOrder` `MemoryOrder` is used, otherwise the `failOrder` + /// `MemoryOrder` is used. + /// + /// `successOrder` must be at least as strong as `failOrder` + /// + /// `failOrder` must not be `MemoryOrder.Release` or `MemoryOrder.AcquireRelease` __intrinsic_op($(kIROp_AtomicCompareExchange)) [__ref] T compareExchange( T compareValue, @@ -3084,30 +3144,58 @@ struct Atomic<T : IAtomicable> MemoryOrder failOrder = MemoryOrder.Relaxed); } -/// These addtional members are only available when `T` conforms to `IArithmeticAtomicable`. +/// These additional members are only available when `T` conforms to `IArithmeticAtomicable`. extension<T : IArithmeticAtomicable> Atomic<T> { + /// Atomically adds the given value to the stored value and returns the + /// original stored value. __intrinsic_op($(kIROp_AtomicAdd)) - [__ref] T add(T value, MemoryOrder order = MemoryOrder.Relaxed); // returns original value + [__ref] T add(T value, MemoryOrder order = MemoryOrder.Relaxed); + + /// Atomically subtracts the given value from the stored value and returns + /// the original stored value. __intrinsic_op($(kIROp_AtomicSub)) - [__ref] T sub(T value, MemoryOrder order = MemoryOrder.Relaxed); // returns original value + [__ref] T sub(T value, MemoryOrder order = MemoryOrder.Relaxed); + + /// Atomically computes the maximum of the stored value and the given + /// value, storing the result and returning the original stored value. __intrinsic_op($(kIROp_AtomicMax)) - [__ref] T max(T value, MemoryOrder order = MemoryOrder.Relaxed); // returns original value + [__ref] T max(T value, MemoryOrder order = MemoryOrder.Relaxed); + + /// Atomically computes the minimum of the stored value and the given + /// value, storing the result and returning the original stored value. __intrinsic_op($(kIROp_AtomicMin)) - [__ref] T min(T value, MemoryOrder order = MemoryOrder.Relaxed); // returns original value + [__ref] T min(T value, MemoryOrder order = MemoryOrder.Relaxed); } -/// These addtional members are only available when `T` conforms to `IBitAtomicable`. +/// These additional members are only available when `T` conforms to `IBitAtomicable`. extension<T : IBitAtomicable> Atomic<T> { + /// Atomically performs a bitwise AND operation between the stored value + /// and the given value, storing the result and returning the original + /// stored value. __intrinsic_op($(kIROp_AtomicAnd)) - [__ref] T and(T value, MemoryOrder order = MemoryOrder.Relaxed); // returns original value + [__ref] T and(T value, MemoryOrder order = MemoryOrder.Relaxed); + + /// Atomically performs a bitwise OR operation between the stored value and + /// the given value, storing the result and returning the original stored + /// value. __intrinsic_op($(kIROp_AtomicOr)) - [__ref] T or(T value, MemoryOrder order = MemoryOrder.Relaxed); // returns original value + [__ref] T or(T value, MemoryOrder order = MemoryOrder.Relaxed); + + /// Atomically performs a bitwise XOR operation between the stored value + /// and the given value, storing the result and returning the original + /// stored value. __intrinsic_op($(kIROp_AtomicXor)) - [__ref] T xor(T value, MemoryOrder order = MemoryOrder.Relaxed); // returns original value + [__ref] T xor(T value, MemoryOrder order = MemoryOrder.Relaxed); + + /// Atomically increments the stored value and returns the original stored + /// value. __intrinsic_op($(kIROp_AtomicInc)) [__ref] T increment(MemoryOrder order = MemoryOrder.Relaxed); + + /// Atomically decrements the stored value and returns the original stored + /// value. __intrinsic_op($(kIROp_AtomicDec)) [__ref] T decrement(MemoryOrder order = MemoryOrder.Relaxed); } |
