Skip to content

Commit 7d739bc

Browse files
committed
GPU: define CAMath::Abs for GPUdoubleCalcImpl
CAMath::Abs is a template that deduces its parameter rather than taking a float, so a call on a GPUdoubleCalc intermediate selects the primary template, which is declared and never defined. Four call sites in the track propagation do exactly that. Compiling to an object hides it, so the Metal build only fails when the kernels are linked; on the host the type is a double and the question does not arise. Every other CAMath entry point takes a float and is reached through the implicit conversion, so only Abs needs the specialisation.
1 parent bb585c3 commit 7d739bc

1 file changed

Lines changed: 10 additions & 0 deletions

File tree

‎GPU/Common/GPUCommonDouble.h‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#define GPUCOMMONDOUBLE_H
1717

1818
#include "GPUCommonDef.h"
19+
#include "GPUCommonMath.h"
1920

2021
#ifndef GPUCA_GPUCODE_DEVICE
2122
#include <cstdint>
@@ -193,6 +194,15 @@ GPUdi() threadgroup float& operator+=(threadgroup float& a, GPUdoubleCalcImpl b)
193194
GPUdi() float& operator+=(float& a, GPUdoubleCalcImpl b) { return a = (float)(GPUdoubleCalcImpl(a) + b); }
194195
#endif
195196

197+
// CAMath::Abs is a template that deduces its parameter, so a call on this type
198+
// picks the primary template, which has no definition. The rest of CAMath takes
199+
// float and is reached through the implicit conversion.
200+
template <>
201+
GPUhdi() GPUdoubleCalcImpl GPUCommonMath::Abs<GPUdoubleCalcImpl>(GPUdoubleCalcImpl x)
202+
{
203+
return (float)x < 0.f ? -x : x;
204+
}
205+
196206
// GPUCA_FORCE_DOUBLECALC lets a host test exercise the Metal representation and
197207
// compare it against the double one.
198208
#if defined(__METAL__) && defined(__FAST_MATH__)

0 commit comments

Comments
 (0)