SGSparseVector<ST> CHashedSparseFeatures<ST>::hash_vector(SGSparseVector<ST> vec, int32_t dim, bool use_quadratic, bool keep_linear_terms) { SGVector<ST> h_vec(dim); SGVector<ST>::fill_vector(h_vec, dim, 0); int32_t hash_cache_size = use_quadratic ? vec.num_feat_entries : 0; SGVector<uint32_t> hash_cache(hash_cache_size); for (index_t i=0; i<vec.num_feat_entries; i++) { uint32_t hash = CHash::MurmurHash3((uint8_t* ) &vec.features[i].feat_index, sizeof (index_t), vec.features[i].feat_index); if (use_quadratic) hash_cache[i] = hash; if ( (!use_quadratic) || keep_linear_terms ) h_vec[hash % dim] += vec.features[i].entry; } if (use_quadratic) { for (index_t i=0; i<vec.num_feat_entries; i++) { index_t n_idx = vec.features[i].feat_index + vec.features[i].feat_index; index_t idx = CHash::MurmurHash3((uint8_t* ) &n_idx, sizeof(index_t), vec.features[i].feat_index) % dim; h_vec[idx] += vec.features[i].entry * vec.features[i].entry; for (index_t j=i+1; j<vec.num_feat_entries; j++) { idx = (hash_cache[i] ^ hash_cache[j]) % dim; h_vec[idx] += vec.features[i].entry * vec.features[j].entry; } } } int32_t num_nnz_features = 0; for (index_t i=0; i<dim; i++) { if (h_vec[i]!=0) num_nnz_features++; } SGSparseVector<ST> sv(num_nnz_features); int32_t sparse_index = 0; for (index_t i=0; i<dim; i++) { if (h_vec[i]!=0) { sv.features[sparse_index].entry = h_vec[i]; sv.features[sparse_index++].feat_index = i; } } return sv; }
int main(void) { // generate 20 random numbers on the host thrust::host_vector<int> h_vec(20); thrust::generate(h_vec.begin(), h_vec.end(), rand); // interface to CUDA code sort_on_device(h_vec); // print sorted array thrust::copy(h_vec.begin(), h_vec.end(), std::ostream_iterator<int>(std::cout, "\n")); return 0; }