Discontinuous Galerkin Library
#include "dg/algorithm.h"
Loading...
Searching...
No Matches
fma.h
Go to the documentation of this file.
1#pragma once
2
3#include <cmath>
4#include <complex>
5#include <thrust/complex.h>
6
7namespace dg
8{
10namespace detail
11{
12// Making T0, T1, T2 different fixes problem that any of them may be const reference types
13// overload A in std::fma
14// for cuda all types must be equal?
15template<class T0, class T1, class T2, class = std::enable_if_t<std::is_floating_point_v<T2> >>
17auto dg_fma( T0 x, T1 y, T2 z)
18{
19 return fma( (T2)x, (T2)y, z);
20}
21// Integer multiplication
22template<class T0, class T1, class T2>
24std::enable_if_t< std::is_integral_v<T2>,decltype(T0()*T1()+T2())> dg_fma( T0 x, T1 y, T2 z)
25{
26 return x*y+z;
27}
29template<class T0, class T, class = std::enable_if_t<std::is_floating_point_v<T> >>
30std::complex<T> dg_fma( T0 x, std::complex<T> y, std::complex<T> z)
31{
32 return {
33 std::fma( (T)x, y.real(), z.real()),
34 std::fma( (T)x, y.imag(), z.imag())
35 };
36}
37template<class T0, class T1, class T, class = std::enable_if_t<std::is_floating_point_v<T> >>
38std::complex<T> dg_fma( T0 x, T1 y, std::complex<T> z)
39{
40 return {
41 std::fma( (T)x, (T)y, z.real()),
42 z.imag()
43 };
44}
45template<class T0, class T, class = std::enable_if_t<std::is_floating_point_v<T> >>
46std::complex<T> dg_fma( std::complex<T> x, T0 y, std::complex<T> z)
47{
48 return {
49 fma( x.real(), (T)y, z.real()),
50 fma( x.imag(), (T)y, z.imag())
51 };
52}
53template<class T, class = std::enable_if_t<std::is_floating_point_v<T> >>
54std::complex<T> dg_fma( std::complex<T> x, std::complex<T> y, std::complex<T> z)
55{
56 std::complex<T> out = {
57 std::fma( x.real(), y.real(), z.real()),
58 std::fma( x.real(), y.imag(), z.imag())
59 };
60 return {
61 std::fma( -x.imag(), y.imag(), out.real()),
62 std::fma( x.imag(), y.real(), out.imag())
63 };
64}
66template<class T0, class T1, class T, class = std::enable_if_t<std::is_floating_point_v<T> >>
68thrust::complex<T> dg_fma( T0 x, T1 y, thrust::complex<T> z)
69{
70 return {
71 std::fma( (T)x, (T)y, z.real()),
72 z.imag()
73 };
74}
75template<class T0, class T, class = std::enable_if_t<std::is_floating_point_v<T> >>
77thrust::complex<T> dg_fma( T0 x, thrust::complex<T> y, thrust::complex<T> z)
78{
79 return {
80 fma( (T)x, y.real(), z.real()),
81 fma( (T)x, y.imag(), z.imag())
82 };
83}
84template<class T0, class T, class = std::enable_if_t<std::is_floating_point_v<T> >>
86thrust::complex<T> dg_fma( thrust::complex<T> x, T0 y, thrust::complex<T> z)
87{
88 return {
89 fma( x.real(), (T)y, z.real()),
90 fma( x.imag(), (T)y, z.imag())
91 };
92}
93template<class T, class = std::enable_if_t<std::is_floating_point_v<T> >>
95thrust::complex<T> dg_fma( thrust::complex<T> x, thrust::complex<T> y, thrust::complex<T> z)
96{
97 thrust::complex<T> out = {
98 fma( x.real(), y.real(), z.real()),
99 fma( x.real(), y.imag(), z.imag())
100 };
101 return {
102 fma( -x.imag(), y.imag(), out.real()),
103 fma( x.imag(), y.real(), out.imag())
104 };
105}
106
107
108} // namespace detail
110} // namespace dg
@ z
z direction
@ y
y direction
@ x
x direction
#define DG_DEVICE
Expands to __host__ __device__ if compiled with nvcc else is empty.
Definition dg_doc.h:378
This is the namespace for all functions and classes defined and used by the discontinuous Galerkin li...