Skip to content

Commit

Permalink
transpose matmul categorical bit reproducibility
Browse files Browse the repository at this point in the history
  • Loading branch information
adityagoel4512 committed Feb 23, 2024
1 parent 5340f2d commit 8c2de99
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 10 deletions.
26 changes: 16 additions & 10 deletions src/tabmat/ext/cat_split_helpers-tmpl.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#include <vector>

#include <omp.h>

<%def name="transpose_matvec(dropfirst)">
template <typename Int, typename F>
Expand All @@ -10,24 +10,30 @@ void _transpose_matvec_${dropfirst}(
F* res,
Int res_size
) {
#pragma omp parallel
int num_threads = omp_get_max_threads();
std::vector<F> all_res(num_threads * res_size, 0.0);
#pragma omp parallel shared(all_res)
{
std::vector<F> restemp(res_size, 0.0);
#pragma omp for
int tid = omp_get_thread_num();
F* res_slice = &all_res[tid * res_size];
#pragma omp for
for (Py_ssize_t i = 0; i < n_rows; i++) {
% if dropfirst == 'all_rows_drop_first':
Py_ssize_t col_idx = indices[i] - 1;
if (col_idx != -1) {
restemp[col_idx] += other[i];
res_slice[col_idx] += other[i];
}
% else:
restemp[indices[i]] += other[i];
res_slice[indices[i]] += other[i];
% endif
}
for (Py_ssize_t i = 0; i < res_size; i++) {
# pragma omp atomic
res[i] += restemp[i];
}
#pragma omp for
for (Py_ssize_t i = 0; i < res_size; ++i) {
for (int tid = 0; tid < num_threads; ++tid) {
#pragma omp atomic
res[i] += all_res[tid * res_size + i];
}
}
}
}
</%def>
Expand Down
24 changes: 24 additions & 0 deletions tests/test_reproducibility.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import numpy as np
import pandas as pd
import pytest

import tabmat as tm

N = 100
K = 5


@pytest.fixture
def df():
rng = np.random.default_rng(1234)
return pd.DataFrame(
pd.Categorical(rng.integers(low=0, high=K - 1, size=N), categories=range(K))
)


@pytest.mark.parametrize("cat_threshold", [K, K + 1])
def test_mat_transpose_vec(df, cat_threshold):
rng = np.random.default_rng(1234)
vec = rng.normal(size=N)
mat = tm.from_pandas(df, cat_threshold=cat_threshold)
np.testing.assert_equal(mat.transpose_matvec(vec), mat.transpose_matvec(vec))

0 comments on commit 8c2de99

Please sign in to comment.