@@ -107,6 +107,72 @@ private void createVectors(Args...)(ref Args args)
107107 }
108108}
109109
110+ version (LDC ) {}
111+ else version (Windows ) {}
112+ else version (X86_64 )
113+ {
114+ // Compiling with DMD for x86-64 for Linux & OS X with optimizations enabled,
115+ // "Tensor mutation on-the-fly" unittest was failing. Disabling inlining
116+ // caused it to succeed.
117+ // TODO: Rework so this is unnecessary!
118+ version = Mir_disable_inlining_in_reduce;
119+ }
120+
121+ version (Mir_disable_inlining_in_reduce)
122+ {
123+ private enum Mir_disable_inlining_in_reduce = true ;
124+
125+ private template _naryAliases (size_t n)
126+ {
127+ static if (n == 0 )
128+ enum _naryAliases = " " ;
129+ else
130+ {
131+ enum i = n - 1 ;
132+ enum _naryAliases = _naryAliases! i ~ " alias " ~ cast (char )(' a' + i) ~ " = args[" ~ i.stringof ~ " ];\n " ;
133+ }
134+ }
135+
136+ private template nonInlinedNaryFun (alias fun)
137+ {
138+ import mir.math.common : optmath;
139+ static if (is (typeof (fun) : string ))
140+ {
141+ // / Specialization for string lambdas
142+ @optmath auto ref nonInlinedNaryFun(Args... )(auto ref Args args)
143+ if (args.length <= 26 )
144+ {
145+ pragma (inline,false );
146+ import mir.functional: _naryAliases;
147+ mixin (_naryAliases! (Args.length));
148+ return mixin (fun);
149+ }
150+ }
151+ else static if (is (typeof (fun.opCall ) == function ))
152+ {
153+ @optmath auto ref nonInlinedNaryFun(Args... )(auto ref Args args)
154+ if (is (typeof (fun.opCall (args))))
155+ {
156+ pragma (inline,false );
157+ return fun.opCall (args);
158+ }
159+ }
160+ else
161+ {
162+ @optmath auto ref nonInlinedNaryFun(Args... )(auto ref Args args)
163+ if (is (typeof (fun(args))))
164+ {
165+ pragma (inline,false );
166+ return fun (args);
167+ }
168+ }
169+ }
170+ }
171+ else
172+ {
173+ private enum Mir_disable_inlining_in_reduce = false ;
174+ }
175+
110176S reduceImpl (alias fun, S, Slices... )(S seed, Slices slices)
111177{
112178 do
@@ -145,7 +211,8 @@ See_Also:
145211template reduce (alias fun)
146212{
147213 import mir.functional: naryFun;
148- static if (__traits(isSame, naryFun! fun, fun))
214+ static if (__traits(isSame, naryFun! fun, fun)
215+ && ! Mir_disable_inlining_in_reduce)
149216 /+ +
150217 Params:
151218 seed = An initial accumulation value.
@@ -174,6 +241,29 @@ template reduce(alias fun)
174241 return reduceImpl! (fun, UT , Slices)(seed, slices);
175242 }
176243 }
244+ else version (Mir_disable_inlining_in_reduce)
245+ // As above, but with inlining disabled.
246+ @optmath auto reduce(S, Slices... )(S seed, Slices slices)
247+ if (Slices.length)
248+ {
249+ slices.checkShapesMatch;
250+ static if (areAllContiguousTensors! Slices)
251+ {
252+ FlattenedList! Slices vectors;
253+ createVectors(slices, vectors);
254+ return .reduce! fun(seed, vectors);
255+ }
256+ else
257+ {
258+ if (slices[0 ].anyEmpty)
259+ return cast (Unqual! S) seed;
260+ static if (is (S : Unqual! S))
261+ alias UT = Unqual! S;
262+ else
263+ alias UT = S;
264+ return reduceImpl! (nonInlinedNaryFun! fun, UT , Slices)(seed, slices);
265+ }
266+ }
177267 else
178268 alias reduce = .reduce! (naryFun! fun);
179269}
0 commit comments