UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
ParallelTransformReduce.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "Async/ParallelFor.h"
6#include "MathUtil.h"
7
8namespace UE {
9namespace Geometry {
10
11 //
12 // Index interface (similar to ParallelFor)
13 // TransformFuncT should be a function pointer-like object with signature: T(IntType )
14 // ReduceFuncT should be a function pointer-like object with signature: T(T,T)
15
16 template<typename IntType, typename T, typename TransformFuncT, typename ReduceFuncT>
18 const T& Init,
22 {
23 check(InNumTasks > 0);
24 // ParallelFor doesn't yet support int64 NumTasks, so cap it
25 const int32 NumTasks = (int32) FMath::Min(InNumTasks, MAX_int32);
26
27 const IntType NumPerTask = (IntType)FMathf::Ceil((float)Num / (float)NumTasks);
28
30 PerTaskResults.SetNum(NumTasks);
31
32 ParallelFor(NumTasks, [&](int32 TaskIndex)
33 {
34 T LocalResult{ Init };
35
36 IntType End = FMath::Min((TaskIndex + 1) * NumPerTask, Num);
37 for (IntType Index = TaskIndex * NumPerTask; Index < End; ++Index)
38 {
39 T Transformed{ Transform(Index) };
40 LocalResult = Reduce(Transformed, LocalResult);
41 }
42
43 PerTaskResults[TaskIndex] = LocalResult;
44 });
45
46 T FinalResult{ Init };
47 for (const T& PartialResult : PerTaskResults)
48 {
50 }
51 return FinalResult;
52 }
53
54
55
56 //
57 // Index interface for non-copyable types
58 // InitFuncT should be a function-like object with signature void(T&)
59 // TransformFuncT should be a function-like object with signature void(IntType,T&)
60 // ReduceFuncT should be a function-like object with signature void(T,T&)
61
62 template<typename IntType, typename T, typename InitFuncT, typename TransformFuncT, typename ReduceFuncT>
67 T& Out,
69 {
70 check(InNumTasks > 0);
71
72 // ParallelFor doesn't yet support int64 NumTasks, so cap it
73 const int32 NumTasks = (int32)FMath::Min(InNumTasks, MAX_int32);
74
75 IntType NumPerTask = (IntType)FMathf::Ceil((float)Num / (float)NumTasks);
76
78 PerTaskResults.SetNum(NumTasks);
79
80 ParallelFor(NumTasks, [&](int32 TaskIndex)
81 {
82 InitFunc(PerTaskResults[TaskIndex]);
83
84 IntType End = FMath::Min((TaskIndex + 1) * NumPerTask, Num);
85 for (IntType Index = TaskIndex * NumPerTask; Index < End; ++Index)
86 {
87 T Transformed;
88 Transform(Index, Transformed);
89 Reduce(Transformed, PerTaskResults[TaskIndex]);
90 }
91 });
92
93 InitFunc(Out);
94 for (const T& PartialResult : PerTaskResults)
95 {
97 }
98 }
99
100
101 //
102 // Iterator interface helpers
103 //
104
105 // TODO: Specialize this for for random-access iterators
106 template<typename IterT>
108 {
109 int64 Count = 0;
110 for (IterT Iter = Begin; Iter != End; ++Iter)
111 {
112 ++Count;
113 }
114 return Count;
115 }
116
117
118 // TODO: Specialize this for random-access iterators
119 template<typename IterT>
121 {
122 IterT I = Start;
123 for (int64 Inc = 0; Inc < N; ++Inc)
124 {
125 ++I;
126 }
127 return I;
128 }
129
130 template<typename ContainerType, typename ElementType, typename SizeType>
136
137 template<typename ContainerType, typename ElementType, typename SizeType>
144
145 // Iterator interface
146 // TransformFuncT should be a function-like object with signature: T(U), where U is the type referred to by IterT
147 // ReduceFuncT should be a function-like object with signature: T(T,T)
148
149 template<typename T, typename IterT, typename TransformFuncT, typename ReduceFuncT>
152 const T& Init,
156 {
158
159 check(InNumTasks > 0);
160
161 // ParallelFor doesn't yet support int64 NumTasks, so cap it
162 const int32 NumTasks = (int32)FMath::Min(InNumTasks, MAX_int32);
163
164 int64 NumPerTask = (int64)FMathf::Ceil((float)Num / (float)NumTasks);
165
167 PerTaskResults.SetNum(NumTasks);
168
169 ParallelFor(NumTasks, [&](int32 TaskIndex)
170 {
171 T LocalResult{ Init };
172
173 IterT LocalIter = AdvanceIterator(BeginIterator, FMath::Min(Num, int64(TaskIndex) * NumPerTask));
174 IterT LocalEndIter = AdvanceIterator(BeginIterator, FMath::Min(Num, (int64(TaskIndex) + 1) * NumPerTask));
175
176 while (LocalIter != LocalEndIter)
177 {
178 T Transformed{ Transform(*LocalIter) };
179 LocalResult = Reduce(Transformed, LocalResult);
180
181 ++LocalIter;
182 }
183
184 PerTaskResults[TaskIndex] = LocalResult;
185 });
186
187 T FinalResult{ Init };
188 for (const T& PartialResult : PerTaskResults)
189 {
191 }
192 return FinalResult;
193 }
194
195 //
196 // Iterator interface for non-copyable types
197 // InitFuncT should be a function-like object with signature: void(T&)
198 // TransformFuncT should be a function-like object with signature: void(U,T&), where U is the type referred to by IterT
199 // ReduceFuncT should be a function-like object with signature: void(T,T&)
200
201 template<typename T, typename IterT, typename InitFuncT, typename TransformFuncT, typename ReduceFuncT>
207 T& Out,
209 {
211
212 check(InNumTasks > 0);
213 // ParallelFor doesn't yet support int64 NumTasks, so cap it
214 const int32 NumTasks = (int32)FMath::Min(InNumTasks, MAX_int32);
215
216 int64 NumPerTask = (int64)FMathf::Ceil((float)Num / (float)NumTasks);
217
219 PerTaskResults.SetNum(NumTasks);
220
221 ParallelFor(NumTasks, [&](int32 TaskIndex)
222 {
223 InitFunc(PerTaskResults[TaskIndex]);
224
225 IterT LocalIter = AdvanceIterator(BeginIterator, FMath::Min(Num, int64(TaskIndex) * NumPerTask));
226 IterT LocalEndIter = AdvanceIterator(BeginIterator, FMath::Min(Num, (int64(TaskIndex) + 1) * NumPerTask));
227
228 while (LocalIter != LocalEndIter)
229 {
230 T Transformed;
231 Transform(*LocalIter, Transformed);
232 Reduce(Transformed, PerTaskResults[TaskIndex]);
233 ++LocalIter;
234 }
235 });
236
237 InitFunc(Out);
238 for (const T& PartialResult : PerTaskResults)
239 {
240 Reduce(PartialResult, Out);
241 }
242 }
243
244} // end namespace UE::Geometry
245} // end namespace UE
#define check(expr)
Definition AssertionMacros.h:314
void ParallelFor(int32 Num, TFunctionRef< void(int32)> Body, bool bForceSingleThread, bool bPumpRenderingThread=false)
Definition ParallelFor.h:481
FPlatformTypes::int64 int64
A 64-bit signed integer.
Definition Platform.h:1127
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
void Init()
Definition LockFreeList.h:4
@ Num
Definition MetalRHIPrivate.h:234
#define MAX_int32
Definition NumericLimits.h:25
USkinnedMeshComponent float
Definition SkinnedMeshComponent.h:60
Definition Array.h:670
void SetNum(SizeType NewNum, EAllowShrinking AllowShrinking=UE::Core::Private::AllowShrinkingByDefault< AllocatorType >())
Definition Array.h:2308
Definition Array.h:64
static RealType Ceil(const RealType Value)
Definition MathUtil.h:390
IterT AdvanceIterator(IterT Start, int64 N)
Definition ParallelTransformReduce.h:120
int64 IteratorDistance(IterT Begin, IterT End)
Definition ParallelTransformReduce.h:107
T ParallelTransformReduce(IntType Num, const T &Init, TransformFuncT Transform, ReduceFuncT Reduce, int64 InNumTasks)
Definition ParallelTransformReduce.h:17
Definition AdvancedWidgetsModule.cpp:13
U16 Index
Definition radfft.cpp:71