forked from Mantevo/miniMD
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutil.h
More file actions
139 lines (126 loc) · 3.67 KB
/
Copy pathutil.h
File metadata and controls
139 lines (126 loc) · 3.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/* ----------------------------------------------------------------------
miniMD is a simple, parallel molecular dynamics (MD) code. miniMD is
an MD microapplication in the Mantevo project at Sandia National
Laboratories ( http://www.mantevo.org ). The primary
authors of miniMD are Steve Plimpton (sjplimp@sandia.gov), Paul Crozier
(pscrozi@sandia.gov) and Christian Trott (crtrott@sandia.gov).
Copyright (2008) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This library is free software; you
can redistribute it and/or modify it under the terms of the GNU Lesser
General Public License as published by the Free Software Foundation;
either version 3 of the License, or (at your option) any later
version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this software; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA. See also: http://www.gnu.org/licenses/lgpl.txt .
For questions, contact Paul S. Crozier (pscrozi@sandia.gov) or
Christian Trott (crtrott@sandia.gov).
Please read the accompanying README and LICENSE files.
---------------------------------------------------------------------- */
#ifndef UTIL_H
#define UTIL_H
#include <cstdarg>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#if PRECISION == 1
typedef uint32_t CAS_t;
#else
typedef uint64_t CAS_t;
#endif
#ifdef USE_OFFLOAD
#define atomic_add(fptr, x) \
{ \
volatile CAS_t *ptr = (CAS_t*) fptr; \
CAS_t expected, desired; \
do \
{ \
expected = *ptr; \
MMD_float expected_float = *fptr; \
MMD_float desired_float = expected_float + x; \
desired = *((CAS_t*) &desired_float); \
} while(not __sync_bool_compare_and_swap(ptr, expected, desired)); \
}
#else
#define atomic_add(fptr, x) \
{ \
_Pragma("omp atomic") \
*fptr += x; \
}
#endif
inline uint32_t log2_ceil(uint32_t N)
{
if(N == 0)
{
return 0;
}
const uint32_t allbut1 = __builtin_clzl(1);
const uint32_t lz = __builtin_clzl(N);
const uint32_t log2 = allbut1 - lz;
uint32_t cand = 1 << log2;
if(N > cand)
{
return log2 + 1;
}
return log2;
}
template <typename T>
void blelloch_excl_scan_target_inplace(T *data, int N)
{
const int levels = log2_ceil(N);
#ifndef USE_OFFLOAD
#pragma omp parallel
#endif
{
#ifdef USE_OFFLOAD
#pragma omp target teams distribute parallel for
#else
#pragma omp for
#endif
for(int i = 0; i < N - 1; i += 2)
{
data[i + 1] = data[i] + data[i + 1];
}
for(int l = 1; l < levels; ++l)
{
const int stride = 1 << (l + 1);
#ifdef USE_OFFLOAD
#pragma omp target teams distribute parallel for
#else
#pragma omp for
#endif
for(int i = stride - 1; i < N; i += stride)
{
data[i] = data[i - stride / 2] + data[i];
}
}
for(int l = levels - 2; l >= 0; --l)
{
const int stride = 1 << (l + 1);
#ifdef USE_OFFLOAD
#pragma omp target teams distribute parallel for
#else
#pragma omp for
#endif
for(int i = stride + stride / 2 - 1; i < N; i += stride)
{
data[i] = data[i - stride / 2] + data[i];
}
}
}
}
static void die(const char *format, ...)
{
va_list args;
va_start(args, format);
vfprintf(stderr, format, args);
va_end(args);
exit(EXIT_FAILURE);
}
#endif