Blender V4.3
hash.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#ifndef __UTIL_HASH_H__
6#define __UTIL_HASH_H__
7
8#include "util/math.h"
9#include "util/types.h"
10
12
13/* [0, uint_max] -> [0.0, 1.0) */
15{
16 /* NOTE: we divide by 4294967808 instead of 2^32 because the latter
17 * leads to a [0.0, 1.0] mapping instead of [0.0, 1.0) due to floating
18 * point rounding error. 4294967808 unfortunately leaves (precisely)
19 * one unused ULP between the max number this outputs and 1.0, but
20 * that's the best you can do with this construction. */
21 return (float)n * (1.0f / 4294967808.0f);
22}
23
24/* [0, uint_max] -> [0.0, 1.0] */
26{
27 return (float)n * (1.0f / (float)0xFFFFFFFFu);
28}
29
30/* ***** Jenkins Lookup3 Hash Functions ***** */
31
32/* Source: http://burtleburtle.net/bob/c/lookup3.c */
33
34#define rot(x, k) (((x) << (k)) | ((x) >> (32 - (k))))
35
36#define mix(a, b, c) \
37 { \
38 a -= c; \
39 a ^= rot(c, 4); \
40 c += b; \
41 b -= a; \
42 b ^= rot(a, 6); \
43 a += c; \
44 c -= b; \
45 c ^= rot(b, 8); \
46 b += a; \
47 a -= c; \
48 a ^= rot(c, 16); \
49 c += b; \
50 b -= a; \
51 b ^= rot(a, 19); \
52 a += c; \
53 c -= b; \
54 c ^= rot(b, 4); \
55 b += a; \
56 } \
57 ((void)0)
58
59#define final(a, b, c) \
60 { \
61 c ^= b; \
62 c -= rot(b, 14); \
63 a ^= c; \
64 a -= rot(c, 11); \
65 b ^= a; \
66 b -= rot(a, 25); \
67 c ^= b; \
68 c -= rot(b, 16); \
69 a ^= c; \
70 a -= rot(c, 4); \
71 b ^= a; \
72 b -= rot(a, 14); \
73 c ^= b; \
74 c -= rot(b, 24); \
75 } \
76 ((void)0)
77
79{
80 uint a, b, c;
81 a = b = c = 0xdeadbeef + (1 << 2) + 13;
82
83 a += kx;
84 final(a, b, c);
85
86 return c;
87}
88
90{
91 uint a, b, c;
92 a = b = c = 0xdeadbeef + (2 << 2) + 13;
93
94 b += ky;
95 a += kx;
96 final(a, b, c);
97
98 return c;
99}
100
102{
103 uint a, b, c;
104 a = b = c = 0xdeadbeef + (3 << 2) + 13;
105
106 c += kz;
107 b += ky;
108 a += kx;
109 final(a, b, c);
110
111 return c;
112}
113
115{
116 uint a, b, c;
117 a = b = c = 0xdeadbeef + (4 << 2) + 13;
118
119 a += kx;
120 b += ky;
121 c += kz;
122 mix(a, b, c);
123
124 a += kw;
125 final(a, b, c);
126
127 return c;
128}
129
130#undef rot
131#undef final
132#undef mix
133
134/* Hashing uint or uint[234] into a float in the range [0, 1]. */
135
140
142{
143 return uint_to_float_incl(hash_uint2(kx, ky));
144}
145
147{
148 return uint_to_float_incl(hash_uint3(kx, ky, kz));
149}
150
152{
153 return uint_to_float_incl(hash_uint4(kx, ky, kz, kw));
154}
155
156/* Hashing float or float[234] into a float in the range [0, 1]. */
157
162
167
172
178
179/* Hashing float[234] into float[234] of components in the range [0, 1]. */
180
185
192
194{
196 hash_float4_to_float(make_float4(k.w, k.x, k.y, k.z)),
197 hash_float4_to_float(make_float4(k.z, k.w, k.x, k.y)),
198 hash_float4_to_float(make_float4(k.y, k.z, k.w, k.x)));
199}
200
201/* Hashing float or float[234] into float3 of components in range [0, 1]. */
202
209
216
218{
220 hash_float4_to_float(make_float4(k.z, k.x, k.w, k.y)),
221 hash_float4_to_float(make_float4(k.w, k.z, k.y, k.x)));
222}
223
224/* Hashing float or float[234] into float2 of components in range [0, 1]. */
225
230
236
238{
239 return make_float2(hash_float4_to_float(make_float4(k.x, k.y, k.z, k.w)),
240 hash_float4_to_float(make_float4(k.z, k.x, k.w, k.y)));
241}
242
243/* SSE Versions Of Jenkins Lookup3 Hash Functions */
244
245#ifdef __KERNEL_SSE__
246# define rot(x, k) (((x) << (k)) | (srl(x, 32 - (k))))
247
248# define mix(a, b, c) \
249 { \
250 a -= c; \
251 a ^= rot(c, 4); \
252 c += b; \
253 b -= a; \
254 b ^= rot(a, 6); \
255 a += c; \
256 c -= b; \
257 c ^= rot(b, 8); \
258 b += a; \
259 a -= c; \
260 a ^= rot(c, 16); \
261 c += b; \
262 b -= a; \
263 b ^= rot(a, 19); \
264 a += c; \
265 c -= b; \
266 c ^= rot(b, 4); \
267 b += a; \
268 }
269
270# define final(a, b, c) \
271 { \
272 c ^= b; \
273 c -= rot(b, 14); \
274 a ^= c; \
275 a -= rot(c, 11); \
276 b ^= a; \
277 b -= rot(a, 25); \
278 c ^= b; \
279 c -= rot(b, 16); \
280 a ^= c; \
281 a -= rot(c, 4); \
282 b ^= a; \
283 b -= rot(a, 14); \
284 c ^= b; \
285 c -= rot(b, 24); \
286 }
287
288ccl_device_inline int4 hash_int4(int4 kx)
289{
290 int4 a, b, c;
291 a = b = c = make_int4(0xdeadbeef + (1 << 2) + 13);
292
293 a += kx;
294 final(a, b, c);
295
296 return c;
297}
298
299ccl_device_inline int4 hash_int4_2(int4 kx, int4 ky)
300{
301 int4 a, b, c;
302 a = b = c = make_int4(0xdeadbeef + (2 << 2) + 13);
303
304 b += ky;
305 a += kx;
306 final(a, b, c);
307
308 return c;
309}
310
311ccl_device_inline int4 hash_int4_3(int4 kx, int4 ky, int4 kz)
312{
313 int4 a, b, c;
314 a = b = c = make_int4(0xdeadbeef + (3 << 2) + 13);
315
316 c += kz;
317 b += ky;
318 a += kx;
319 final(a, b, c);
320
321 return c;
322}
323
324ccl_device_inline int4 hash_int4_4(int4 kx, int4 ky, int4 kz, int4 kw)
325{
326 int4 a, b, c;
327 a = b = c = make_int4(0xdeadbeef + (4 << 2) + 13);
328
329 a += kx;
330 b += ky;
331 c += kz;
332 mix(a, b, c);
333
334 a += kw;
335 final(a, b, c);
336
337 return c;
338}
339
340# if defined(__KERNEL_AVX2__)
341ccl_device_inline vint8 hash_int8(vint8 kx)
342{
343 vint8 a, b, c;
344 a = b = c = make_vint8(0xdeadbeef + (1 << 2) + 13);
345
346 a += kx;
347 final(a, b, c);
348
349 return c;
350}
351
352ccl_device_inline vint8 hash_int8_2(vint8 kx, vint8 ky)
353{
354 vint8 a, b, c;
355 a = b = c = make_vint8(0xdeadbeef + (2 << 2) + 13);
356
357 b += ky;
358 a += kx;
359 final(a, b, c);
360
361 return c;
362}
363
364ccl_device_inline vint8 hash_int8_3(vint8 kx, vint8 ky, vint8 kz)
365{
366 vint8 a, b, c;
367 a = b = c = make_vint8(0xdeadbeef + (3 << 2) + 13);
368
369 c += kz;
370 b += ky;
371 a += kx;
372 final(a, b, c);
373
374 return c;
375}
376
377ccl_device_inline vint8 hash_int8_4(vint8 kx, vint8 ky, vint8 kz, vint8 kw)
378{
379 vint8 a, b, c;
380 a = b = c = make_vint8(0xdeadbeef + (4 << 2) + 13);
381
382 a += kx;
383 b += ky;
384 c += kz;
385 mix(a, b, c);
386
387 a += kw;
388 final(a, b, c);
389
390 return c;
391}
392# endif
393
394# undef rot
395# undef final
396# undef mix
397
398#endif
399
400/* ***** Hash Prospector Hash Functions *****
401 *
402 * These are based on the high-quality 32-bit hash/mixing functions from
403 * https://github.com/skeeto/hash-prospector
404 */
405
407{
408 // The actual mixing function from Hash Prospector.
409 i ^= i >> 16;
410 i *= 0x21f0aaad;
411 i ^= i >> 15;
412 i *= 0xd35a2d97;
413 i ^= i >> 15;
414
415 // The xor is just to make input zero not map to output zero.
416 // The number is randomly selected and isn't special.
417 return i ^ 0xe6fe3beb;
418}
419
420/* Seedable version of hash_hp_uint() above. */
422{
423 // Manipulate the seed so it doesn't interact poorly with n when they
424 // are both e.g. incrementing. This isn't fool-proof, but is good
425 // enough for practical use.
426 seed ^= seed << 19;
427
428 return hash_hp_uint(i ^ seed);
429}
430
431/* Outputs [0.0, 1.0). */
436
437/* Outputs [0.0, 1.0). */
442
443/* ***** Modified Wang Hash Functions *****
444 *
445 * These are based on a bespoke modified version of the Wang hash, and
446 * can serve as a faster hash when quality isn't critical.
447 *
448 * The original Wang hash is documented here:
449 * https://www.burtleburtle.net/bob/hash/integer.html
450 */
451
453{
454 i = (i ^ 61) ^ seed;
455 i += i << 3;
456 i ^= i >> 4;
457 i *= 0x27d4eb2d;
458 return i;
459}
460
461/* Outputs [0.0, 1.0). */
466
467/* ***** Index Shuffling Hash Function *****
468 *
469 * This function takes an index, the length of the thing the index points
470 * into, and returns a shuffled index. For example, if you pass indices
471 * 0 through 19 to this function with a length parameter of 20, it will
472 * return the indices in a shuffled order with no repeats. Indices
473 * larger than the length parameter will simply repeat the same shuffled
474 * pattern over and over.
475 *
476 * This is useful for iterating over an array in random shuffled order
477 * without having to shuffle the array itself.
478 *
479 * Passing different seeds results in different random shuffles.
480 *
481 * This function runs in average O(1) time.
482 *
483 * See https://andrew-helmer.github.io/permute/ for details on how this
484 * works.
485 */
487{
488 i = i % length;
489 uint mask = (1 << (32 - count_leading_zeros(length - 1))) - 1;
490
491 do {
492 i ^= seed;
493 i *= 0xe170893d;
494 i ^= seed >> 16;
495 i ^= (i & mask) >> 4;
496 i ^= seed >> 8;
497 i *= 0x0929eb3f;
498 i ^= seed >> 23;
499 i ^= (i & mask) >> 1;
500 i *= 1 | seed >> 27;
501 i *= 0x6935fa69;
502 i ^= (i & mask) >> 11;
503 i *= 0x74dcb303;
504 i ^= (i & mask) >> 2;
505 i *= 0x9e501cc3;
506 i ^= (i & mask) >> 2;
507 i *= 0xc860a3df;
508 i &= mask;
509 i ^= i >> 5;
510 } while (i >= length);
511
512 return i;
513}
514
521{
522 const uint qx = 1103515245U * ((x >> 1U) ^ (y));
523 const uint qy = 1103515245U * ((y >> 1U) ^ (x));
524 const uint n = 1103515245U * ((qx) ^ (qy >> 3U));
525
526 return n;
527}
528
529/* ********** */
530
531#ifndef __KERNEL_GPU__
532static inline uint hash_string(const char *str)
533{
534 uint i = 0, c;
535
536 while ((c = *str++)) {
537 i = i * 37 + c;
538 }
539
540 return i;
541}
542#endif
543
545
546#endif /* __UTIL_HASH_H__ */
unsigned int uint
static unsigned long seed
Definition btSoftBody.h:39
SIMD_FORCE_INLINE btScalar length() const
Return the length of the vector.
Definition btVector3.h:257
local_group_size(16, 16) .push_constant(Type b
#define ccl_device_forceinline
#define ccl_device_inline
#define CCL_NAMESPACE_END
ccl_device_forceinline float4 make_float4(const float x, const float y, const float z, const float w)
ccl_device_forceinline float3 make_float3(const float x, const float y, const float z)
ccl_device_forceinline float2 make_float2(const float x, const float y)
#define __float_as_uint(x)
ccl_device_forceinline int4 make_int4(const int x, const int y, const int z, const int w)
draw_view in_light_buf[] float
#define str(s)
static uint hash_string(const char *str)
Definition hash.h:532
ccl_device_inline uint hash_uint2(uint kx, uint ky)
Definition hash.h:89
ccl_device_inline float hash_uint_to_float(uint kx)
Definition hash.h:136
ccl_device_inline float3 hash_float_to_float3(float k)
Definition hash.h:203
ccl_device_inline float hash_hp_seeded_float(uint i, uint seed)
Definition hash.h:438
ccl_device_inline float hash_wang_seeded_float(uint i, uint seed)
Definition hash.h:462
ccl_device_inline float3 hash_float4_to_float3(float4 k)
Definition hash.h:217
CCL_NAMESPACE_BEGIN ccl_device_forceinline float uint_to_float_excl(uint n)
Definition hash.h:14
ccl_device_inline float hash_float_to_float(float k)
Definition hash.h:158
ccl_device_forceinline float uint_to_float_incl(uint n)
Definition hash.h:25
ccl_device_inline uint hash_wang_seeded_uint(uint i, uint seed)
Definition hash.h:452
ccl_device_inline float3 hash_float2_to_float3(float2 k)
Definition hash.h:210
ccl_device_inline float2 hash_float2_to_float2(float2 k)
Definition hash.h:181
ccl_device_inline float hash_float2_to_float(float2 k)
Definition hash.h:163
ccl_device_inline float hash_hp_float(uint i)
Definition hash.h:432
ccl_device_inline uint hash_uint3(uint kx, uint ky, uint kz)
Definition hash.h:101
ccl_device_inline float hash_float4_to_float(float4 k)
Definition hash.h:173
ccl_device_inline uint hash_uint4(uint kx, uint ky, uint kz, uint kw)
Definition hash.h:114
ccl_device_inline float hash_uint4_to_float(uint kx, uint ky, uint kz, uint kw)
Definition hash.h:151
ccl_device_inline uint hash_iqnt2d(const uint x, const uint y)
Definition hash.h:520
ccl_device_inline float2 hash_float_to_float2(float k)
Definition hash.h:226
ccl_device_inline uint hash_shuffle_uint(uint i, uint length, uint seed)
Definition hash.h:486
ccl_device_inline float4 hash_float4_to_float4(float4 k)
Definition hash.h:193
ccl_device_inline float2 hash_float3_to_float2(float3 k)
Definition hash.h:231
ccl_device_inline uint hash_hp_uint(uint i)
Definition hash.h:406
ccl_device_inline uint hash_uint(uint kx)
Definition hash.h:78
ccl_device_inline float hash_uint2_to_float(uint kx, uint ky)
Definition hash.h:141
ccl_device_inline float hash_float3_to_float(float3 k)
Definition hash.h:168
ccl_device_inline float3 hash_float3_to_float3(float3 k)
Definition hash.h:186
ccl_device_inline float2 hash_float4_to_float2(float4 k)
Definition hash.h:237
ccl_device_inline float hash_uint3_to_float(uint kx, uint ky, uint kz)
Definition hash.h:146
#define mix(a, b, c)
Definition hash.h:36
ccl_device_inline uint hash_hp_seeded_uint(uint i, uint seed)
Definition hash.h:421
ccl_device_inline float4 mask(const int4 mask, const float4 a)
float x
float y
float z
Definition sky_float3.h:27
float y
Definition sky_float3.h:27
float x
Definition sky_float3.h:27
ccl_device_inline vint8 make_vint8(int a, int b, int c, int d, int e, int f, int g, int h)
ccl_device_inline uint count_leading_zeros(uint x)
Definition util/math.h:874