static QUEUE_DATA * process_QueryCmd(HMMD_COMMAND *cmd, WORKER_ENV *env) { int i; int n; int status; char *p; char *name; char *desc; ESL_DSQ *dsq; QUEUE_DATA *query = NULL; if ((query = malloc(sizeof(QUEUE_DATA))) == NULL) LOG_FATAL_MSG("malloc", errno); memset(query, 0, sizeof(QUEUE_DATA)); /* avoid uninitialized bytes. remove this, if we ever serialize/deserialize structures properly */ printf("CMD: %d %d\n", cmd->hdr.command, cmd->srch.query_type); query->cmd_type = cmd->hdr.command; query->query_type = cmd->srch.query_type; query->dbx = cmd->srch.db_inx; query->inx = cmd->srch.inx; query->cnt = cmd->srch.cnt; query->sock = env->fd; query->cmd = NULL; p = cmd->srch.data; /* process search specific options */ status = process_searchopts(env->fd, p, &query->opts); if (status != eslOK) LOG_FATAL_MSG("esl_getopts_Create", status); query->hmm = NULL; query->seq = NULL; query->abc = esl_alphabet_Create(eslAMINO); /* check if we are processing a sequence or hmm */ if (cmd->srch.query_type == HMMD_SEQUENCE) { n = cmd->srch.query_length - 2; name = p + cmd->srch.opts_length; desc = name + strlen(name) + 1; dsq = (ESL_DSQ *) (desc + strlen(desc) + 1); query->seq = esl_sq_CreateDigitalFrom(query->abc, name, dsq, n, desc, NULL, NULL); } else { P7_HMM thmm; P7_HMM *hmm = p7_hmm_CreateShell(); /* allocate memory for the hmm and initialize */ p += cmd->srch.opts_length; memcpy(&thmm, p, sizeof(P7_HMM)); hmm->flags = thmm.flags; p7_hmm_CreateBody(hmm, cmd->srch.query_length, query->abc); p += sizeof(P7_HMM); /* initialize fields */ hmm->nseq = thmm.nseq; hmm->eff_nseq = thmm.eff_nseq; hmm->max_length = thmm.max_length; hmm->checksum = thmm.checksum; hmm->ctime = NULL; hmm->comlog = NULL; for (i = 0; i < p7_NCUTOFFS; i++) hmm->cutoff[i] = thmm.cutoff[i]; for (i = 0; i < p7_NEVPARAM; i++) hmm->evparam[i] = thmm.evparam[i]; for (i = 0; i < p7_MAXABET; i++) hmm->compo[i] = thmm.compo[i]; /* fill in the hmm pointers */ n = sizeof(float) * (hmm->M + 1) * p7H_NTRANSITIONS; memcpy(*hmm->t, p, n); p += n; n = sizeof(float) * (hmm->M + 1) * query->abc->K; memcpy(*hmm->mat, p, n); p += n; memcpy(*hmm->ins, p, n); p += n; if (thmm.name) { hmm->name = strdup(p); p += strlen(hmm->name) + 1; } if (thmm.acc) { hmm->acc = strdup(p); p += strlen(hmm->acc) + 1; } if (thmm.desc) { hmm->desc = strdup(p); p += strlen(hmm->desc) + 1; } n = hmm->M + 2; if (hmm->flags & p7H_RF) { memcpy(hmm->rf, p, n); p += n; } if (hmm->flags & p7H_MMASK) { memcpy(hmm->mm, p, n); p += n; } if (hmm->flags & p7H_CONS) { memcpy(hmm->consensus, p, n); p += n; } if (hmm->flags & p7H_CS) { memcpy(hmm->cs, p, n); p += n; } if (hmm->flags & p7H_CA) { memcpy(hmm->ca, p, n); p += n; } n = sizeof(int) * (hmm->M + 1); if (hmm->flags & p7H_MAP) { memcpy(hmm->map, p, n); p += n; } query->hmm = hmm; } return query; }
/* Function: p7_hmm_mpi_Unpack() * Synopsis: Unpacks one HMM from an MPI buffer. * * Purpose: Unpack one HMM from MPI packed buffer * <buf>, starting from position <*pos>, where the total length * of the buffer in bytes is <n>. The new HMM is allocated here. * * Caller may or may not already know what alphabet the HMM * is expected to be in. A reference to the current * alphabet is passed in <byp_abc>. If the alphabet is unknown, * pass <*byp_abc = NULL>, and when the HMM is received, an * appropriate new alphabet object is allocated and passed * back to the caller via <*byp_abc>. If the alphabet is * already known, <*byp_abc> is that alphabet, and the new * HMM's alphabet type is verified to agree with it. This * mechanism allows an application to let the first HMM * determine the alphabet type for the application, while * still keeping the alphabet under the application's scope * of control. * * Args: buf - MPI packed buffer to unpack * n - total length of <buf> in bytes * pos - current parsing/unpacking position in <buf> * comm - MPI communicator * byp_abc - BYPASS: <*byp_abc> == ESL_ALPHABET *> if known; * <*byp_abc> == NULL> if alphabet unknown; * ret_hmm - RETURN: ptr to newly allocated, unpacked profile * * Returns: <eslOK> on success. <*pos> is updated to the position of * the next element in <buf> to unpack (if any). <*ret_hmm> * contains a newly allocated HMM, which the caller is * responsible for free'ing. If <*byp_abc> was passed as * <NULL>, it now points to an <ESL_ALPHABET> object that * was allocated here; caller is responsible for free'ing * this. * * Returns <eslEINCOMPAT> if the HMM is in a different * alphabet than <*byp_abc> said to expect. In this case, * <*byp_abc> is unchanged, <*buf> and <*nalloc> may have been * changed, and <*ret_hmm> is <NULL>. * * Throws: <eslESYS> on an MPI call failure. <eslEMEM> on allocation failure. * In either case, <*ret_hmm> is <NULL>, and the state of <buf> * and <*pos> is undefined and should be considered to be corrupted. */ int p7_hmm_mpi_Unpack(char *buf, int n, int *pos, MPI_Comm comm, ESL_ALPHABET **byp_abc, P7_HMM **ret_hmm) { P7_HMM *hmm = NULL; ESL_ALPHABET *abc = NULL; int64_t offset; int M, K, atype; int status; /* Use the CreateShell/CreateBody interface, because that interface allocates our optional fields, using <flags> */ if (( hmm = p7_hmm_CreateShell() ) == NULL) { status = eslEMEM; goto ERROR; } /* First, unpack info that we need for HMM body allocation */ if (MPI_Unpack(buf, n, pos, &M, 1, MPI_INT, comm) != MPI_SUCCESS) ESL_XEXCEPTION(eslESYS, "mpi unpack failed"); if (MPI_Unpack(buf, n, pos, &(hmm->flags), 1, MPI_INT, comm) != MPI_SUCCESS) ESL_XEXCEPTION(eslESYS, "mpi unpack failed"); if (MPI_Unpack(buf, n, pos, &atype, 1, MPI_INT, comm) != MPI_SUCCESS) ESL_XEXCEPTION(eslESYS, "mpi unpack failed"); /* Set or verify the alphabet */ if (*byp_abc == NULL) { /* alphabet unknown. create new one */ if ( (abc = esl_alphabet_Create(atype)) == NULL) { status = eslEMEM; goto ERROR; } } else { /* already known: check it */ abc = *byp_abc; if (abc->type != atype){ status = eslEINCOMPAT; goto ERROR; } } K = abc->K; /* For convenience below. */ /* Allocate the HMM body */ if ((status = p7_hmm_CreateBody(hmm, M, abc)) != eslOK) goto ERROR; /* Unpack the rest of the HMM */ if (MPI_Unpack( buf, n, pos, hmm->t[0], p7H_NTRANSITIONS*(M+1), MPI_FLOAT, comm) != MPI_SUCCESS) ESL_XEXCEPTION(eslESYS, "mpi unpack failed"); if (MPI_Unpack( buf, n, pos, hmm->mat[0], K*(M+1), MPI_FLOAT, comm) != MPI_SUCCESS) ESL_XEXCEPTION(eslESYS, "mpi unpack failed"); if (MPI_Unpack( buf, n, pos, hmm->ins[0], K*(M+1), MPI_FLOAT, comm) != MPI_SUCCESS) ESL_XEXCEPTION(eslESYS, "mpi unpack failed"); if ((status = esl_mpi_UnpackOpt( buf, n, pos, (void**) &(hmm->name), NULL, MPI_CHAR, comm)) != eslOK) goto ERROR; if ((status = esl_mpi_UnpackOpt( buf, n, pos, (void**) &(hmm->acc), NULL, MPI_CHAR, comm)) != eslOK) goto ERROR; if ((status = esl_mpi_UnpackOpt( buf, n, pos, (void**) &(hmm->desc), NULL, MPI_CHAR, comm)) != eslOK) goto ERROR; if (hmm->flags & p7H_RF) { if (MPI_Unpack(buf, n, pos, hmm->rf, M+2, MPI_CHAR, comm) != MPI_SUCCESS) ESL_XEXCEPTION(eslESYS, "mpi unpack failed"); } if (hmm->flags & p7H_MMASK) { if (MPI_Unpack(buf, n, pos, hmm->mm, M+2, MPI_CHAR, comm) != MPI_SUCCESS) ESL_XEXCEPTION(eslESYS, "mpi unpack failed"); } if (hmm->flags & p7H_CONS) { if (MPI_Unpack(buf, n, pos, hmm->consensus, M+2, MPI_CHAR, comm) != MPI_SUCCESS) ESL_XEXCEPTION(eslESYS, "mpi unpack failed"); } if (hmm->flags & p7H_CS) { if (MPI_Unpack(buf, n, pos, hmm->cs, M+2, MPI_CHAR, comm) != MPI_SUCCESS) ESL_XEXCEPTION(eslESYS, "mpi unpack failed"); } if (hmm->flags & p7H_CA) { if (MPI_Unpack(buf, n, pos, hmm->ca, M+2, MPI_CHAR, comm) != MPI_SUCCESS) ESL_XEXCEPTION(eslESYS, "mpi unpack failed"); } if ((status = esl_mpi_UnpackOpt( buf, n, pos, (void**)&(hmm->comlog), NULL, MPI_CHAR, comm)) != eslOK) goto ERROR; if (MPI_Unpack( buf, n, pos, &(hmm->nseq), 1, MPI_INT, comm) != MPI_SUCCESS) ESL_XEXCEPTION(eslESYS, "mpi unpack failed"); if (MPI_Unpack( buf, n, pos, &(hmm->eff_nseq), 1, MPI_FLOAT, comm) != MPI_SUCCESS) ESL_XEXCEPTION(eslESYS, "mpi unpack failed"); if (MPI_Unpack( buf, n, pos, &(hmm->max_length), 1, MPI_FLOAT, comm) != MPI_SUCCESS) ESL_XEXCEPTION(eslESYS, "mpi unpack failed"); if ((status = esl_mpi_UnpackOpt( buf, n, pos, (void**) &(hmm->ctime), NULL, MPI_CHAR, comm)) != eslOK) goto ERROR; if (hmm->flags & p7H_MAP) { if (MPI_Unpack(buf, n, pos, hmm->map, M+1, MPI_INT, comm) != MPI_SUCCESS) ESL_XEXCEPTION(eslESYS, "mpi unpack failed"); } if (MPI_Unpack( buf, n, pos, &(hmm->checksum), 1, MPI_UINT32_T, comm) != MPI_SUCCESS) ESL_XEXCEPTION(eslESYS, "mpi unpack failed"); if (MPI_Unpack( buf, n, pos, hmm->evparam, p7_NEVPARAM, MPI_FLOAT, comm) != MPI_SUCCESS) ESL_XEXCEPTION(eslESYS, "mpi unpack failed"); if (MPI_Unpack( buf, n, pos, hmm->cutoff, p7_NCUTOFFS, MPI_FLOAT, comm) != MPI_SUCCESS) ESL_XEXCEPTION(eslESYS, "mpi unpack failed"); if (MPI_Unpack( buf, n, pos, hmm->compo, p7_MAXABET, MPI_FLOAT, comm) != MPI_SUCCESS) ESL_XEXCEPTION(eslESYS, "mpi unpack failed"); if (MPI_Unpack( buf, n, pos, &offset, 1, MPI_INT64_T, comm) != MPI_SUCCESS) ESL_XEXCEPTION(eslESYS, "mpi unpack failed"); hmm->offset = offset; /* receive as int64_t, then cast to off_t, which is probably int64_t (but not guaranteed) */ *byp_abc = abc; /* works even if caller provided *byp_abc, because then abc==*byp_abc already */ *ret_hmm = hmm; return eslOK; ERROR: if (hmm) p7_hmm_Destroy(hmm); if (abc && *byp_abc == NULL) esl_alphabet_Destroy(abc); *ret_hmm = NULL; return status; }