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