diff options
| author | Tomáš Jusko | 2023-09-24 00:22:47 +0200 |
|---|---|---|
| committer | Tomáš Jusko | 2023-09-24 00:22:47 +0200 |
| commit | 708df6c01c1465f8d881840a28602547adaf70ff (patch) | |
| tree | 49e56f099dc5524d0c5680d445d15227ac2c27c4 | |
| parent | c4cfc3689cf0852d47e12478b51572b5231f787d (diff) | |
| download | pyecsca-708df6c01c1465f8d881840a28602547adaf70ff.tar.gz pyecsca-708df6c01c1465f8d881840a28602547adaf70ff.tar.zst pyecsca-708df6c01c1465f8d881840a28602547adaf70ff.zip | |
feat: Added Pearson correlation coefficient for GPU
| -rw-r--r-- | pyecsca/sca/stacked_traces/correlate.py | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/pyecsca/sca/stacked_traces/correlate.py b/pyecsca/sca/stacked_traces/correlate.py new file mode 100644 index 0000000..10705ca --- /dev/null +++ b/pyecsca/sca/stacked_traces/correlate.py @@ -0,0 +1,44 @@ +import numpy as np +import numpy.typing as npt +from numba import cuda +from math import sqrt + + +@cuda.jit(device=True, cache=True) +def gpu_pearson_corr(samples: npt.NDArray[np.number], + intermediate_values: npt.NDArray[np.number], + result: cuda.devicearray.DeviceNDArray): + """ + Calculates the Pearson correlation coefficient between the given samples and intermediate values using GPU acceleration. + + :param samples: A 2D array of shape (n, m) containing the samples. + :type samples: npt.NDArray[np.number] + :param intermediate_values: A 1D array of shape (n,) containing the intermediate values. + :type intermediate_values: npt.NDArray[np.number] + :param result: A 1D array of shape (m,) to store the resulting correlation coefficients. + :type result: cuda.devicearray.DeviceNDArray + """ + col: int = cuda.grid(1) # type: ignore + + if col >= samples.shape[1]: # type: ignore + return + + n = samples.shape[0] + samples_sum = 0. + samples_sq_sum = 0. + intermed_sum = 0. + intermed_sq_sum = 0. + product_sum = 0. + + for row in range(n): + samples_sum += samples[row, col] + samples_sq_sum += samples[row, col] ** 2 + intermed_sum += intermediate_values[row] + intermed_sq_sum += intermediate_values[row] ** 2 + product_sum += samples[row, col] * intermediate_values[row] + + numerator = n * product_sum - samples_sum * intermed_sum + denominator = (sqrt(n * samples_sq_sum - samples_sum * samples_sum) + * sqrt(n * intermed_sq_sum - intermed_sum * intermed_sum)) + + result[col] = numerator / denominator |
