1 #include "bool.h"
2 #include "cpuid.h"
3 #include <errno.h>
4 #include <sys/stat.h>		/* For fstat */
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <strings.h>
8 #include <string.h>
9 #include <libgen.h>
10 #include <unistd.h>
11 
12 static bool
file_exists_p(char * filename)13 file_exists_p (char *filename) {
14   struct stat sb;
15 
16   if (stat(filename,&sb) == 0) {
17     return true;
18   } else {
19     return false;
20   }
21 }
22 
23 int
main(int argc,char * argv[])24 main (int argc, char *argv[]) {
25   bool sse2_support_p;
26   bool ssse3_support_p;
27   bool sse4_1_support_p;
28   bool sse4_2_support_p;
29   bool avx2_support_p;
30   bool avx512_support_p;
31   bool avx512bw_support_p;
32   char *dir, **new_argv;
33   int i;
34   int rc;
35 
36   CPUID_support(&sse2_support_p,&ssse3_support_p,&sse4_1_support_p,&sse4_2_support_p,
37 		&avx2_support_p,&avx512_support_p,&avx512bw_support_p);
38 
39   new_argv = (char **) malloc((argc + 1) * sizeof(char *));
40   for (i = 1; i < argc; i++) {
41     new_argv[i] = argv[i];
42   }
43   new_argv[argc] = (char *) NULL;
44 
45   if (index(argv[0],'/') == NULL) {
46     /* Depend on path */
47     /* Cannot use file_exists_p, since it won't search PATH */
48 
49     if (avx512bw_support_p == true) {
50       new_argv[0] = "gsnap.avx512bw";
51       if ((rc = execvp(new_argv[0],new_argv)) == -1 && errno == ENOENT) {
52 	fprintf(stderr,"Note: %s does not exist.  For faster speed, may want to compile package on an AVX512 (with BW) machine\n",new_argv[0]);
53       } else {
54 	free(new_argv);
55 	return rc;
56       }
57     }
58 
59     if (avx512_support_p == true) {
60       new_argv[0] = "gsnap.avx512";
61       if ((rc = execvp(new_argv[0],new_argv)) == -1 && errno == ENOENT) {
62 	fprintf(stderr,"Note: %s does not exist.  For faster speed, may want to compile package on an AVX512 machine\n",new_argv[0]);
63       } else {
64 	free(new_argv);
65 	return rc;
66       }
67     }
68 
69     if (avx2_support_p == true) {
70       new_argv[0] = "gsnap.avx2";
71       if ((rc = execvp(new_argv[0],new_argv)) == -1 && errno == ENOENT) {
72 	fprintf(stderr,"Note: %s does not exist.  For faster speed, may want to compile package on an AVX2 machine\n",new_argv[0]);
73       } else {
74 	free(new_argv);
75 	return rc;
76       }
77     }
78 
79     if (sse4_2_support_p == true) {
80       new_argv[0] = "gsnap.sse42";
81       if ((rc = execvp(new_argv[0],new_argv)) == -1 && errno == ENOENT) {
82 	fprintf(stderr,"Note: %s does not exist.  For faster speed, may want to compile package on an SSE4.2 machine\n",new_argv[0]);
83       } else {
84 	free(new_argv);
85 	return rc;
86       }
87     }
88 
89     if (sse4_1_support_p == true) {
90       new_argv[0] = "gsnap.sse41";
91       if ((rc = execvp(new_argv[0],new_argv)) == -1 && errno == ENOENT) {
92 	fprintf(stderr,"Note: %s does not exist.  For faster speed, may want to compile package on an SSE4.1 machine\n",new_argv[0]);
93       } else {
94 	free(new_argv);
95 	return rc;
96       }
97     }
98 
99     if (ssse3_support_p == true) {
100       new_argv[0] = "gsnap.ssse3";
101       if ((rc = execvp(new_argv[0],new_argv)) == -1 && errno == ENOENT) {
102 	fprintf(stderr,"Note: %s does not exist.  For faster speed, may want to compile package on an SSSE3 machine\n",new_argv[0]);
103       } else {
104 	free(new_argv);
105 	return rc;
106       }
107     }
108 
109     if (sse2_support_p == true) {
110       new_argv[0] = "gsnap.sse2";
111       if ((rc = execvp(new_argv[0],new_argv)) == -1 && errno == ENOENT) {
112 	fprintf(stderr,"Note: %s does not exist.  For faster speed, may want to compile package on an SSE2 machine\n",new_argv[0]);
113       } else {
114 	free(new_argv);
115 	return rc;
116       }
117     }
118 
119     if (true) {
120       new_argv[0] = "gsnap.nosimd";
121       rc = execvp(new_argv[0],new_argv);
122       free(new_argv);
123       return rc;
124     }
125 
126   } else {
127     dir = dirname(argv[0]);
128 
129     if (avx512bw_support_p == true) {
130       new_argv[0] = (char *) malloc((strlen(dir) + strlen("/") + strlen("gsnap.avx512bw") + 1) * sizeof(char));
131       sprintf(new_argv[0],"%s/gsnap.avx512bw",dir);
132       if (file_exists_p(new_argv[0]) == false) {
133 	fprintf(stderr,"Note: %s does not exist.  For faster speed, may want to compile package on an AVX512 (with BW) machine\n",new_argv[0]);
134 	free(new_argv[0]);
135       } else {
136 	rc = execvp(new_argv[0],new_argv);
137 	free(new_argv[0]);
138 	free(new_argv);
139 	return rc;
140       }
141     }
142 
143     if (avx512_support_p == true) {
144       new_argv[0] = (char *) malloc((strlen(dir) + strlen("/") + strlen("gsnap.avx512") + 1) * sizeof(char));
145       sprintf(new_argv[0],"%s/gsnap.avx512",dir);
146       if (file_exists_p(new_argv[0]) == false) {
147 	fprintf(stderr,"Note: %s does not exist.  For faster speed, may want to compile package on an AVX512 machine\n",new_argv[0]);
148 	free(new_argv[0]);
149       } else {
150 	rc = execvp(new_argv[0],new_argv);
151 	free(new_argv[0]);
152 	free(new_argv);
153 	return rc;
154       }
155     }
156 
157     if (avx2_support_p == true) {
158       new_argv[0] = (char *) malloc((strlen(dir) + strlen("/") + strlen("gsnap.avx2") + 1) * sizeof(char));
159       sprintf(new_argv[0],"%s/gsnap.avx2",dir);
160       if (file_exists_p(new_argv[0]) == false) {
161 	fprintf(stderr,"Note: %s does not exist.  For faster speed, may want to compile package on an AVX2 machine\n",new_argv[0]);
162 	free(new_argv[0]);
163       } else {
164 	rc = execvp(new_argv[0],new_argv);
165 	free(new_argv[0]);
166 	free(new_argv);
167 	return rc;
168       }
169     }
170 
171     if (sse4_2_support_p == true) {
172       new_argv[0] = (char *) malloc((strlen(dir) + strlen("/") + strlen("gsnap.sse42") + 1) * sizeof(char));
173       sprintf(new_argv[0],"%s/gsnap.sse42",dir);
174       if (file_exists_p(new_argv[0]) == false) {
175 	fprintf(stderr,"Note: %s does not exist.  For faster speed, may want to compile package on an SSE4.2 machine\n",new_argv[0]);
176 	free(new_argv[0]);
177       } else {
178 	rc = execvp(new_argv[0],new_argv);
179 	free(new_argv[0]);
180 	free(new_argv);
181 	return rc;
182       }
183     }
184 
185     if (sse4_1_support_p == true) {
186       new_argv[0] = (char *) malloc((strlen(dir) + strlen("/") + strlen("gsnap.sse41") + 1) * sizeof(char));
187       sprintf(new_argv[0],"%s/gsnap.sse41",dir);
188       if (file_exists_p(new_argv[0]) == false) {
189 	fprintf(stderr,"Note: %s does not exist.  For faster speed, may want to compile package on an SSE4.1 machine\n",new_argv[0]);
190 	free(new_argv[0]);
191       } else {
192 	rc = execvp(new_argv[0],new_argv);
193 	free(new_argv[0]);
194 	free(new_argv);
195 	return rc;
196       }
197     }
198 
199     if (ssse3_support_p == true) {
200       new_argv[0] = (char *) malloc((strlen(dir) + strlen("/") + strlen("gsnap.ssse3") + 1) * sizeof(char));
201       sprintf(new_argv[0],"%s/gsnap.ssse3",dir);
202       if (file_exists_p(new_argv[0]) == false) {
203 	fprintf(stderr,"Note: %s does not exist.  For faster speed, may want to compile package on an SSSE3 machine\n",new_argv[0]);
204 	free(new_argv[0]);
205       } else {
206 	rc = execvp(new_argv[0],new_argv);
207 	free(new_argv[0]);
208 	free(new_argv);
209 	return rc;
210       }
211     }
212 
213     if (sse2_support_p == true) {
214       new_argv[0] = (char *) malloc((strlen(dir) + strlen("/") + strlen("gsnap.sse2") + 1) * sizeof(char));
215       sprintf(new_argv[0],"%s/gsnap.sse2",dir);
216       if (file_exists_p(new_argv[0]) == false) {
217 	fprintf(stderr,"Note: %s does not exist.  For faster speed, may want to compile package on an SSE2 machine\n",new_argv[0]);
218 	free(new_argv[0]);
219       } else {
220 	rc = execvp(new_argv[0],new_argv);
221 	free(new_argv[0]);
222 	free(new_argv);
223 	return rc;
224       }
225     }
226 
227     if (true) {
228       new_argv[0] = (char *) malloc((strlen(dir) + strlen("/") + strlen("gsnap.nosimd") + 1) * sizeof(char));
229       sprintf(new_argv[0],"%s/gsnap.nosimd",dir);
230       if (file_exists_p(new_argv[0]) == false) {
231 	fprintf(stderr,"Note: %s does not exist.  For faster speed, may want to compile package on an non-SIMD machine\n",new_argv[0]);
232 	free(new_argv[0]);
233       } else {
234 	rc = execvp(new_argv[0],new_argv);
235 	free(new_argv[0]);
236 	free(new_argv);
237 	return rc;
238       }
239     }
240   }
241 
242   fprintf(stderr,"Error: appropriate GSNAP version not found\n");
243   free(new_argv);
244   return -1;
245 }
246 
247