@@ -66,6 +66,9 @@ struct ClusterNative {
6666 static constexpr int scaleSaturatedQtot = 8 ;
6767 static constexpr int maxRegularQtot = 25 * 1024 ;
6868 static constexpr int maxSaturatedQtot = (USHRT_MAX - maxRegularQtot) * scaleSaturatedQtot;
69+ static constexpr float scaleNNDirectionPacked = 2048 .f;
70+ static constexpr int16_t invalidNNDirectionPacked = -32768 ;
71+ static constexpr float maxNNDirection = 32767 .f / scaleNNDirectionPacked;
6972
7073 uint32_t timeFlagsPacked; // < Contains the time in the lower 24 bits in a packed format, contains the flags in the
7174 // upper 8 bits
@@ -74,18 +77,40 @@ struct ClusterNative {
7477 uint8_t sigmaPadPacked; // < Sigma of the pad in packed format
7578 uint16_t qMax; // < QMax of the cluster
7679 uint16_t qTotPacked; // < Total charge of the cluster
80+ int16_t nnDydxPacked = invalidNNDirectionPacked;
81+ int16_t nnDzdxPacked = invalidNNDirectionPacked;
7782
7883 GPUd () static uint16_t packPad (float pad) { return (uint16_t )(pad * scalePadPacked + 0.5 ); }
7984 GPUd () static uint32_t packTime (float time) { return (uint32_t )(time * scaleTimePacked + 0.5 ); }
8085 GPUd () static float unpackPad (uint16_t pad) { return float (pad) * (1 .f / scalePadPacked); }
8186 GPUd () static float unpackTime (uint32_t time) { return float (time) * (1 .f / scaleTimePacked); }
87+ GPUd () static int16_t packNNDirection (float v)
88+ {
89+ v = v < -maxNNDirection ? -maxNNDirection : (v > maxNNDirection ? maxNNDirection : v);
90+ return static_cast <int16_t >(v * scaleNNDirectionPacked + (v >= 0 .f ? 0 .5f : -0 .5f ));
91+ }
92+ GPUd () static float unpackNNDirection (int16_t v) { return float (v) * (1 .f / scaleNNDirectionPacked); }
8293
8394 GPUdDefault () ClusterNative() = default ;
8495 GPUd () ClusterNative(uint32_t time, uint8_t flags, uint16_t pad, uint8_t sigmaTime, uint8_t sigmaPad, uint16_t qmax, uint16_t qtotPacked) : padPacked(pad), sigmaTimePacked(sigmaTime), sigmaPadPacked(sigmaPad), qMax(qmax), qTotPacked(qtotPacked)
8596 {
8697 setTimePackedFlags (time, flags);
8798 }
8899
100+ GPUd () bool hasNNDirection () const { return nnDydxPacked != invalidNNDirectionPacked && nnDzdxPacked != invalidNNDirectionPacked; }
101+ GPUd () float getNNDydx () const { return unpackNNDirection (nnDydxPacked); }
102+ GPUd () float getNNDzdx () const { return unpackNNDirection (nnDzdxPacked); }
103+ GPUd () void setNNDirection (float dydx, float dzdx)
104+ {
105+ nnDydxPacked = packNNDirection (dydx);
106+ nnDzdxPacked = packNNDirection (dzdx);
107+ }
108+ GPUd () void clearNNDirection ()
109+ {
110+ nnDydxPacked = invalidNNDirectionPacked;
111+ nnDzdxPacked = invalidNNDirectionPacked;
112+ }
113+
89114 GPUd () uint16_t getQmax () const { return qMax; }
90115 GPUd () uint32_t getQtot () const { return isSaturated () ? getSaturatedQtot () : (uint32_t )qTotPacked; }
91116 GPUd () uint8_t getFlags () const { return timeFlagsPacked >> 24 ; }
@@ -187,6 +212,10 @@ struct ClusterNative {
187212 return (this ->qMax < rhs.qMax );
188213 } else if (this ->qTotPacked != rhs.qTotPacked ) {
189214 return (this ->getQtot () < rhs.getQtot ());
215+ } else if (this ->nnDydxPacked != rhs.nnDydxPacked ) {
216+ return (this ->nnDydxPacked < rhs.nnDydxPacked );
217+ } else if (this ->nnDzdxPacked != rhs.nnDzdxPacked ) {
218+ return (this ->nnDzdxPacked < rhs.nnDzdxPacked );
190219 } else {
191220 return (this ->getFlags () < rhs.getFlags ());
192221 }
@@ -200,6 +229,8 @@ struct ClusterNative {
200229 this ->sigmaPadPacked == rhs.sigmaPadPacked &&
201230 this ->qMax == rhs.qMax &&
202231 this ->qTotPacked == rhs.qTotPacked &&
232+ this ->nnDydxPacked == rhs.nnDydxPacked &&
233+ this ->nnDzdxPacked == rhs.nnDzdxPacked &&
203234 this ->getFlags () == rhs.getFlags ();
204235 }
205236
0 commit comments