swps3.c

Go to the documentation of this file.
00001 
00005 /*
00006  * Copyright (c) 2007-2008 ETH Zürich, Institute of Computational Science
00007  *
00008  * Permission is hereby granted, free of charge, to any person
00009  * obtaining a copy of this software and associated documentation
00010  * files (the "Software"), to deal in the Software without
00011  * restriction, including without limitation the rights to use,
00012  * copy, modify, merge, publish, distribute, sublicense, and/or sell
00013  * copies of the Software, and to permit persons to whom the
00014  * Software is furnished to do so, subject to the following
00015  * conditions:
00016  *
00017  * The above copyright notice and this permission notice shall be
00018  * included in all copies or substantial portions of the Software.
00019  *
00020  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00021  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
00022  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00023  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
00024  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
00025  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
00026  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
00027  * OTHER DEALINGS IN THE SOFTWARE.
00028  */
00029 
00030 #include "swps3.h"
00031 #include "matrix.h"
00032 #include "fasta.h"
00033 #include "DynProgr_scalar.h"
00034 #if defined(__SSE2__)
00035 #include "DynProgr_sse_byte.h"
00036 #include "DynProgr_sse_short.h"
00037 #endif
00038 #if defined(__ALTIVEC__)
00039 #include "DynProgr_altivec.h"
00040 #endif
00041 #if defined(__PS3)
00042 #include "DynProgr_PPU.h"
00043 #endif
00044 #include <stdio.h>
00045 #include <stdlib.h>
00046 #include <sys/types.h>
00047 #include <sys/wait.h>
00048 #include <sys/select.h>
00049 #include <unistd.h>
00050 #include <string.h>
00051 #include <assert.h>
00052 #include <float.h>
00053 
00054 static ssize_t write_all(int fd, const void *data, size_t len) {
00055         size_t sent = 0;
00056         while(sent < len) {
00057                 ssize_t res;
00058                 res = write(fd,(const int8_t*)data+sent,len-sent);
00059                 switch(res) {
00060                 case 0:
00061                         return sent;
00062                 case -1:
00063                         return -1;
00064                 default:
00065                         sent += res;
00066                 }
00067         }
00068         return sent;
00069 }
00070 
00071 static ssize_t read_all(int fd, void *buf, size_t len) {
00072         size_t recv = 0;
00073         while(recv < len) {
00074                 ssize_t res;
00075                 res = read(fd,(int8_t*)buf+recv,len-recv);
00076                 switch(res) {
00077                 case 0:
00078                         return recv;
00079                 case -1:
00080                         return -1;
00081                 default:
00082                         recv += res;
00083                 }
00084         }
00085         return recv;
00086 }
00087 
00088 int main( int argc, char * argv[] ){
00089         char * matrixFile = NULL, * queryFile = NULL, * dbFile = NULL;
00090         int i, queryLen;
00091         char * query;
00092 #if defined(__SSE2__)
00093         SWType type = SSE2;
00094 #elif defined(__PS3)
00095         SWType type = PS3;
00096 #elif defined(__ALTIVEC__)
00097         SWType type = ALTIVEC;
00098 #else
00099         SWType type = SCALAR;
00100 #endif
00101         Options options = {-12,-2,DBL_MAX};
00102         int qCount=0, dCount=0, qResidues=0, dResidues=0;
00103 #ifdef HAVE_SYSCONF_NPROCESSORS
00104         int threads = sysconf(_SC_NPROCESSORS_ONLN);
00105 #else
00106 #if defined(__PS3)
00107         int threads = 6;
00108 #else
00109         int threads = 1;
00110 #endif
00111 #endif
00112         SBMatrix matrix;
00113         FastaLib * queryLib;
00114         for ( i=1; i<argc; i++ ){
00115                 if (argv[i][0]=='-'){
00116                         switch( argv[i][1] ){
00117                                 case 'h':
00118                                         matrixFile = NULL;
00119                                         i = argc; break;
00120                                 case 's':
00121                                         type = SCALAR;
00122                                         break;
00123                                 case 't':
00124                                         options.threshold = atoi( argv[++i] );
00125                                         break;
00126                                 case 'i':
00127                                         options.gapOpen = atoi( argv[++i] );
00128                                         break;
00129                                 case 'e':
00130                                         options.gapExt = atoi( argv[++i] );
00131                                         break;
00132                                 case 'j':
00133                                         threads = atoi( argv[++i] );
00134                                         break;
00135                                 default:
00136                                         matrixFile = NULL;
00137                                         i = argc; break;
00138                         }
00139                 }else{
00140                         if (matrixFile == NULL)
00141                                 matrixFile = argv[i];
00142                         else if (queryFile == NULL)
00143                                 queryFile = argv[i];
00144                         else if (dbFile == NULL)
00145                                 dbFile = argv[i];
00146                         else{
00147                                 matrixFile = NULL;
00148                                 i = argc; break;
00149                         }
00150                 }
00151         }
00152         if ( matrixFile == NULL || queryFile == NULL || dbFile == NULL ){
00153                 printf( "Usage: %s [-h] [-s] [-j num] [-i num] [-e num] [-t num] matrix query db\n", argv[0] );
00154                 return 0;
00155         }
00156         matrix   = swps3_readSBMatrix( matrixFile );
00157         queryLib = swps3_openLib( queryFile );
00158         while ( (query=swps3_readNextSequence( queryLib, &queryLen )) ){
00159                 double score = 0;
00160                 int *pipes_read;
00161                 int *pipes_write;
00162                 char **seq_names;
00163                 pid_t *children;
00164                 int child_id = -1;
00165                 int childpipe_read = -1;
00166                 int childpipe_write = -1;
00167                 FastaLib * dbLib = swps3_openLib( dbFile );
00168 #if defined(__SSE2__)
00169                 ProfileByte  * profileByte = swps3_createProfileByteSSE( query, queryLen, matrix );
00170                 ProfileShort * profileShort = swps3_createProfileShortSSE( query, queryLen, matrix );
00171 #endif
00172 #if defined(__PS3)
00173                 SPEProfile * profileByte = swps3_createProfileBytePPU(query, queryLen, matrix, MAX_SEQ_LENGTH);
00174                 SPEProfile * profileShort = swps3_createProfileShortPPU(query, queryLen, matrix, MAX_SEQ_LENGTH);
00175                 SPEProfile * profileFloat = swps3_createProfileFloatPPU(query, queryLen, matrix, MAX_SEQ_LENGTH);
00176                 /* by default byte profile will be loaded */
00177                 int current_profile_is_byte = 0;
00178                 /* loadProfileByte(profileByte, MAX_SEQ_LENGTH, &options);*/
00179 #endif
00180 #if defined(__ALTIVEC__)
00181                 void *profileByteAltivec = swps3_createProfileByteAltivec(query, queryLen, matrix);
00182                 void *profileShortAltivec = swps3_createProfileShortAltivec(query, queryLen, matrix);
00183                 void *profileFloatAltivec = swps3_createProfileFloatAltivec(query, queryLen, matrix);
00184 #endif
00185                 pipes_read = malloc(threads*sizeof(*pipes_read));
00186                 pipes_write = malloc(threads*sizeof(*pipes_write));
00187                 children = malloc(threads*sizeof(*children));
00188                 seq_names = malloc(threads*sizeof(*seq_names));
00189                 for(i=0;i<threads;++i) {
00190                         pipes_read[i]=-1;
00191                         pipes_write[i]=-1;
00192                         children[i]=-1;
00193                         seq_names[i]=malloc((MAX_SEQ_NAME_LENGTH+1)*sizeof(char));
00194                         seq_names[i][MAX_SEQ_NAME_LENGTH]='\0';
00195                 }
00196 
00197                 qCount++; qResidues+=queryLen;
00198                 dCount=dResidues=0;
00199 
00200                 if(threads>1) {
00201                         for(i=0; i<threads; ++i) {
00202                                 int fds[2];
00203                                 int res;
00204                                 char *db;
00205                                 int dbLen;
00206 
00207                                 db=swps3_readNextSequence( dbLib, &dbLen);
00208                                 strncpy(seq_names[i],swps3_getSequenceName(dbLib),MAX_SEQ_NAME_LENGTH);
00209 
00210                                 if(db == NULL) break;
00211 
00212                                 dResidues+=dbLen;
00213 
00214                                 res = pipe(fds);
00215                                 if(res < 0) {
00216                                         perror("error during pipe()");
00217                                         exit(1);
00218                                 }
00219                                 pipes_read[i] = fds[0];
00220                                 childpipe_write = fds[1];
00221 
00222                                 res = pipe(fds);
00223                                 if(res < 0) {
00224                                         perror("error during pipe()");
00225                                         exit(1);
00226                                 }
00227                                 pipes_write[i] = fds[1];
00228                                 childpipe_read = fds[0];
00229 
00230                                 children[i] = fork();
00231                                 if(children[i] < 0) {
00232                                         perror("error during fork()");
00233                                         exit(1);
00234                                 } else if(children[i] == 0) {
00235                                         int j;
00236                                         for(j=0; j<=i; ++j) {
00237                                                 close(pipes_read[j]);
00238                                                 close(pipes_write[j]);
00239                                                 pipes_read[j] = -1;
00240                                                 pipes_write[j] = -1;
00241                                         }
00242                                         child_id = i;
00243 
00244                                         break;
00245                                 } else {
00246                                         ssize_t sres;
00247 
00248                                         close(childpipe_read);
00249                                         close(childpipe_write);
00250                                         childpipe_read = -1;
00251                                         childpipe_write = -1;
00252 
00253                                         sres = write_all(pipes_write[i],&dbLen,sizeof(int));
00254                                         if(sres != sizeof(int)) {
00255                                                 perror("error during write()");
00256                                                 exit(1);
00257                                         }
00258                                         sres = write_all(pipes_write[i],db,dbLen);
00259                                         if(sres != dbLen) {
00260                                                 perror("error during write()");
00261                                                 exit(1);
00262                                         }
00263                                 }
00264                         }
00265                 } else {
00266                         childpipe_read = -1;
00267                         childpipe_write = -1;
00268                         child_id = 0;
00269                 }
00270 
00271                 do {
00272                         int dbLen;
00273                         char * db;
00274                         char * dbName;
00275 
00276                         if(childpipe_read <= 0) {
00277                                 db = swps3_readNextSequence( dbLib, &dbLen);
00278                                 dbName = swps3_getSequenceName(dbLib);
00279                         } else {
00280                                 static char buffer[MAX_SEQ_LENGTH] __ALIGNED__;
00281                                 ssize_t res;
00282 
00283                                 db = buffer;
00284 
00285                                 res = read_all(childpipe_read,&dbLen,sizeof(int));
00286                                 if(res != sizeof(int)) {
00287                                         if(res == 0) exit(0);
00288                                         perror("error during read()");
00289                                         exit(1);
00290                                 }
00291                                 res = read_all(childpipe_read,db,dbLen);
00292                                 if(res != dbLen) {
00293                                         perror("error during read()");
00294                                         exit(1);
00295                                 }
00296                                 dbName = seq_names[child_id];
00297                         }
00298 
00299                         if(child_id == -1) {
00300                                 fd_set readfds;
00301                                 int max_fd = -1;
00302                                 int i;
00303                                 int res;
00304 
00305                                 FD_ZERO(&readfds);
00306 
00307                                 for(i=0; i<threads; ++i) {
00308                                         if(pipes_read[i] > 0) FD_SET(pipes_read[i],&readfds);
00309                                         if(pipes_read[i]>max_fd) max_fd = pipes_read[i];
00310                                 }
00311 
00312                                 /* all children exited */
00313                                 if(max_fd == -1) break;
00314 
00315                                 res = select(max_fd+1, &readfds, NULL, NULL, NULL);
00316                                 if(res <= 0) {
00317                                         perror("error during select()");
00318                                         exit(1);
00319                                 }
00320                                 for(i=0; i<threads; ++i) {
00321                                         if(pipes_read[i] > 0 && FD_ISSET(pipes_read[i],&readfds)) {
00322                                                 static char tmpbuff[MAX_SEQ_NAME_LENGTH+1];
00323                                                 char *newName;
00324                                                 res = read_all(pipes_read[i],&score,sizeof(score));
00325                                                 if(res != sizeof(score)) {
00326                                                         perror("error during read()");
00327                                                         exit(1);
00328                                                 }
00329 
00330                                                 newName = dbName;
00331                                                 strncpy(tmpbuff,seq_names[i],MAX_SEQ_NAME_LENGTH);
00332                                                 dbName = tmpbuff;
00333 
00334                                                 if(db) {
00335                                                         strncpy(seq_names[i],newName,MAX_SEQ_NAME_LENGTH);
00336 
00337                                                         res = write_all(pipes_write[i],&dbLen,sizeof(int));
00338                                                         if(res != sizeof(int)) {
00339                                                                 perror("error during write()");
00340                                                                 exit(1);
00341                                                         }
00342                                                         res = write_all(pipes_write[i],db,dbLen);
00343                                                         if(res != dbLen) {
00344                                                                 perror("error during write()");
00345                                                                 exit(1);
00346                                                         }
00347                                                 } else {
00348                                                         close(pipes_write[i]);
00349                                                         close(pipes_read[i]);
00350                                                         pipes_write[i] = -1;
00351                                                         pipes_read[i] = -1;
00352                                                         free(seq_names[i]);
00353                                                         seq_names[i] = NULL;
00354                                                         waitpid(children[i],NULL,0);
00355                                                         children[i] = -1;
00356                                                 }
00357                                                 break;
00358                                         }
00359                                 }
00360                         } else {
00361                                 if(db == NULL) break;
00362 
00363 #ifdef DEBUG
00364                                 for(i=0; i<queryLen; ++i) printf("\t%c",query[i]);
00365                                 printf("\n");
00366 #endif
00367 
00368 #if defined(__SSE2__)
00369                                 if(type == SSE2) {
00370                                         if( (score = swps3_alignmentByteSSE( profileByte, db, dbLen, &options )) >= DBL_MAX ) {
00371                                                 score = swps3_alignmentShortSSE( profileShort, db, dbLen, &options );
00372                                                 assert(score >= 250 && "score too low");
00373                                         }
00374                                 }
00375 #endif
00376 #if defined(__PS3)
00377                                 if(type == PS3) {
00378 #if defined(__ALTIVEC__)
00379                                         if(child_id == 6) {
00380 #if 0
00381                                                 score = swps3_dynProgrFloatAltivec(db, dbLen, profileFloatAltivec, &options);
00382 #else
00383                                                 score = swps3_dynProgrByteAltivec(db, dbLen, profileByteAltivec, &options);
00384                                                 if(score >= DBL_MAX)
00385                                                         score = swps3_dynProgrShortAltivec(db, dbLen, profileShortAltivec, &options);
00386 #endif
00387                                         } else {
00388 #endif /* __ALTIVEC__ */
00389 #if 0
00390                                                 loadProfileFloat(profileFloat, MAX_SEQ_LENGTH, &options);
00391                                                 score = alignmentProfileSPE( db, dbLen );
00392 #elif 1
00393                                                 if(!current_profile_is_byte) swps3_loadProfileByte(profileByte, MAX_SEQ_LENGTH, &options);
00394                                                 current_profile_is_byte = 1;
00395                                                 score = swps3_alignmentProfileSPE( db, dbLen );
00396                                                 if( score >= DBL_MAX ) {
00397                                                         if(current_profile_is_byte) swps3_loadProfileShort(profileShort, MAX_SEQ_LENGTH, &options);
00398                                                         current_profile_is_byte = 0;
00399                                                         score = swps3_alignmentProfileSPE( db, dbLen );
00400                                                 }
00401 #elif 1
00402                                                 if(!current_profile_is_byte) swps3_loadProfileShort(profileShort, MAX_SEQ_LENGTH, &options);
00403                                                 current_profile_is_byte = 1;
00404                                                 score = swps3_alignmentProfileSPE( db, dbLen );
00405 #else
00406                                                 score = swps3_alignmentByteSPE( matrix, query, queryLen, db, dbLen, &options );
00407                                                 if( score >= DBL_MAX ) {
00408                                                         score = swps3_alignmentShortSPE( matrix, query, queryLen, db, dbLen, &options );
00409                                                 }
00410 #endif
00411 #if defined(__ALTIVEC__)
00412                                         }
00413 #endif /* __ALTIVEC__ */
00414                                 }
00415 #endif /* __PS3 */
00416 #if defined(__ALTIVEC__)
00417                                 if(type == ALTIVEC) {
00418 #if 0
00419                                         score = swps3_dynProgrFloatAltivec(db, dbLen, profileFloatAltivec, &options);
00420 #else
00421                                         score = swps3_dynProgrByteAltivec(db, dbLen, profileByteAltivec, &options);
00422                                         if(score >= DBL_MAX)
00423                                                 score = swps3_dynProgrShortAltivec(db, dbLen, profileShortAltivec, &options);
00424                                 }
00425 #endif
00426 #endif /* __ALTIVEC__ */
00427                                 if(type == SCALAR) {
00428                                         double dmatrix[MATRIX_DIM*MATRIX_DIM];
00429                                         for(i=0;i<MATRIX_DIM*MATRIX_DIM;++i) dmatrix[i]=matrix[i];
00430                                         score = swps3_alignScalar( dmatrix, query, queryLen, db, dbLen, &options);
00431                                 }
00432                         }
00433 
00434                         if(childpipe_write > 0) {
00435                                 ssize_t res;
00436 
00437                                 res = write_all(childpipe_write,&score,sizeof(score));
00438                                 if(res != sizeof(score)) {
00439                                         perror("error during write()");
00440                                         exit(1);
00441                                 }
00442                         } else {
00443                                 if(score >= options.threshold) {
00444                                         printf(">threshold\t%s\n",dbName);
00445                                 } else {
00446                                         printf("%g\t%s\n",score,dbName);
00447                                 }
00448                         }
00449 
00450                         dCount++; dResidues+=dbLen;
00451                 } while(1);
00452 
00453                 free(pipes_read);
00454                 free(pipes_write);
00455                 free(children);
00456                 free(seq_names);
00457 
00458 #if defined(__SSE2__)
00459                 swps3_freeProfileByteSSE( profileByte );
00460                 swps3_freeProfileShortSSE( profileShort );
00461 #endif
00462 #if defined(__PS3)
00463                 swps3_freeProfilePPU( profileByte );
00464                 swps3_freeProfilePPU( profileShort );
00465                 swps3_freeProfilePPU( profileFloat );
00466 #endif
00467                 swps3_closeLib( dbLib );
00468         }
00469         fprintf(stderr,"%d[%d] x %d[%d]\n", qCount, qResidues, dCount, dResidues );
00470 
00471         swps3_closeLib( queryLib );
00472         return 0;
00473 }

Generated on Thu Jun 5 12:44:37 2008 for swps3 by  doxygen 1.5.4