1 #ifdef HAVE_CONFIG_H
2 #include "config.h"
3 #endif
4
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <math.h>
8
9 #include "ViennaRNA/utils/basic.h"
10 #include "ViennaRNA/utils/cpu.h"
11
12
13 typedef int (proto_fun_zip_reduce)(const int *a,
14 const int *b,
15 int size);
16
17
18 /*
19 #################################
20 # PRIVATE FUNCTION DECLARATIONS #
21 #################################
22 */
23 static int zip_add_min_dispatcher(const int *a,
24 const int *b,
25 int size);
26
27
28 static int
29 fun_zip_add_min_default(const int *e1,
30 const int *e2,
31 int count);
32
33
34 #if VRNA_WITH_SIMD_AVX512
35 int
36 vrna_fun_zip_add_min_avx512(const int *e1,
37 const int *e2,
38 int count);
39
40
41 #endif
42
43 #if VRNA_WITH_SIMD_SSE41
44 int
45 vrna_fun_zip_add_min_sse41(const int *e1,
46 const int *e2,
47 int count);
48
49
50 #endif
51
52
53 static proto_fun_zip_reduce *fun_zip_add_min = &zip_add_min_dispatcher;
54
55
56 /*
57 #################################
58 # BEGIN OF FUNCTION DEFINITIONS #
59 #################################
60 */
61 PUBLIC void
vrna_fun_dispatch_disable(void)62 vrna_fun_dispatch_disable(void)
63 {
64 fun_zip_add_min = &fun_zip_add_min_default;
65 }
66
67
68 PUBLIC void
vrna_fun_dispatch_enable(void)69 vrna_fun_dispatch_enable(void)
70 {
71 fun_zip_add_min = &zip_add_min_dispatcher;
72 }
73
74
75 PUBLIC int
vrna_fun_zip_add_min(const int * e1,const int * e2,int count)76 vrna_fun_zip_add_min(const int *e1,
77 const int *e2,
78 int count)
79 {
80 return (*fun_zip_add_min)(e1, e2, count);
81 }
82
83
84 /*
85 #################################
86 # STATIC helper functions below #
87 #################################
88 */
89
90 /* zip_add_min() dispatcher */
91 static int
zip_add_min_dispatcher(const int * a,const int * b,int size)92 zip_add_min_dispatcher(const int *a,
93 const int *b,
94 int size)
95 {
96 unsigned int features = vrna_cpu_simd_capabilities();
97
98 #if VRNA_WITH_SIMD_AVX512
99 if (features & VRNA_CPU_SIMD_AVX512F) {
100 fun_zip_add_min = &vrna_fun_zip_add_min_avx512;
101 goto exec_fun_zip_add_min;
102 }
103
104 #endif
105
106 #if VRNA_WITH_SIMD_SSE41
107 if (features & VRNA_CPU_SIMD_SSE41) {
108 fun_zip_add_min = &vrna_fun_zip_add_min_sse41;
109 goto exec_fun_zip_add_min;
110 }
111
112 #endif
113
114 fun_zip_add_min = &fun_zip_add_min_default;
115
116 exec_fun_zip_add_min:
117
118 return (*fun_zip_add_min)(a, b, size);
119 }
120
121
122 static int
fun_zip_add_min_default(const int * e1,const int * e2,int count)123 fun_zip_add_min_default(const int *e1,
124 const int *e2,
125 int count)
126 {
127 int i;
128 int decomp = INF;
129
130 for (i = 0; i < count; i++) {
131 if ((e1[i] != INF) && (e2[i] != INF)) {
132 const int en = e1[i] + e2[i];
133 decomp = MIN2(decomp, en);
134 }
135 }
136
137 return decomp;
138 }
139