static void AdjustRegionH(struct region_h *rh, unsigned n) { for(;n;n--,rh++) { AdjustBuffer(&rh->offset,1,sizeof(rh->offset)); AdjustBuffer(&rh->nline,1,sizeof(rh->nline)); AdjustBuffer(&rh->sw,4,sizeof(rh->sw.x)); } }
static void AdjustLineH(struct line_h *lh, unsigned n) { for(;n;n--,lh++) { AdjustBuffer(&lh->offset,1,sizeof(lh->offset)); AdjustBuffer(&lh->npair,1,sizeof(lh->npair)); AdjustBuffer(&lh->left,2,sizeof(lh->left)); AdjustBuffer(&lh->sw,4,sizeof(lh->sw.x)); } }
status_t LinkSender::FlushCompleted(size_t newBufferSize) { // we need to hide the incomplete message so that it's not flushed int32 end = fCurrentEnd; int32 start = fCurrentStart; fCurrentEnd = fCurrentStart; status_t status = Flush(); if (status < B_OK) { fCurrentEnd = end; return status; } char *oldBuffer = NULL; status = AdjustBuffer(newBufferSize, &oldBuffer); if (status != B_OK) return status; // move the incomplete message to the start of the buffer fCurrentEnd = end - start; if (oldBuffer != fBuffer) { memcpy(fBuffer, oldBuffer + start, fCurrentEnd); free(oldBuffer); } else memmove(fBuffer, fBuffer + start, fCurrentEnd); return B_OK; }
status_t LinkSender::StartMessage(int32 code, size_t minSize) { // end previous message if (EndMessage() < B_OK) CancelMessage(); if (minSize > kMaxBufferSize - sizeof(message_header)) { // we will handle this case in Attach, using an area minSize = sizeof(area_id); } minSize += sizeof(message_header); // Eventually flush buffer to make space for the new message. // Note, we do not take the actual buffer size into account to not // delay the time between buffer flushes too much. if (fBufferSize > 0 && (minSize > SpaceLeft() || fCurrentStart >= kWatermark)) { status_t status = Flush(); if (status < B_OK) return status; } if (minSize > fBufferSize) { if (AdjustBuffer(minSize) != B_OK) return fCurrentStatus = B_NO_MEMORY; } message_header *header = (message_header *)(fBuffer + fCurrentStart); header->size = 0; // will be set later header->code = code; header->flags = 0; STRACE(("info: LinkSender buffered header %ld (%lx) [%lu %lu %lu].\n", code, code, header->size, header->code, header->flags)); fCurrentEnd += sizeof(message_header); return B_OK; }
// saves the read to the read archive void CReadWriter::SaveRead(const Mosaik::Read& mr) { // initialize unsigned char readNameLen = (unsigned char)mr.Name.Length(); unsigned short numMate1Bases = (unsigned short)mr.Mate1.Bases.Length(); unsigned short numMate2Bases = (unsigned short)mr.Mate2.Bases.Length(); // return if both mates are empty if((numMate1Bases == 0) && (numMate2Bases == 0)) return; mNumBases += numMate1Bases + numMate2Bases; bool isPairedEnd = false; if(numMate2Bases > 0) isPairedEnd = true; // calculate the entry size unsigned short entrySize = 2 * numMate1Bases + readNameLen + SIZEOF_SHORT + 2; if(isPairedEnd) entrySize += 2 * numMate2Bases + SIZEOF_SHORT; if(mIsSOLiD) { entrySize += SOLID_PREFIX_LENGTH; if(isPairedEnd) entrySize += SOLID_PREFIX_LENGTH; } // check the memory buffer if(mBufferPosition >= (mBufferLen - entrySize)) AdjustBuffer(); // ============================ // serialize data to our buffer // ============================ // no need to leave space for entry size unsigned int bufferOffset = mBufferPosition; // store the read type mBuffer[bufferOffset++] = (isPairedEnd ? 1 : 0); // store the read name mBuffer[bufferOffset++] = readNameLen; memcpy(mBuffer + bufferOffset, mr.Name.CData(), readNameLen); bufferOffset += readNameLen; // ============ // store mate 1 // ============ // sanity check if ( mr.Mate1.Bases.Length() != mr.Mate1.Qualities.Length() ) { printf("ERROR: The lengths of bases(%u) and qualities(%u) of Read (%s) didn't match.\n", mr.Mate1.Bases.Length(), mr.Mate1.Qualities.Length(), mr.Name.CData()); exit(1); } // store the read length memcpy(mBuffer + bufferOffset, (char*)&numMate1Bases, SIZEOF_SHORT); bufferOffset += SIZEOF_SHORT; // store the bases memcpy(mBuffer + bufferOffset, mr.Mate1.Bases.CData(), numMate1Bases); bufferOffset += numMate1Bases; if(mIsSOLiD) { memcpy(mBuffer + bufferOffset, mr.Mate1.SolidPrefixTransition, SOLID_PREFIX_LENGTH); bufferOffset += SOLID_PREFIX_LENGTH; } // store the qualities memcpy(mBuffer + bufferOffset, mr.Mate1.Qualities.CData(), numMate1Bases); bufferOffset += numMate1Bases; // ============ // store mate 2 // ============ if(isPairedEnd) { // sanity check if ( mr.Mate2.Bases.Length() != mr.Mate2.Qualities.Length() ) { printf("ERROR: The lengths of bases(%u) and qualities(%u) of Read (%s) didn't match.\n", mr.Mate2.Bases.Length(), mr.Mate2.Qualities.Length(), mr.Name.CData()); exit(1); } // store the read length memcpy(mBuffer + bufferOffset, (char*)&numMate2Bases, SIZEOF_SHORT); bufferOffset += SIZEOF_SHORT; // store the bases memcpy(mBuffer + bufferOffset, mr.Mate2.Bases.CData(), numMate2Bases); bufferOffset += numMate2Bases; if(mIsSOLiD) { memcpy(mBuffer + bufferOffset, mr.Mate2.SolidPrefixTransition, SOLID_PREFIX_LENGTH); bufferOffset += SOLID_PREFIX_LENGTH; } // store the qualities memcpy(mBuffer + bufferOffset, mr.Mate2.Qualities.CData(), numMate2Bases); bufferOffset += numMate2Bases; } // check the buffer if(bufferOffset >= mBufferLen) { cout << endl << "ERROR: Buffer overrun detected when saving read. Used " << bufferOffset << " bytes, but allocated " << mBufferLen << " bytes." << endl; exit(1); } // update the partition variables and buffer position mPartitionMembers++; mBufferPosition = bufferOffset; // flush the buffer if(mPartitionMembers >= mPartitionSize) WritePartition(); // increment the read counter mNumReads++; }
int main(int argc, char *argv[]) { /* ******************** Step 0: Get Host Names and IDs ******************** */ MPI_Init(&argc, &argv); /* starts MPI */ par.t0 = 0; Tstart(par.t0); MPI_Comm_rank(MPI_COMM_WORLD, &par.id); /* get current process id */ MPI_Comm_size(MPI_COMM_WORLD, &par.np); /* get number of processes */ MPI_Get_processor_name(par.proc_name, &par.namelength); Init(&par, &mat); /* ******************** Step 0: Set some init values ******************** */ if (par.id == 0) { if (argc == 4) { par.foutdir = argv[3]; } else { if (argc > 4 || argc < 2) { fprintf(stderr, "Wrong number of argument %d. ./matrix.ij ./vector.vec",argc); exit(1); } else par.foutdir = NULL; } par.fmat = argv[1]; par.fvec = argv[2]; par.fout = NULL; } else { par.fmat = par.fvec = par.fout = par.foutdir = NULL; }; if (par.id == 0) { printf("PID %6d: Proc %2d of %d, %s\n", par.PID, par.id, par.np, par.proc_name); } MPI_Barrier(MPI_COMM_WORLD); /* ******************** Step 1: Distribute the data ******************** */ if (par.id == 0) { Step1root(&par); } else { Step1other(&par); } AdjustBuffer(&par); CreateCSR(&par, &mat); // here, all nodes have local mat and vec in CSR form MPI_Barrier(MPI_COMM_WORLD); Tstart(par.t1); /* ******************** Step 2: Analyze non-zero entry******************** */ IndexCSC(&par, &mat); /* ******************** Step 3: Analyze non-zero entry******************** */ DeterminNonlocalb(&par, &mat); /* ******************** Step 4: Figure out which process needs which ******************** */ /* ******************** Step 5: Actual transfer the data ******************** */ if (par.id == 0) printf("Starting transferring the vector b at ID=0\n"); Tstart(par.t2); Tstart(par.t11); TransferVector(&par, &mat); Tstop(par.t11); /* ******************** Step 6: Computing local product ******************** */ Tstart(par.t13); if (par.id == 0) printf("Starting computation at ID=0\n"); ComputeOutput(&par, &mat); Tstop(par.t13); Tstop(par.t2); Tstop(par.t1); /* ******************** Step 7: Gather Data ******************** */ GatherOutput(&par, &mat); if (par.id == 0) { WriteOutput(&par, &mat); Tstop(par.t0); printf("\n======================================================\n"); printf("Overall time t0 (sec):\t%.8lf\n", par.t0); printf("Total time taken t1 (sec):$\t%.8lf\n", par.t1); printf("Time taken (step5&6) t2 (sec):$\t%.8lf\n", par.t2); printf("Time taken (fileio) t10 (sec):\t%.8lf\n", par.t10); printf("Transfer needed vec t11 (sec):\t%.8lf\n", par.t11); printf("Local computation t13 (sec):\t%.8lf\n", par.t13); printf("Write output file t12 (sec):\t%.8lf\n", par.t12); printf("======================================================\n"); } FinalFreeMemory(&par, &mat); MPI_Finalize(); return 0; }