Compute sign bit of dot product of hash(seed, input) and weight. NOTE: use float as seed, and convert it to double as a temporary solution to match the trained model. This is going to be changed once the new model is trained in an optimized method.
| 113 | // model is trained in an optimized method. |
| 114 | // |
| 115 | int RunningSignBit(const TfLiteTensor* input, const TfLiteTensor* weight, |
| 116 | float seed) { |
| 117 | double score = 0.0; |
| 118 | int input_item_bytes = input->bytes / SizeOfDimension(input, 0); |
| 119 | char* input_ptr = input->data.raw; |
| 120 | |
| 121 | const size_t seed_size = sizeof(float); |
| 122 | const size_t key_bytes = sizeof(float) + input_item_bytes; |
| 123 | std::unique_ptr<char[]> key(new char[key_bytes]); |
| 124 | |
| 125 | for (int i = 0; i < SizeOfDimension(input, 0); ++i) { |
| 126 | // Create running hash id and value for current dimension. |
| 127 | memcpy(key.get(), &seed, seed_size); |
| 128 | memcpy(key.get() + seed_size, input_ptr, input_item_bytes); |
| 129 | |
| 130 | int64_t hash_signature = ::util::Fingerprint64(key.get(), key_bytes); |
| 131 | double running_value = static_cast<double>(hash_signature); |
| 132 | input_ptr += input_item_bytes; |
| 133 | if (weight == nullptr) { |
| 134 | score += running_value; |
| 135 | } else { |
| 136 | score += weight->data.f[i] * running_value; |
| 137 | } |
| 138 | } |
| 139 | |
| 140 | return (score > 0) ? 1 : 0; |
| 141 | } |
| 142 | |
| 143 | void SparseLshProjection(const TfLiteTensor* hash, const TfLiteTensor* input, |
| 144 | const TfLiteTensor* weight, int32_t* out_buf) { |
no test coverage detected