-
Notifications
You must be signed in to change notification settings - Fork 6
/
Hash.cuh
115 lines (98 loc) · 2.52 KB
/
Hash.cuh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
//
// Created by davidxu on 22-7-27.
//
#ifndef GPU_POISSONRECON_HASH_CUH
#define GPU_POISSONRECON_HASH_CUH
struct KeyValue
{
int key;
int value;
};
const int kHashTableCapacity = 8 * 1024 * 1024;
const int kEmpty = 0xffffffff;
// 32 bit Murmur3 hash
__device__ int hash(int k)
{
k ^= k >> 16;
k *= 0x85ebca6b;
k ^= k >> 13;
k *= 0xc2b2ae35;
k ^= k >> 16;
return k & (kHashTableCapacity-1);
}
KeyValue* create_hashtable(){
KeyValue *hashtable;
cudaMalloc(&hashtable,sizeof(KeyValue) * kHashTableCapacity);
static_assert(kEmpty == 0xffffffff, "memset expected kEmpty=0xffffffff");
cudaMemset(hashtable,0xff,sizeof(KeyValue) * kHashTableCapacity);
return hashtable;
}
__device__ void insert(KeyValue *hashtable,const int& key,const int& value){
int slot = hash(key);
while(true)
{
int prev = atomicCAS(&hashtable[slot].key, kEmpty, key);
if (prev == kEmpty || prev == key)
{
hashtable[slot].value = value;
return;
}
slot = (slot + 1) & (kHashTableCapacity-1);
}
}
__device__ void insertMin(KeyValue *hashtable,const int& key,const int& value){
int slot = hash(key);
while(true)
{
int prev = atomicCAS(&hashtable[slot].key, kEmpty, key);
if(prev == kEmpty)
{
atomicExch(&hashtable[slot].value,0x7fffffff);
atomicMin(&hashtable[slot].value,value);
return;
}
if(prev == key)
{
atomicMin(&hashtable[slot].value,value);
return;
}
slot = (slot + 1) & (kHashTableCapacity-1);
}
}
__device__ void keyAdd(KeyValue *hashtable,const int& key){
int slot = hash(key);
while(true)
{
int prev = atomicCAS(&hashtable[slot].key, kEmpty, key);
if(prev == kEmpty)
{
atomicAdd(&hashtable[slot].value,1);
}
if(prev == kEmpty || prev == key)
{
atomicAdd(&hashtable[slot].value,1);
return;
}
slot = (slot + 1) & (kHashTableCapacity-1);
}
}
__device__ int find(KeyValue *hashtable,const int& key){
int slot = hash(key);
while (true)
{
if (hashtable[slot].key == key)
{
return hashtable[slot].value;
}
if (hashtable[slot].key == kEmpty)
{
return 0;
}
slot = (slot + 1) & (kHashTableCapacity - 1);
}
}
void destroy_hashtable(KeyValue* pHashTable)
{
cudaFree(pHashTable);
}
#endif //GPU_POISSONRECON_HASH_CUH