FLImaging 7.8.25.3
BackendConv3D.h
1#pragma once
2
3#if _MSC_VER >= 1900 && defined(_M_X64)
4
5#include "BackendBase.h"
6#include "Parameters.h"
7#include <immintrin.h>
8
9namespace FLImaging
10{
11 namespace AI
12 {
13 template <typename T>
14 class FL_EXPORT CTensor;
15
16 template <typename T>
17 class FL_EXPORT CBackendConv3D : public CBackendBase<T>
18 {
19 public:
20 CBackendConv3D();
21 CBackendConv3D(const CBackendConv3D<T>& bc);
22 virtual ~CBackendConv3D();
23
24 virtual const CResult SetConvolutionParams(const CConvolution3DParameters& convParams);
25 virtual CConvolution3DParameters GetConvolutionParams();
26
27 virtual const CResult Forward(CTensor<T>* pTsrX, CTensor<T>* pTsrW, CTensor<T>* pTsrY, const std::vector<int64_t>& vctYShape);
28 virtual const CResult DerivativeImage(CTensor<T>* pTsrDy, CTensor<T>* pTsrW, CTensor<T>* pTsrDx, const std::vector<int64_t>& vctDxShape, bool bAddGradient);
29 virtual const CResult DerivativeKernel(CTensor<T>* pTsrDy, CTensor<T>* pTsrX, CTensor<T>* pTsrDw, const std::vector<int64_t>& vctDwShape, bool bAddGradient);
30
31 DeclareGetClassType();
32 SupportToDuplicateObjectWithoutCreateNewObject(CBackendConv3D<T>, *this);
33
34 protected:
35 virtual const CResult Forward_Direct(CTensor<T>* pTsrOperand, CTensor<T>* pTsrKernel, CTensor<T>* pTsrResult);
36 virtual const CResult DerivativeImage_Direct(CTensor<T>* pTsrDy, CTensor<T>* pTsrW, CTensor<T>* pTsrDx, bool bAddGradient);
37 virtual const CResult DerivativeKernel_Direct(CTensor<T>* pTsrDy, CTensor<T>* pTsrX, CTensor<T>* pTsrDw, bool bAddGradient);
38
39 protected:
40 CConvolution3DParameters m_conv3DParams;
41
42 private:
43 template <typename T>
44 struct AvxTemplate;
45
46 template <>
47 struct AvxTemplate<float>
48 {
49 using Vec = __m256;
50 static constexpr int32_t LANES = 8;
51
52 static inline Vec zero()
53 {
54 return _mm256_setzero_ps();
55 }
56
57 static inline Vec set1(float f32V)
58 {
59 return _mm256_set1_ps(f32V);
60 }
61
62 static inline Vec loadu(const float* pF32)
63 {
64 return _mm256_loadu_ps(pF32);
65 }
66
67 static inline void storeu(float* pF32, Vec vec)
68 {
69 _mm256_storeu_ps(pF32, vec);
70 }
71
72 static inline Vec fmadd(Vec vecA, Vec vecB, Vec vecC)
73 {
74 return _mm256_add_ps(vecC, _mm256_mul_ps(vecA, vecB));
75 }
76
77 static inline float hsum(Vec v)
78 {
79 alignas(32) float arrF32Buf[LANES];
80 _mm256_store_ps(arrF32Buf, v);
81 float f32Ret = 0.0f;
82
83 for(int i = 0; i < LANES; ++i)
84 f32Ret += arrF32Buf[i];
85
86 return f32Ret;
87 }
88 };
89
90 template <>
91 struct AvxTemplate<double>
92 {
93 using Vec = __m256d;
94 static constexpr int32_t LANES = 4;
95
96 static inline Vec zero()
97 {
98 return _mm256_setzero_pd();
99 }
100
101 static inline Vec set1(double f64V)
102 {
103 return _mm256_set1_pd(f64V);
104 }
105
106 static inline Vec loadu(const double* pF64)
107 {
108 return _mm256_loadu_pd(pF64);
109 }
110
111 static inline void storeu(double* pF64, Vec vec)
112 {
113 _mm256_storeu_pd(pF64, vec);
114 }
115
116 static inline Vec fmadd(Vec vecA, Vec vecB, Vec vecC)
117 {
118 return _mm256_add_pd(vecC, _mm256_mul_pd(vecA, vecB));
119 }
120
121 static inline double hsum(Vec v)
122 {
123 alignas(32) double arrF64Buf[LANES];
124 _mm256_store_pd(arrF64Buf, v);
125 double f64Ret = 0.0;
126
127 for(int i = 0; i < LANES; ++i)
128 f64Ret += arrF64Buf[i];
129
130 return f64Ret;
131 }
132 };
133 };
134 }
135}
136
137#endif
Definition AlgorithmAIBase.h:18