thesis version
This commit is contained in:
76
examples/basic.cpp
Normal file
76
examples/basic.cpp
Normal file
@ -0,0 +1,76 @@
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
|
||||
#include <pfor/pfor.h>
|
||||
#include <pfor/traits.h>
|
||||
|
||||
std::size_t pfor::ParallelForParameters::nThreads = 16;
|
||||
|
||||
constexpr long n = 16;
|
||||
|
||||
template<std::size_t v>
|
||||
constexpr auto _ = pfor::ctv<v>;
|
||||
|
||||
#define OPERAND(T, ID) \
|
||||
T ID##_; \
|
||||
auto ID = pfor::Operand<T, class TID##ID>{ID##_}
|
||||
|
||||
template<typename T, std::size_t n>
|
||||
void printArray(std::array<T, n> const& array) {
|
||||
std::copy(std::begin(array), std::end(array), std::ostream_iterator<T>(std::cout, " "));
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
int main() {
|
||||
using TypeA = std::array<int, n+1>; OPERAND(TypeA, a);
|
||||
using TypeB = std::array<int, 2*n+1>; OPERAND(TypeB, b);
|
||||
using Type = std::array<int, n>; OPERAND(Type, c); OPERAND(Type, d);
|
||||
|
||||
std::generate_n(std::begin(a_), a_.size(), [i=0]() mutable { return i++; });
|
||||
std::generate_n(std::begin(b_), b_.size(), [i=0]() mutable { return n-i++; });
|
||||
std::generate_n(std::begin(c_), c_.size(), [i=0]() mutable { return 1+i++%3; });
|
||||
std::generate_n(std::begin(d_), d_.size(), [i=0]() mutable { return -i++; });
|
||||
|
||||
pfor::Index i;
|
||||
|
||||
{
|
||||
auto e = a[_<2>*i+_<1>] = a[_<2>*i];
|
||||
std::cout << "Is {a[2*i+1] = a[2*i]} parallelizable? " << std::boolalpha << parallelTest(pfor::Range{0,0}, e) << std::endl;
|
||||
}
|
||||
|
||||
{
|
||||
auto e = a[i*i] = a[i*i]+1;
|
||||
std::cout << "Is {a[i*i] = a[i*i]+1} parallelizable? " << std::boolalpha << parallelTest(pfor::Range{0,0}, e) << std::endl;
|
||||
}
|
||||
|
||||
{
|
||||
auto e = a[injective(i*i)] = a[injective(i*i)]+1;
|
||||
std::cout << "Is {a[injective(i*i)] = a[injective(i*i)]+1} parallelizable? " << std::boolalpha << parallelTest(pfor::Range{0,0}, e) << std::endl;
|
||||
}
|
||||
|
||||
{
|
||||
auto e = a[i+_<1>] = a[i];
|
||||
std::cout << "Is {a[i+1] = a[i]}(step=1) parallelizable? " << std::boolalpha << parallelTest(pfor::RangeCT<0,1>{0}, e) << std::endl;
|
||||
std::cout << "Is {a[i+1] = a[i]}(step=2) parallelizable? " << std::boolalpha << parallelTest(pfor::RangeCT<0,2>{0}, e) << std::endl;
|
||||
}
|
||||
|
||||
pfor::parallelFor<pfor::ForLoopThread>(pfor::Range{0, n},
|
||||
d[i] = (xpr(i)+1)*a[i+_<1>],
|
||||
b[_<2>*i+_<1>] = b[_<2>*i]
|
||||
);
|
||||
|
||||
pfor::parallelFor<pfor::ForLoopThread>(pfor::Range{0, static_cast<pfor::Range::ValueType>(std::sqrt(n))},
|
||||
c[injective(i*i)] = c[injective(i*i)] + i
|
||||
);
|
||||
|
||||
pfor::parallelFor<pfor::ForLoopThread>(pfor::RangeCT<0,2>{n},
|
||||
a[i+_<1>] = a[i]
|
||||
);
|
||||
|
||||
printArray(a_);
|
||||
printArray(b_);
|
||||
printArray(c_);
|
||||
printArray(d_);
|
||||
}
|
58
examples/gen.cpp
Normal file
58
examples/gen.cpp
Normal file
@ -0,0 +1,58 @@
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <sstream>
|
||||
|
||||
#include <pfor/pfor.h>
|
||||
|
||||
#define K 1
|
||||
|
||||
std::size_t pfor::ParallelForParameters::nThreads{1};
|
||||
|
||||
template<std::size_t n>
|
||||
constexpr auto _ = pfor::ctv<n>;
|
||||
|
||||
using T = int;
|
||||
|
||||
#define OPERAND(Type, name, size, filler) \
|
||||
Type * name##_ = new Type[size]; \
|
||||
{ \
|
||||
std::size_t i = 0; \
|
||||
std::generate_n(name##_, size, [&i]{ return filler; }); \
|
||||
} \
|
||||
auto name = pfor::Operand<Type*, class ID##name>(name##_);
|
||||
|
||||
void printer(std::size_t) {}
|
||||
|
||||
template<typename T, typename... Ts>
|
||||
void printer(std::size_t n, T &&array, Ts&&... arrays) {
|
||||
for(std::size_t i = 0; i < n; ++i)
|
||||
std::clog << std::forward<T>(array)[i] << ", ";
|
||||
std::clog << std::endl;
|
||||
printer(n, std::forward<Ts>(arrays)...);
|
||||
}
|
||||
|
||||
int main() {
|
||||
std::size_t const N = 1000000;
|
||||
|
||||
OPERAND(T, a0, N, i++);
|
||||
OPERAND(T, a1, N, i++);
|
||||
OPERAND(T, a2, N, i++);
|
||||
OPERAND(T, a3, N, i++);
|
||||
OPERAND(T, a4, N, i++);
|
||||
OPERAND(T, a5, N, i++);
|
||||
OPERAND(T, a6, N, i++);
|
||||
OPERAND(T, a7, N, i++);
|
||||
|
||||
for(std::size_t k = 0; k < K; ++k) {
|
||||
parallelFor(pfor::Range{0, N-1}, [&](pfor::Index i) {
|
||||
return
|
||||
a0[i] = a0[i+_<1>] + a1[i] * a2[i],
|
||||
a1[i] = a1[i+_<1>] + a2[i] * a3[i],
|
||||
a2[i] = a2[i+_<1>] + a3[i] * a4[i],
|
||||
a5[i] = a5[i+_<1>] + a6[i] * a7[i];
|
||||
});
|
||||
}
|
||||
|
||||
printer(N, a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_);
|
||||
}
|
74
examples/operand.cpp
Normal file
74
examples/operand.cpp
Normal file
@ -0,0 +1,74 @@
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
|
||||
#include <pfor/pfor.h>
|
||||
|
||||
#define N 10
|
||||
#define DELAY 10'000'000
|
||||
|
||||
#define WAIT(DELAY) \
|
||||
for(std::size_t i = 0; i < DELAY; ++i)
|
||||
|
||||
template<std::size_t n>
|
||||
constexpr auto _ = pfor::ctv<n>;
|
||||
|
||||
std::size_t pfor::ParallelForParameters::nThreads = 4;
|
||||
|
||||
/* slow operator+ */
|
||||
template<typename T = int>
|
||||
class Foo {
|
||||
T data;
|
||||
|
||||
public:
|
||||
Foo() = default;
|
||||
Foo(T const&data): data{data} {}
|
||||
|
||||
Foo &operator=(T const&data) {
|
||||
WAIT(DELAY);
|
||||
this->data = data;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Foo operator+(Foo const&o) {
|
||||
WAIT(DELAY);
|
||||
return Foo{data+o.data};
|
||||
}
|
||||
|
||||
operator T() const { return data; }
|
||||
};
|
||||
|
||||
int main() {
|
||||
Foo<> a[N+1], b[N], c[N], d[N];
|
||||
int t[N];
|
||||
|
||||
{ int i = 0; std::generate_n(std::begin(a), N+1, [&i]{ return N-(i++); }); }
|
||||
{ int i = 0; std::generate_n(std::begin(b), N, [&i]{ return i++; }); }
|
||||
{ std::generate_n(std::begin(c), N, []{ return 250; }); }
|
||||
{ int i = 0; std::generate_n(std::begin(d), N, [&i]{ return i++&1; }); }
|
||||
|
||||
pfor::parallelFor<pfor::ForLoopOMP>(pfor::Range{0, N-1},
|
||||
[
|
||||
a=pfor::Operand<Foo<>*, class IDa>(a),
|
||||
b=pfor::Operand<Foo<>*, class IDb>(b),
|
||||
c=pfor::Operand<Foo<>*, class IDc>(c),
|
||||
d=pfor::Operand<Foo<>*, class IDd>(d),
|
||||
t=pfor::expr::Constant<int*>(t)
|
||||
] (auto i) mutable {
|
||||
return (
|
||||
a[i] = b[i]+a[i+_<1>],
|
||||
c[i] = c[i]+c[i],
|
||||
b[i] = 3
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
std::copy(a, a+N, std::ostream_iterator<int>(std::cout, " "));
|
||||
std::cout << std::endl;
|
||||
std::copy(b, b+N, std::ostream_iterator<int>(std::cout, " "));
|
||||
std::cout << std::endl;
|
||||
std::copy(c, c+N, std::ostream_iterator<int>(std::cout, " "));
|
||||
std::cout << std::endl;
|
||||
std::copy(d, d+N, std::ostream_iterator<int>(std::cout, " "));
|
||||
std::cout << std::endl;
|
||||
}
|
47
examples/properties.cpp
Normal file
47
examples/properties.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
#include <iostream>
|
||||
#include <pfor/pfor.h>
|
||||
#include <pfor/traits.h>
|
||||
|
||||
int main() {
|
||||
std::array<int, 1> a;
|
||||
pfor::Operand<std::array<int, 1>, void> o{a};
|
||||
pfor::Index i;
|
||||
|
||||
auto strinc = strictinc(i*i);
|
||||
auto strdec = strictdec(i*i);
|
||||
|
||||
{
|
||||
auto e = o[strinc] = o[strinc]+1;
|
||||
std::cout << "strictly inc: " << std::boolalpha << parallelTest(pfor::Range{0,0}, e) << std::endl;
|
||||
}
|
||||
{
|
||||
auto ii = strinc + strinc;
|
||||
auto e = o[ii] = o[ii]+1;
|
||||
std::cout << "strictly inc + strictly inc: " << std::boolalpha << parallelTest(pfor::Range{0,0}, e) << std::endl;
|
||||
}
|
||||
{
|
||||
auto ii = strinc + strdec;
|
||||
auto e = o[ii] = o[ii]+1;
|
||||
std::cout << "strictly inc + strictly dec: " << std::boolalpha << parallelTest(pfor::Range{0,0}, e) << std::endl;
|
||||
}
|
||||
{
|
||||
auto ii = strdec + strinc;
|
||||
auto e = o[ii] = o[ii]+1;
|
||||
std::cout << "strictly dec + strictly inc: " << std::boolalpha << parallelTest(pfor::Range{0,0}, e) << std::endl;
|
||||
}
|
||||
{
|
||||
auto ii = strdec + strdec;
|
||||
auto e = o[ii] = o[ii]+1;
|
||||
std::cout << "strictly dec + strictly dec: " << std::boolalpha << parallelTest(pfor::Range{0,0}, e) << std::endl;
|
||||
}
|
||||
{
|
||||
auto ii = strinc - strdec;
|
||||
auto e = o[ii] = o[ii]+1;
|
||||
std::cout << "strictly inc - strictly dec: " << std::boolalpha << parallelTest(pfor::Range{0,0}, e) << std::endl;
|
||||
}
|
||||
{
|
||||
auto ii = strdec - strinc;
|
||||
auto e = o[ii] = o[ii]+1;
|
||||
std::cout << "strictly dec - strictly inc: " << std::boolalpha << parallelTest(pfor::Range{0,0}, e) << std::endl;
|
||||
}
|
||||
}
|
52
examples/seq.cpp
Normal file
52
examples/seq.cpp
Normal file
@ -0,0 +1,52 @@
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
|
||||
#include <pfor/pfor.h>
|
||||
|
||||
#define K 1
|
||||
|
||||
std::size_t pfor::ParallelForParameters::nThreads{1};
|
||||
|
||||
using T = int;
|
||||
|
||||
#define OPERAND(Type, name, n, size, filler) \
|
||||
Type * name##n##_ = new Type[size]; \
|
||||
{ \
|
||||
std::size_t i = 0; \
|
||||
std::generate_n(name##n##_, size, [&i]{ return filler; }); \
|
||||
}
|
||||
|
||||
void printer(std::size_t) {}
|
||||
|
||||
template<typename T, typename... Ts>
|
||||
void printer(std::size_t n, T &&array, Ts&&... arrays) {
|
||||
for(std::size_t i = 0; i < n; ++i)
|
||||
std::clog << std::forward<T>(array)[i] << ", ";
|
||||
std::clog << std::endl;
|
||||
printer(n, std::forward<Ts>(arrays)...);
|
||||
}
|
||||
|
||||
int main() {
|
||||
std::size_t const N = 1000000;
|
||||
|
||||
OPERAND(T, a, 0, N, i++);
|
||||
OPERAND(T, a, 1, N, i++);
|
||||
OPERAND(T, a, 2, N, i++);
|
||||
OPERAND(T, a, 3, N, i++);
|
||||
OPERAND(T, a, 4, N, i++);
|
||||
OPERAND(T, a, 5, N, i++);
|
||||
OPERAND(T, a, 6, N, i++);
|
||||
OPERAND(T, a, 7, N, i++);
|
||||
|
||||
for(std::size_t k = 0; k < K; ++k) {
|
||||
for(std::size_t i = 0; i < N-1; ++i) {
|
||||
a0_[i] = a0_[i+1] + a1_[i] * a2_[i];
|
||||
a1_[i] = a1_[i+1] + a2_[i] * a3_[i];
|
||||
a2_[i] = a2_[i+1] + a3_[i] * a4_[i];
|
||||
a5_[i] = a5_[i+1] + a6_[i] * a7_[i];
|
||||
}
|
||||
}
|
||||
|
||||
printer(N, a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_);
|
||||
}
|
27
examples/thesis.cpp
Normal file
27
examples/thesis.cpp
Normal file
@ -0,0 +1,27 @@
|
||||
#include <cstdio>
|
||||
#include <cmath>
|
||||
#include <pfor/pfor.h>
|
||||
|
||||
std::size_t pfor::ParallelForParameters::nThreads = 16;
|
||||
|
||||
constexpr long n = 16;
|
||||
|
||||
int main() {
|
||||
std::array<int, n> a_; pfor::Operand<decltype(a_), class IDa> a{a_};
|
||||
std::array<int, n> b_; pfor::Operand<decltype(b_), class IDb> b{b_};
|
||||
std::array<int, n> c_; pfor::Operand<decltype(c_), class IDc> c{c_};
|
||||
std::array<int, n> d_; pfor::Operand<decltype(d_), class IDd> d{d_};
|
||||
std::array<int, n> e_; pfor::Operand<decltype(e_), class IDe> e{e_};
|
||||
std::array<int, n> f_; pfor::Operand<decltype(f_), class IDf> f{f_};
|
||||
|
||||
auto pow = pfor::makeOperator<float(&)(float, float)>(std::pow);
|
||||
|
||||
pfor::Index i;
|
||||
pfor::parallelFor<pfor::ForLoopThread>(pfor::Range{0, static_cast<decltype(+n)>(std::sqrt(n))},
|
||||
a[i] = a[i] * b[i],
|
||||
c[i] = c[i+pfor::ctv<1>] - d[i],
|
||||
b[i] = b[i] + i,
|
||||
d[i] = pow(c[i], e[i]),
|
||||
f[injective(i*i)] = 2 * f[injective(i*i)]
|
||||
);
|
||||
}
|
48
examples/types.cpp
Normal file
48
examples/types.cpp
Normal file
@ -0,0 +1,48 @@
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
|
||||
#include <pfor/pfor.h>
|
||||
|
||||
#define N 10
|
||||
|
||||
template<typename..., typename... Ts>
|
||||
void printTypes(Ts...) {
|
||||
std::puts(__PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
int main() {
|
||||
int dummy[N+1];
|
||||
auto a = pfor::Operand<int*, class IDa>(dummy);
|
||||
auto b = pfor::Operand<int*, class IDb>(dummy);
|
||||
auto c = pfor::Operand<int*, class IDc>(dummy);
|
||||
auto d = pfor::Operand<int*, class IDd>(dummy);
|
||||
auto e = pfor::Operand<int*, class IDe>(dummy);
|
||||
auto f = pfor::Operand<int*, class IDf>(dummy);
|
||||
|
||||
pfor::Index i;
|
||||
auto expr =
|
||||
(
|
||||
a[i] = a[i] * b[i],
|
||||
c[i] = c[i+pfor::ctv<1>] + d[i],
|
||||
b[i] = b[i] + 1,
|
||||
d[i] = c[i]^e[i],
|
||||
f[i] = 2 * f[i]
|
||||
);
|
||||
|
||||
using CommaSplittedExpr = pfor::expr::SplitComma<decltype(expr)>;
|
||||
using ExprInfo = pfor::expr::ExpressionInfo<CommaSplittedExpr>;
|
||||
using Clusters = typename pfor::impl::ClustersGenImpl<pfor::Pack<>, ExprInfo>::type;
|
||||
using ClustersIds = pfor::ClustersExpressionIds<Clusters>;
|
||||
using Type = pfor::PackSort<pfor::ComparatorUIntPack, ClustersIds>;
|
||||
|
||||
printTypes(expr);
|
||||
std::puts("--");
|
||||
printTypes<CommaSplittedExpr>();
|
||||
std::puts("--");
|
||||
printTypes<ExprInfo>();
|
||||
std::puts("--");
|
||||
printTypes<Clusters>();
|
||||
std::puts("--");
|
||||
printTypes<Type>();
|
||||
}
|
33
examples/unrolling.cpp
Normal file
33
examples/unrolling.cpp
Normal file
@ -0,0 +1,33 @@
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
|
||||
#include <pfor/pfor.h>
|
||||
#include <pfor/traits.h>
|
||||
|
||||
constexpr long n = 10;
|
||||
|
||||
#define OPERAND(T, ID) \
|
||||
T ID##_; \
|
||||
auto ID = pfor::Operand<T, class TID##ID>{ID##_}
|
||||
|
||||
template<typename T, std::size_t n>
|
||||
void printArray(std::array<T, n> const& array) {
|
||||
std::copy(std::begin(array), std::end(array), std::ostream_iterator<T>(std::cout, " "));
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
int main() {
|
||||
using Type = std::array<int, n>;
|
||||
OPERAND(Type, a);
|
||||
|
||||
std::generate_n(std::begin(a_), n, [i=1]() mutable { return i++; });
|
||||
|
||||
pfor::Index i;
|
||||
|
||||
pfor::parallelFor<pfor::ForLoopUnrolling<4>::template Template>(pfor::Range{0, n},
|
||||
a[i] = 3*a[i]
|
||||
);
|
||||
|
||||
printArray(a_);
|
||||
}
|
56
examples/userops.cpp
Normal file
56
examples/userops.cpp
Normal file
@ -0,0 +1,56 @@
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
|
||||
#include <pfor/pfor.h>
|
||||
|
||||
constexpr long n = 10;
|
||||
|
||||
template<std::size_t n>
|
||||
constexpr auto _ = pfor::ctv<n>;
|
||||
|
||||
#define OPERAND(T, ID) \
|
||||
T ID##_; \
|
||||
auto ID = pfor::Operand<T, class TID##ID>{ID##_}
|
||||
|
||||
template<typename T, std::size_t n>
|
||||
void printArray(std::array<T, n> const& array) {
|
||||
std::copy(std::begin(array), std::end(array), std::ostream_iterator<T>(std::cout, " "));
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
inline static long long factorial(long long n) {
|
||||
long long r = 1;
|
||||
while(n > 1) r *= n--;
|
||||
return r;
|
||||
}
|
||||
|
||||
std::size_t pfor::ParallelForParameters::nThreads = 4;
|
||||
|
||||
int main() {
|
||||
using Type = std::array<int, n>;
|
||||
OPERAND(Type, a); OPERAND(Type, b); OPERAND(Type, c); OPERAND(Type, d);
|
||||
|
||||
std::generate_n(std::begin(a_), n, [i=0]() mutable { return i++; });
|
||||
std::generate_n(std::begin(b_), n, [i=0]() mutable { return n-i++; });
|
||||
std::generate_n(std::begin(c_), n, [i=0]() mutable { return i++%3; });
|
||||
std::generate_n(std::begin(d_), n, [i=0]() mutable { return -i++; });
|
||||
|
||||
pfor::Index i;
|
||||
|
||||
auto add3 = pfor::makeOperator([](auto a, auto b, auto c) { return a+b+c; });
|
||||
auto pow = pfor::makeOperator<float(&)(float, float)>(std::pow);
|
||||
auto factorial = pfor::makeOperator(::factorial);
|
||||
|
||||
pfor::parallelFor<pfor::ForLoopThread>(pfor::Range{0, n},
|
||||
a[i] = add3(a[i], c[i], c[i]),
|
||||
b[i] = pow(b[i], c[i]),
|
||||
d[i] = pow(factorial(-d[i]/2), xpr(i) % 4 + 1)
|
||||
);
|
||||
|
||||
printArray(a_);
|
||||
printArray(b_);
|
||||
printArray(c_);
|
||||
printArray(d_);
|
||||
}
|
Reference in New Issue
Block a user