Loading...
Searching...
No Matches
PbcSimd.cpp
Go to the documentation of this file.
1/*
2** This file is part of eOn.
3**
4** SPDX-License-Identifier: BSD-3-Clause
5**
6** Copyright (c) 2010--present, eOn Development Team
7** All rights reserved.
8**
9** Repo:
10** https://github.com/TheochemUI/eOn
11*/
12#include "eon/PbcSimd.h"
13
14#include <cmath>
15#include <cstddef>
16
17#ifndef EON_PBC_SIMD_SCALAR_DEFINED
18#define EON_PBC_SIMD_SCALAR_DEFINED
19namespace {
20
21void wrapMinimumImageScalar(double *data, size_t begin, size_t n) {
22 for (size_t i = begin; i < n; ++i) {
23 const double x = data[i];
24 data[i] = x - std::floor(x + 0.5);
25 }
26}
27
28void wrapLegacyUnitScalar(double *data, size_t begin, size_t n) {
29 for (size_t i = begin; i < n; ++i) {
30 const double y = data[i] + 1.0;
31 data[i] = y - std::trunc(y);
32 }
33}
34
35} // namespace
36#endif // EON_PBC_SIMD_SCALAR_DEFINED
37
38#ifdef WITH_HIGHWAY
39
40#undef HWY_TARGET_INCLUDE
41#define HWY_TARGET_INCLUDE "client/PbcSimd.cpp"
42#include "hwy/foreach_target.h" // IWYU pragma: keep
43#include "hwy/highway.h"
44
45HWY_BEFORE_NAMESPACE();
46namespace eonc::pbc {
47namespace HWY_NAMESPACE {
48namespace hn = hwy::HWY_NAMESPACE;
49
50void wrapMinimumImage(double *HWY_RESTRICT data, size_t n) {
51 const hn::ScalableTag<double> d;
52 const size_t lanes = hn::Lanes(d);
53 const auto half = hn::Set(d, 0.5);
54 size_t i = 0;
55 if (lanes > 0) {
56 for (; i + lanes <= n; i += lanes) {
57 const auto v = hn::LoadU(d, data + i);
58 hn::StoreU(hn::Sub(v, hn::Floor(hn::Add(v, half))), d, data + i);
59 }
60 }
61 wrapMinimumImageScalar(data, i, n);
62}
63
64void wrapLegacyUnit(double *HWY_RESTRICT data, size_t n) {
65 const hn::ScalableTag<double> d;
66 const size_t lanes = hn::Lanes(d);
67 const auto one = hn::Set(d, 1.0);
68 size_t i = 0;
69 if (lanes > 0) {
70 for (; i + lanes <= n; i += lanes) {
71 const auto y = hn::Add(hn::LoadU(d, data + i), one);
72 hn::StoreU(hn::Sub(y, hn::Trunc(y)), d, data + i);
73 }
74 }
75 wrapLegacyUnitScalar(data, i, n);
76}
77
78} // namespace HWY_NAMESPACE
79} // namespace eonc::pbc
80HWY_AFTER_NAMESPACE();
81
82#if HWY_ONCE
83namespace eonc::pbc {
84
85HWY_EXPORT(wrapMinimumImage);
86HWY_EXPORT(wrapLegacyUnit);
87
88void wrapMinimumImage(double *data, size_t n) {
89 if (n == 0) {
90 return;
91 }
92 HWY_DYNAMIC_DISPATCH(wrapMinimumImage)(data, n);
93}
94
95void wrapLegacyUnit(double *data, size_t n) {
96 if (n == 0) {
97 return;
98 }
99 HWY_DYNAMIC_DISPATCH(wrapLegacyUnit)(data, n);
100}
101
102} // namespace eonc::pbc
103#endif // HWY_ONCE
104
105#else // !WITH_HIGHWAY
106
107namespace eonc::pbc {
108
109void wrapMinimumImage(double *data, size_t n) {
110 wrapMinimumImageScalar(data, 0, n);
111}
112
113void wrapLegacyUnit(double *data, size_t n) {
114 wrapLegacyUnitScalar(data, 0, n);
115}
116
117} // namespace eonc::pbc
118
119#endif // WITH_HIGHWAY
void wrapMinimumImage(double *data, size_t n)
Definition PbcSimd.cpp:109
void wrapLegacyUnit(double *data, size_t n)
Definition PbcSimd.cpp:113