Ignore:
Timestamp:
Oct 25, 2017, 4:57:58 PM (19 months ago)
Author:
nmedfort
Message:

First stage of MultiBlockKernel? and pipeline restructuring

File:
1 edited

Legend:

Unmodified
Added
Removed
  • icGREP/icgrep-devel/icgrep/kernels/source_kernel.cpp

    r5694 r5706  
    2828/// MMAP SOURCE KERNEL
    2929
    30 void MMapSourceKernel::linkExternalMethods(const std::unique_ptr<kernel::KernelBuilder> & kb) {
    31     mFileSizeFunction = kb->LinkFunction("file_size", &file_size);
    32 }
    33 
    34 void MMapSourceKernel::generateInitializeMethod(const std::unique_ptr<KernelBuilder> & kb) {
     30Function * MMapSourceKernel::linkFileSizeMethod(const std::unique_ptr<kernel::KernelBuilder> & kb) {
     31    return kb->LinkFunction("file_size", &file_size);
     32}
     33
     34void MMapSourceKernel::generateInitializeMethod(Function * const fileSizeMethod, const unsigned codeUnitWidth, const std::unique_ptr<KernelBuilder> & kb) {
    3535    BasicBlock * const emptyFile = kb->CreateBasicBlock("EmptyFile");
    3636    BasicBlock * const nonEmptyFile = kb->CreateBasicBlock("NonEmptyFile");
    3737    BasicBlock * const exit = kb->CreateBasicBlock("Exit");
    3838    IntegerType * const sizeTy = kb->getSizeTy();
    39     assert (kb->getKernel() == this);
    4039    Value * const fd = kb->getScalarField("fileDescriptor");
    41     assert (mFileSizeFunction);
    42     Value * fileSize = kb->CreateCall(mFileSizeFunction, fd);
     40    assert (fileSizeMethod);
     41    Value * fileSize = kb->CreateCall(fileSizeMethod, fd);
    4342    fileSize = kb->CreateZExtOrTrunc(fileSize, sizeTy);
    44     if (mCodeUnitWidth > 8) {
    45         fileSize = kb->CreateUDiv(fileSize, kb->getSize(mCodeUnitWidth / 8));
     43    if (codeUnitWidth > 8) {
     44        fileSize = kb->CreateUDiv(fileSize, kb->getSize(codeUnitWidth / 8));
    4645    }
    4746    Value * const isEmpty = kb->CreateICmpEQ(fileSize, ConstantInt::getNullValue(fileSize->getType()));
     
    7473}
    7574
    76 void MMapSourceKernel::generateDoSegmentMethod(const std::unique_ptr<KernelBuilder> & kb) {
     75void MMapSourceKernel::generateDoSegmentMethod(const unsigned codeUnitWidth, const unsigned segmentBlocks, const std::unique_ptr<KernelBuilder> & kb) {
    7776
    7877    BasicBlock * dropPages = kb->CreateBasicBlock("dropPages");
     
    9089
    9190    // multiply the consumed count by the code unit size then mask off any partial pages
    92     if (mCodeUnitWidth > 8) {
    93         consumed = kb->CreateMul(consumed, ConstantInt::get(consumedTy, mCodeUnitWidth / 8));
     91    if (codeUnitWidth > 8) {
     92        consumed = kb->CreateMul(consumed, ConstantInt::get(consumedTy, codeUnitWidth / 8));
    9493    }
    9594    const auto pageSize = getpagesize();
     
    124123    // determine whether or not we've exhausted the file buffer
    125124    kb->SetInsertPoint(processSegment);
    126     ConstantInt * segmentItems = kb->getSize(mSegmentBlocks * kb->getBitBlockWidth());
     125    ConstantInt * segmentItems = kb->getSize(segmentBlocks * kb->getBitBlockWidth());
    127126    Value * const fileSize = kb->getScalarField("fileSize");
    128127    Value * const produced = kb->CreateAdd(kb->getProducedItemCount("sourceBuffer"), segmentItems);
    129128    Value * const lessThanFullSegment = kb->CreateICmpULT(fileSize, produced);
    130129    kb->CreateUnlikelyCondBr(lessThanFullSegment, setTermination, mmapSourceExit);
     130
    131131    kb->SetInsertPoint(setTermination);
    132 
    133132    kb->setTerminationSignal();
    134133    kb->CreateBr(mmapSourceExit);
     
    140139    itemsRead->addIncoming(fileSize, setTermination);
    141140    kb->setProducedItemCount("sourceBuffer", itemsRead);
    142 }
    143 
    144 void MMapSourceKernel::generateFinalizeMethod(const std::unique_ptr<KernelBuilder> & kb) {
     141
     142}
     143
     144void MMapSourceKernel::unmapSourceBuffer(const std::unique_ptr<KernelBuilder> & kb) {
    145145    kb->CreateMUnmap(kb->getBaseAddress("sourceBuffer"), kb->getBufferedSize("sourceBuffer"));
    146146}
     
    160160/// READ SOURCE KERNEL
    161161
    162 void ReadSourceKernel::generateInitializeMethod(const std::unique_ptr<KernelBuilder> & kb) {
    163     const size_t initialBufferSize = 8 * getpagesize() * mCodeUnitWidth;
    164     ConstantInt * const bufferBytes = kb->getSize(initialBufferSize * mCodeUnitWidth/8);
    165     PointerType * const codeUnitPtrTy = IntegerType::get(kb->getContext(), mCodeUnitWidth)->getPointerTo();
     162void ReadSourceKernel::generateInitializeMethod(const unsigned codeUnitWidth, const std::unique_ptr<KernelBuilder> & kb) {
     163    const size_t initialBufferSize = 8 * getpagesize() * codeUnitWidth;
     164    ConstantInt * const bufferBytes = kb->getSize(initialBufferSize * codeUnitWidth / 8);
     165    PointerType * const codeUnitPtrTy = IntegerType::get(kb->getContext(), codeUnitWidth)->getPointerTo();
    166166    Value * const buffer = kb->CreatePointerCast(kb->CreateCacheAlignedMalloc(bufferBytes), codeUnitPtrTy);
    167167    kb->setScalarField("buffer", buffer);
     
    172172}
    173173
    174 void ReadSourceKernel::generateDoSegmentMethod(const std::unique_ptr<KernelBuilder> & kb) {
    175 
    176     ConstantInt * const readSize = kb->getSize(getpagesize() * 8/mCodeUnitWidth);
    177     PointerType * const codeUnitPtrTy = IntegerType::get(kb->getContext(), mCodeUnitWidth)->getPointerTo();
     174void ReadSourceKernel::generateDoSegmentMethod(const unsigned codeUnitWidth, const unsigned segmentBlocks, const std::unique_ptr<KernelBuilder> & kb) {
     175
     176    ConstantInt * const readSize = kb->getSize(getpagesize() * 8/codeUnitWidth);
     177    PointerType * const codeUnitPtrTy = IntegerType::get(kb->getContext(), codeUnitWidth)->getPointerTo();
    178178    PointerType * const i8PtrTy = IntegerType::get(kb->getContext(), 8)->getPointerTo();
    179     ConstantInt * const codeUnitBytes = kb->getSize(mCodeUnitWidth/8);
     179    ConstantInt * const codeUnitBytes = kb->getSize(codeUnitWidth/8);
    180180    BasicBlock * const entryBlock = kb->GetInsertBlock();
    181181    BasicBlock * const exhaustedBuffer = kb->CreateBasicBlock("ExhaustedBuffer");
     
    184184    BasicBlock * const stdInExit = kb->CreateBasicBlock("StdInExit");
    185185
    186     assert(kb->getKernel() == this);
    187 
    188186    // Check whether we need to read another page of data
    189     ConstantInt * const segmentSize = kb->getSize(mSegmentBlocks * kb->getBitBlockWidth());
     187    ConstantInt * const segmentSize = kb->getSize(segmentBlocks * kb->getBitBlockWidth());
    190188    Value * bufferedSize = kb->getBufferedSize("sourceBuffer");
    191189    Value * const produced = kb->getProducedItemCount("sourceBuffer");
    192190    Value * unreadSize = kb->CreateSub(bufferedSize, produced);
     191
    193192    kb->CreateUnlikelyCondBr(kb->CreateICmpULT(unreadSize, segmentSize), exhaustedBuffer, stdInExit);
    194193
     
    207206    // If so, we can append to our existing buffer without impacting any subsequent kernel.
    208207
    209     Value * inputStream = kb->getRawOutputPointer("sourceBuffer", kb->getInt32(0), kb->getInt32(0));
     208    Value * inputStream = kb->getRawOutputPointer("sourceBuffer", kb->getInt32(0));
    210209    Value * const originalPtr = kb->CreateGEP(inputStream, produced);
    211210
     
    216215    Value * B = kb->CreateGEP(buffer, capacity);
    217216    Value * const canAppend = kb->CreateICmpULT(L, B);
     217
    218218    kb->CreateLikelyCondBr(canAppend, readData, waitOnConsumers);
    219219
     
    225225    // that our "unproduced" data must be block aligned.
    226226    const size_t blockAlignment = kb->getBitBlockWidth() / 8;
    227     Constant * const alignmentMask = kb->getSize(-(blockAlignment * 8 / mCodeUnitWidth));
     227    Constant * const alignmentMask = kb->getSize(-(blockAlignment * 8 / codeUnitWidth));
    228228    Value * const consumed = kb->CreateAnd(kb->getConsumedItemCount("sourceBuffer"), alignmentMask);
    229229    Value * const remaining = kb->CreateSub(bufferedSize, consumed);
     
    233233    Value * source = unconsumedPtr;
    234234    Value * toCopy = remaining;
    235     if (mCodeUnitWidth != 8) {
     235    if (codeUnitWidth != 8) {
    236236        source = kb->CreatePointerCast(unconsumedPtr, i8PtrTy);
    237237        toCopy = kb->CreateMul(remaining, codeUnitBytes);
     
    247247    kb->SetInsertPoint(copyBack);
    248248    // If so, just copy the data ...
    249     if (mCodeUnitWidth != 8) {
     249    if (codeUnitWidth != 8) {
    250250        target = kb->CreatePointerCast(buffer, i8PtrTy);
    251251    }
     
    256256    kb->SetInsertPoint(expandAndCopyBack);
    257257    Value * const expandedCapacity = kb->CreateShl(capacity, 1);
    258     Value * const expandedBytes = mCodeUnitWidth == 8 ? expandedCapacity : kb->CreateMul(expandedCapacity, codeUnitBytes);
     258    Value * const expandedBytes = codeUnitWidth == 8 ? expandedCapacity : kb->CreateMul(expandedCapacity, codeUnitBytes);
    259259    Value * const expandedBuffer = kb->CreatePointerCast(kb->CreateCacheAlignedMalloc(expandedBytes), codeUnitPtrTy);
    260     target = mCodeUnitWidth == 8 ? expandedBuffer : kb->CreatePointerCast(expandedBuffer, i8PtrTy);
     260    target = codeUnitWidth == 8 ? expandedBuffer : kb->CreatePointerCast(expandedBuffer, i8PtrTy);
    261261    kb->CreateMemCpy(target, source, toCopy, 1);
    262262    kb->CreateFree(buffer);
     
    284284    addr->addIncoming(originalPtr, exhaustedBuffer);
    285285    addr->addIncoming(modifiedPtr, calculateLogicalAddress);
    286     assert(kb->getKernel() == this);
    287286    Value * const fd = kb->getScalarField("fileDescriptor");
    288     Value * toRead = readSize;
    289     if (mCodeUnitWidth != 8) {
    290         toRead = kb->CreateMul(toRead, codeUnitBytes);
    291     }
    292     Value * bytesRead = kb->CreateReadCall(fd, addr, toRead);
    293     Value * itemsRead = bytesRead;
    294     if (mCodeUnitWidth != 8) {
    295         itemsRead = kb->CreateUDiv(bytesRead, codeUnitBytes);
     287
     288    Value * itemsRead = kb->CreateReadCall(fd, addr, readSize);
     289    if (codeUnitWidth != 8) {
     290        itemsRead = kb->CreateUDiv(itemsRead, codeUnitBytes);
    296291    }
    297292    unreadSize = kb->CreateAdd(unreadSize, itemsRead);
     
    306301    Value * bytesToZero = kb->CreateSub(segmentSize, unreadSize);
    307302    Value * unreadPtr = kb->CreateGEP(addr, unreadSize);
    308     bytesToZero = mCodeUnitWidth == 8 ? bytesToZero : kb->CreateMul(bytesToZero, codeUnitBytes);
    309     if (mCodeUnitWidth != 8) {
     303    bytesToZero = codeUnitWidth == 8 ? bytesToZero : kb->CreateMul(bytesToZero, codeUnitBytes);
     304    if (codeUnitWidth != 8) {
    310305        bytesToZero = kb->CreateMul(bytesToZero, codeUnitBytes);
    311306        unreadPtr = kb->CreatePointerCast(unreadPtr, i8PtrTy);
    312307    }
    313308    kb->CreateMemZero(unreadPtr, bytesToZero);
    314     kb->setTerminationSignal();
     309    kb->setCapacity("sourceBuffer", bufferedSize);
     310    kb->setTerminationSignal(kb->CreateICmpEQ(unreadSize, Constant::getNullValue(itemsRead->getType())));
    315311    kb->CreateBr(stdInExit);
    316312
     
    326322}
    327323
    328 void ReadSourceKernel::generateFinalizeMethod(const std::unique_ptr<KernelBuilder> & kb) {
     324void ReadSourceKernel::freeBuffer(const std::unique_ptr<KernelBuilder> & kb) {
    329325    kb->CreateFree(kb->getScalarField("buffer"));
    330326}
     
    342338}
    343339
    344 // Hybrid MMap/Read source kernel
    345    
     340/// Hybrid MMap/Read source kernel
     341
     342void FDSourceKernel::linkExternalMethods(const std::unique_ptr<kernel::KernelBuilder> & kb) {
     343    mFileSizeFunction = MMapSourceKernel::linkFileSizeMethod(kb);
     344}
     345
     346void FDSourceKernel::generateFinalizeMethod(const std::unique_ptr<KernelBuilder> & kb) {
     347    BasicBlock * finalizeRead = kb->CreateBasicBlock("finalizeRead");
     348    BasicBlock * finalizeMMap = kb->CreateBasicBlock("finalizeMMap");
     349    BasicBlock * finalizeDone = kb->CreateBasicBlock("finalizeDone");
     350    // if the fileDescriptor is 0, the file is stdin, use readSource kernel logic, otherwise use mmap logic.
     351    kb->CreateCondBr(kb->CreateICmpEQ(kb->getScalarField("fileDescriptor"), kb->getInt32(STDIN_FILENO)), finalizeRead, finalizeMMap);
     352    kb->SetInsertPoint(finalizeRead);
     353    ReadSourceKernel::freeBuffer(kb);
     354    kb->CreateBr(finalizeDone);
     355    kb->SetInsertPoint(finalizeMMap);
     356    MMapSourceKernel::unmapSourceBuffer(kb);
     357    kb->CreateBr(finalizeDone);
     358    kb->SetInsertPoint(finalizeDone);
     359}
     360
     361void FDSourceKernel::generateInitializeMethod(const std::unique_ptr<KernelBuilder> & kb) {
     362    BasicBlock * initializeRead = kb->CreateBasicBlock("initializeRead");
     363    BasicBlock * initializeMMap = kb->CreateBasicBlock("initializeMMap");
     364    BasicBlock * initializeDone = kb->CreateBasicBlock("initializeDone");
     365    // if the fileDescriptor is 0, the file is stdin, use readSource kernel logic, otherwise use MMap logic.
     366    kb->CreateCondBr(kb->CreateICmpEQ(kb->getScalarField("fileDescriptor"), kb->getInt32(STDIN_FILENO)), initializeRead, initializeMMap);
     367    kb->SetInsertPoint(initializeRead);
     368    ReadSourceKernel::generateInitializeMethod(mCodeUnitWidth, kb);
     369    kb->CreateBr(initializeDone);
     370    kb->SetInsertPoint(initializeMMap);
     371    MMapSourceKernel::generateInitializeMethod(mFileSizeFunction, mCodeUnitWidth, kb);
     372    kb->CreateBr(initializeDone);
     373    kb->SetInsertPoint(initializeDone);
     374}
     375
     376void FDSourceKernel::generateDoSegmentMethod(const std::unique_ptr<KernelBuilder> & kb) {
     377    BasicBlock * DoSegmentRead = kb->CreateBasicBlock("DoSegmentRead");
     378    BasicBlock * DoSegmentMMap = kb->CreateBasicBlock("DoSegmentMMap");
     379    BasicBlock * DoSegmentDone = kb->CreateBasicBlock("DoSegmentDone");
     380    // if the fileDescriptor is 0, the file is stdin, use readSource kernel logic, otherwise use MMap logic.
     381    kb->CreateCondBr(kb->CreateICmpEQ(kb->getScalarField("fileDescriptor"), kb->getInt32(STDIN_FILENO)), DoSegmentRead, DoSegmentMMap);
     382    kb->SetInsertPoint(DoSegmentRead);
     383    ReadSourceKernel::generateDoSegmentMethod(mCodeUnitWidth, mSegmentBlocks, kb);
     384    kb->CreateBr(DoSegmentDone);
     385    kb->SetInsertPoint(DoSegmentMMap);
     386    MMapSourceKernel::generateDoSegmentMethod(mCodeUnitWidth, mSegmentBlocks, kb);
     387    kb->CreateBr(DoSegmentDone);
     388    kb->SetInsertPoint(DoSegmentDone);
     389}
     390
    346391FDSourceKernel::FDSourceKernel(const std::unique_ptr<kernel::KernelBuilder> & kb, unsigned blocksPerSegment, unsigned codeUnitWidth)
    347392: SegmentOrientedKernel("FD_source" + std::to_string(blocksPerSegment) + "@" + std::to_string(codeUnitWidth)
     
    355400, mCodeUnitWidth(codeUnitWidth)
    356401, mFileSizeFunction(nullptr) {
    357    
    358 }
    359 
    360 void FDSourceKernel::generateFinalizeMethod(const std::unique_ptr<KernelBuilder> & kb) {
    361     BasicBlock * finalizeRead = kb->CreateBasicBlock("finalizeRead");
    362     BasicBlock * finalizeMMap = kb->CreateBasicBlock("finalizeMMap");
    363     BasicBlock * finalizeDone = kb->CreateBasicBlock("finalizeDone");
    364     // if the fileDescriptor is 0, the file is stdin, use readSource kernel logic, otherwise use mmap logic.
    365     kb->CreateCondBr(kb->CreateICmpEQ(kb->getScalarField("fileDescriptor"), kb->getInt32(STDIN_FILENO)), finalizeRead, finalizeMMap);
    366     kb->SetInsertPoint(finalizeRead);
    367     reinterpret_cast<ReadSourceKernel *>(this)->ReadSourceKernel::generateFinalizeMethod(kb);
    368     kb->CreateBr(finalizeDone);
    369     kb->SetInsertPoint(finalizeMMap);
    370     reinterpret_cast<MMapSourceKernel *>(this)->MMapSourceKernel::generateFinalizeMethod(kb);
    371     kb->CreateBr(finalizeDone);
    372     kb->SetInsertPoint(finalizeDone);
    373 }
    374 
    375 void FDSourceKernel::generateInitializeMethod(const std::unique_ptr<KernelBuilder> & kb) {
    376     BasicBlock * initializeRead = kb->CreateBasicBlock("initializeRead");
    377     BasicBlock * initializeMMap = kb->CreateBasicBlock("initializeMMap");
    378     BasicBlock * initializeDone = kb->CreateBasicBlock("initializeDone");
    379     // if the fileDescriptor is 0, the file is stdin, use readSource kernel logic, otherwise use MMap logic.
    380     kb->CreateCondBr(kb->CreateICmpEQ(kb->getScalarField("fileDescriptor"), kb->getInt32(STDIN_FILENO)), initializeRead, initializeMMap);
    381     kb->SetInsertPoint(initializeRead);
    382     reinterpret_cast<ReadSourceKernel *>(this)->ReadSourceKernel::generateInitializeMethod(kb);
    383     kb->CreateBr(initializeDone);
    384     kb->SetInsertPoint(initializeMMap);
    385     reinterpret_cast<MMapSourceKernel *>(this)->MMapSourceKernel::generateInitializeMethod(kb);
    386     kb->CreateBr(initializeDone);
    387     kb->SetInsertPoint(initializeDone);
    388 }
    389 
    390 void FDSourceKernel::generateDoSegmentMethod(const std::unique_ptr<KernelBuilder> & kb) {
    391     BasicBlock * DoSegmentRead = kb->CreateBasicBlock("DoSegmentRead");
    392     BasicBlock * DoSegmentMMap = kb->CreateBasicBlock("DoSegmentMMap");
    393     BasicBlock * DoSegmentDone = kb->CreateBasicBlock("DoSegmentDone");
    394     // if the fileDescriptor is 0, the file is stdin, use readSource kernel logic, otherwise use MMap logic.
    395     kb->CreateCondBr(kb->CreateICmpEQ(kb->getScalarField("fileDescriptor"), kb->getInt32(STDIN_FILENO)), DoSegmentRead, DoSegmentMMap);
    396     kb->SetInsertPoint(DoSegmentRead);
    397     reinterpret_cast<ReadSourceKernel *>(this)->ReadSourceKernel::generateDoSegmentMethod(kb);
    398     kb->CreateBr(DoSegmentDone);
    399     kb->SetInsertPoint(DoSegmentMMap);
    400     reinterpret_cast<MMapSourceKernel *>(this)->MMapSourceKernel::generateDoSegmentMethod(kb);
    401     kb->CreateBr(DoSegmentDone);
    402     kb->SetInsertPoint(DoSegmentDone);
    403 }
    404 
    405 
    406 void FDSourceKernel::linkExternalMethods(const std::unique_ptr<kernel::KernelBuilder> & kb) {
    407     mFileSizeFunction = kb->LinkFunction("file_size", &file_size);
    408 }
    409    
    410    
     402
     403}
     404
    411405/// MEMORY SOURCE KERNEL
    412406
Note: See TracChangeset for help on using the changeset viewer.