Changeset 5761 for icGREP/icgrep-devel


Ignore:
Timestamp:
Dec 8, 2017, 1:55:22 AM (19 months ago)
Author:
nmedfort
Message:

Cache signature is now written into .kernel bitcode file. Minor bug fix and revision of GrepEngine::DoGrepThreadMethod?

Location:
icGREP/icgrep-devel/icgrep
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • icGREP/icgrep-devel/icgrep/IR_Gen/CBuilder.cpp

    r5757 r5761  
    966966#endif
    967967
    968 void CBuilder::__CreateAssert(Value * const assertion, StringRef failureMessage) {
     968void CBuilder::__CreateAssert(Value * const assertion, const Twine failureMessage) {
    969969    if (LLVM_UNLIKELY(isa<Constant>(assertion))) {
    970970        if (LLVM_UNLIKELY(cast<Constant>(assertion)->isNullValue())) {
     
    10781078            trace = CreatePointerCast(trace, stackPtrTy);
    10791079            depth = getInt32(n);
    1080         }
    1081         IRBuilder<>::CreateCall(function, {assertion, GetString(failureMessage), trace, depth});
     1080        }       
     1081        SmallVector<char, 1024> tmp;
     1082        IRBuilder<>::CreateCall(function, {assertion, GetString(failureMessage.toStringRef(tmp)), trace, depth});
    10821083    } else { // if assertions are not enabled, make it a compiler assumption.
    10831084        IRBuilder<>::CreateAssumption(assertion);
  • icGREP/icgrep-devel/icgrep/IR_Gen/CBuilder.h

    r5755 r5761  
    210210   
    211211    llvm::Value * GetString(llvm::StringRef Str);
    212    
     212
    213213    void CallPrintMsgToStderr(const std::string & message);
    214214
     
    236236    virtual llvm::StoreInst *  CreateAtomicStoreRelease(llvm::Value * val, llvm::Value * ptr);
    237237
    238     void CreateAssert(llvm::Value * assertion, llvm::StringRef failureMessage) {
     238    void CreateAssert(llvm::Value * assertion, const llvm::Twine failureMessage) {
    239239        if (LLVM_UNLIKELY(assertion->getType()->isVectorTy())) {
    240240            assertion = CreateBitCast(assertion, getIntNTy(assertion->getType()->getPrimitiveSizeInBits()));
     
    243243    }
    244244
    245     void CreateAssertZero(llvm::Value * assertion, llvm::StringRef failureMessage) {
     245    void CreateAssertZero(llvm::Value * assertion, const llvm::Twine failureMessage) {
    246246        if (LLVM_UNLIKELY(assertion->getType()->isVectorTy())) {
    247247            assertion = CreateBitCast(assertion, getIntNTy(assertion->getType()->getPrimitiveSizeInBits()));
     
    355355    bool hasAddressSanitizer() const;
    356356
    357     void __CreateAssert(llvm::Value * assertion, llvm::StringRef failureMessage);
     357    void __CreateAssert(llvm::Value * assertion, const llvm::Twine failureMessage);
    358358
    359359    llvm::Function * LinkFunction(llvm::StringRef name, llvm::FunctionType * type, void * functionPtr) const;
  • icGREP/icgrep-devel/icgrep/grep_engine.cpp

    r5758 r5761  
    431431// DoGrep thread function.
    432432void * GrepEngine::DoGrepThreadMethod() {
    433     size_t fileIdx;
    434 
    435     count_mutex.lock();
    436     fileIdx = mNextFileToGrep;
    437     if (fileIdx < inputFiles.size()) {
    438         mFileStatus[fileIdx] = FileStatus::InGrep;
    439         mNextFileToGrep++;
    440     }
    441     count_mutex.unlock();
    442 
     433
     434    auto fileIdx = mNextFileToGrep++;
    443435    while (fileIdx < inputFiles.size()) {
    444         size_t grepResult = doGrep(inputFiles[fileIdx], fileIdx);
    445        
    446         count_mutex.lock();
     436        const size_t grepResult = doGrep(inputFiles[fileIdx], fileIdx);
    447437        mFileStatus[fileIdx] = FileStatus::GrepComplete;
    448         if (grepResult > 0) grepMatchFound = true;
    449         fileIdx = mNextFileToGrep;
    450         if (fileIdx < inputFiles.size()) {
    451             mFileStatus[fileIdx] = FileStatus::InGrep;
    452             mNextFileToGrep++;
    453         }
    454         count_mutex.unlock();
     438        if (grepResult > 0) {
     439            grepMatchFound = true;
     440        }
    455441        if (QuietMode && grepMatchFound) {
    456             if (pthread_self() != mEngineThread) pthread_exit(nullptr);
     442            if (pthread_self() != mEngineThread) {
     443                pthread_exit(nullptr);
     444            }
    457445            return nullptr;
    458446        }
    459     }
    460     count_mutex.lock();
    461     fileIdx = mNextFileToPrint;
    462     bool readyToPrint = ((fileIdx == 0) || (mFileStatus[fileIdx - 1] == FileStatus::PrintComplete)) && (mFileStatus[fileIdx] == FileStatus::GrepComplete);
    463     if (fileIdx < inputFiles.size() && readyToPrint) {
    464         mFileStatus[fileIdx] = FileStatus::Printing;
    465         mNextFileToPrint++;
    466     }
    467     count_mutex.unlock();
    468 
    469     while (fileIdx < inputFiles.size()) {
     447        fileIdx = mNextFileToGrep++;
     448    }
     449
     450    auto printIdx = mNextFileToPrint++;
     451    while (printIdx < inputFiles.size()) {
     452        const bool readyToPrint = ((printIdx == 0) || (mFileStatus[printIdx - 1] == FileStatus::PrintComplete)) && (mFileStatus[printIdx] == FileStatus::GrepComplete);
    470453        if (readyToPrint) {
    471             std::cout << mResultStrs[fileIdx]->str();
    472         } else if (pthread_self() == mEngineThread) {
     454            const auto output = mResultStrs[printIdx]->str();
     455            if (!output.empty()) {
     456                mWriteMutex.lock();
     457                std::cout << output;
     458                mWriteMutex.unlock();
     459            }
     460            mFileStatus[printIdx] = FileStatus::PrintComplete;
     461            printIdx = mNextFileToPrint++;
     462        } else {
     463            mCacheMutex.lock();
    473464            mGrepDriver->performIncrementalCacheCleanupStep();
    474         }
    475         count_mutex.lock();
    476         if (readyToPrint) mFileStatus[fileIdx] = FileStatus::PrintComplete;
    477         fileIdx = mNextFileToPrint;
    478         if (fileIdx < inputFiles.size()) {
    479             readyToPrint = ((fileIdx == 0) || (mFileStatus[fileIdx - 1] == FileStatus::PrintComplete)) && (mFileStatus[fileIdx] == FileStatus::GrepComplete);
    480             if (readyToPrint) {
    481                 mFileStatus[fileIdx] = FileStatus::Printing;
    482                 mNextFileToPrint++;
    483             }
    484         }
    485         count_mutex.unlock();
    486     }
     465            mCacheMutex.unlock();
     466        }
     467        pthread_yield();
     468    }
     469
    487470    if (pthread_self() != mEngineThread) {
    488471        pthread_exit(nullptr);
    489     }
    490     else {
     472    } else {
    491473        return nullptr;
    492474    }
  • icGREP/icgrep-devel/icgrep/grep_engine.h

    r5735 r5761  
    1313#include <sstream>
    1414#include <mutex>
     15#include <atomic>
    1516
    1617namespace re { class CC; }
     
    2324
    2425class GrepEngine {
     26    enum class FileStatus {Pending, GrepComplete, PrintComplete};
    2527public:
    2628
     
    4244    Driver * mGrepDriver;
    4345
    44     enum class FileStatus {Pending, InGrep, GrepComplete, Printing, PrintComplete};
    45     std::mutex count_mutex;
    46     size_t mNextFileToGrep;
    47     size_t mNextFileToPrint;
     46    std::atomic<unsigned> mNextFileToGrep;
     47    std::atomic<unsigned> mNextFileToPrint;
    4848    std::vector<std::string> inputFiles;
    4949    std::vector<std::unique_ptr<std::stringstream>> mResultStrs;
    5050    std::vector<FileStatus> mFileStatus;
     51    std::mutex mWriteMutex;
     52    std::mutex mCacheMutex;
     53
     54
    5155    bool grepMatchFound;
    5256   
  • icGREP/icgrep-devel/icgrep/kernels/kernel.cpp

    r5757 r5761  
    973973        Value * const remaining = b->CreateSub(avail, processed);
    974974        Value * const remainingStrides = b->CreateUDiv(remaining, inputStrideSize[i]);
    975         hasMoreStrides = b->CreateAnd(hasMoreStrides, b->CreateICmpNE(remainingStrides, ZERO));
     975        Value * const hasRemainingStrides = b->CreateICmpNE(remainingStrides, ZERO);
     976        hasMoreStrides = b->CreateAnd(hasMoreStrides, hasRemainingStrides);
    976977    }
    977978    // even if we do not have enough input data for a full stride, if this is our final stride, allow it ...
     
    992993            Value * const remaining = b->CreateSub(capacity, unconsumed);
    993994            Value * const remainingStrides = b->CreateUDiv(remaining, outputStrideSize[i]);
    994             hasMoreStrides = b->CreateAnd(hasMoreStrides, b->CreateICmpNE(remainingStrides, ZERO));
     995            Value * const hasRemainingStrides = b->CreateICmpNE(remainingStrides, ZERO);
     996            hasMoreStrides = b->CreateAnd(hasMoreStrides, hasRemainingStrides);
    995997        }
    996998        // Do copybacks if necessary.
     
    9991001        }
    10001002    }
     1003
     1004    // b->CreateAssertZero(b->CreateOr(b->CreateNot(initiallyFinal), hasMoreStrides), getName() + " does not have enough output space for the final stride");
     1005
    10011006    b->CreateCondBr(hasMoreStrides, segmentLoop, segmentDone);
    10021007
  • icGREP/icgrep-devel/icgrep/kernels/source_kernel.cpp

    r5757 r5761  
    2828}
    2929
    30 void MMapSourceKernel::generateInitializeMethod(Function * const fileSizeMethod, const unsigned codeUnitWidth, const unsigned /* blocksRequiredPerSegment */, const std::unique_ptr<KernelBuilder> & kb) {
     30void MMapSourceKernel::generateInitializeMethod(Function * const fileSizeMethod, const unsigned codeUnitWidth, const unsigned segmentSize, const std::unique_ptr<KernelBuilder> & kb) {
    3131    BasicBlock * const emptyFile = kb->CreateBasicBlock("EmptyFile");
    3232    BasicBlock * const nonEmptyFile = kb->CreateBasicBlock("NonEmptyFile");
     
    4444    // we cannot mmap a 0 length file; just create a 1-page sized fake file buffer for simplicity
    4545    kb->SetInsertPoint(emptyFile);
    46     Constant * pageSize = kb->getSize(getpagesize());
    47     Value * fakeFileBuffer = kb->CreateAnonymousMMap(pageSize);
     46    Constant * const readSize = kb->getSize(segmentSize);
     47    Value * const fakeFileBuffer = kb->CreateAnonymousMMap(readSize);
    4848    kb->CreateBr(exit);
    4949
     
    5353
    5454    kb->SetInsertPoint(exit);
    55     PHINode * buffer = kb->CreatePHI(fileBackedBuffer->getType(), 2);
     55    PHINode * const buffer = kb->CreatePHI(fileBackedBuffer->getType(), 2);
    5656    buffer->addIncoming(fakeFileBuffer, emptyFile);
    5757    buffer->addIncoming(fileBackedBuffer, nonEmptyFile);
    58     PHINode * size = kb->CreatePHI(sizeTy, 2);
    59     size->addIncoming(pageSize, emptyFile);
    60     size->addIncoming(fileSize, nonEmptyFile);
     58    PHINode * const bufferSize = kb->CreatePHI(sizeTy, 2);
     59    bufferSize->addIncoming(readSize, emptyFile);
     60    bufferSize->addIncoming(fileSize, nonEmptyFile);
    6161
    6262    PointerType * const codeUnitPtrTy = kb->getIntNTy(codeUnitWidth)->getPointerTo();
    6363    Value * bufferPtr = kb->CreatePointerCast(buffer, codeUnitPtrTy);
     64    kb->setScalarField("buffer", bufferPtr);
     65    kb->setScalarField("fileSize", fileSize);
     66
    6467    kb->setBaseAddress("sourceBuffer", bufferPtr);
    65     kb->setBufferedSize("sourceBuffer", size);
    66     kb->setScalarField("readableBuffer", bufferPtr);
    67     kb->setScalarField("fileSize", fileSize);
     68    kb->setBufferedSize("sourceBuffer", bufferSize);
    6869    kb->setCapacity("sourceBuffer", fileSize);
    6970    kb->CreateMAdvise(buffer, fileSize, CBuilder::ADVICE_WILLNEED);
     
    7172}
    7273
    73 void MMapSourceKernel::generateDoSegmentMethod(const unsigned codeUnitWidth, const unsigned blocksRequiredPerSegment, const std::unique_ptr<KernelBuilder> & kb) {
     74void MMapSourceKernel::generateDoSegmentMethod(const unsigned codeUnitWidth, const unsigned segmentSize, const std::unique_ptr<KernelBuilder> & kb) {
    7475
    7576    BasicBlock * dropPages = kb->CreateBasicBlock("dropPages");
     
    7879    BasicBlock * mmapSourceExit = kb->CreateBasicBlock("mmapSourceExit");
    7980
    80     Constant * const segmentSize = kb->getSize(blocksRequiredPerSegment * kb->getBitBlockWidth());
     81    Constant * const readSize = kb->getSize(segmentSize);
    8182    Constant * const pageSize = kb->getSize(getpagesize());
    8283
     
    8687
    8788    Value * const consumedBuffer = kb->getRawOutputPointer("sourceBuffer", consumed);
    88     Value * const readableBuffer = kb->getScalarField("readableBuffer");
     89    Value * const readableBuffer = kb->getScalarField("buffer");
    8990    Value * const unnecessaryBytes = kb->CreatePtrDiff(consumedBuffer, readableBuffer);
    9091
     
    9596    // instruct the OS that it can safely drop any fully consumed pages
    9697    kb->CreateMAdvise(readableBuffer, unnecessaryBytes, CBuilder::ADVICE_DONTNEED);
    97     kb->setScalarField("readableBuffer", kb->CreateGEP(readableBuffer, unnecessaryBytes));
     98    kb->setScalarField("buffer", kb->CreateGEP(readableBuffer, unnecessaryBytes));
    9899    kb->CreateBr(processSegment);
    99100
     
    101102    kb->SetInsertPoint(processSegment);
    102103    Value * const fileSize = kb->getScalarField("fileSize");
    103     Value * const produced = kb->CreateAdd(kb->getProducedItemCount("sourceBuffer"), segmentSize);
     104    Value * const produced = kb->CreateAdd(kb->getProducedItemCount("sourceBuffer"), readSize);
    104105    Value * const lessThanFullSegment = kb->CreateICmpULT(fileSize, produced);
    105106    kb->CreateUnlikelyCondBr(lessThanFullSegment, setTermination, mmapSourceExit);
     
    122123}
    123124
    124 MMapSourceKernel::MMapSourceKernel(const std::unique_ptr<kernel::KernelBuilder> & kb, unsigned blocksRequiredPerSegment, unsigned codeUnitWidth)
    125 : SegmentOrientedKernel("mmap_source" + std::to_string(blocksRequiredPerSegment) + "@" + std::to_string(codeUnitWidth),
     125MMapSourceKernel::MMapSourceKernel(const std::unique_ptr<kernel::KernelBuilder> & kb, const unsigned stridesPerSegment, const unsigned codeUnitWidth)
     126: SegmentOrientedKernel("mmap_source" + std::to_string(stridesPerSegment) + "@" + std::to_string(codeUnitWidth),
    126127{},
    127128{Binding{kb->getStreamSetTy(1, codeUnitWidth), "sourceBuffer", FixedRate(), Deferred()}},
    128129{Binding{kb->getInt32Ty(), "fileDescriptor"}},
    129 {Binding{kb->getSizeTy(), "fileSize"}}, {Binding{kb->getIntNTy(codeUnitWidth)->getPointerTo(), "readableBuffer"}})
    130 , mBlocksRequiredPerSegment(blocksRequiredPerSegment)
     130{Binding{kb->getSizeTy(), "fileSize"}}, {Binding{kb->getIntNTy(codeUnitWidth)->getPointerTo(), "buffer"}})
     131, mStridesPerSegment(stridesPerSegment)
    131132, mCodeUnitWidth(codeUnitWidth)
    132133, mFileSizeFunction(nullptr) {
     
    136137/// READ SOURCE KERNEL
    137138
    138 void ReadSourceKernel::generateInitializeMethod(const unsigned codeUnitWidth, const unsigned blocksRequiredPerSegment, const std::unique_ptr<KernelBuilder> & b) {
     139void ReadSourceKernel::generateInitializeMethod(const unsigned codeUnitWidth, const unsigned segmentSize, const std::unique_ptr<KernelBuilder> & b) {
    139140    const unsigned pageSize = getpagesize();
    140     const unsigned segmentSize = blocksRequiredPerSegment * b->getBitBlockWidth();
    141141    const auto bufferSize = std::max(pageSize * 8, segmentSize * 4);
    142142    ConstantInt * const bufferItems = b->getSize(bufferSize);
     
    150150}
    151151
    152 void ReadSourceKernel::generateDoSegmentMethod(const unsigned codeUnitWidth, const unsigned blocksRequiredPerSegment, const std::unique_ptr<KernelBuilder> & b) {
     152void ReadSourceKernel::generateDoSegmentMethod(const unsigned codeUnitWidth, const unsigned segmentSize, const std::unique_ptr<KernelBuilder> & b) {
    153153
    154154    const unsigned pageSize = getpagesize();
    155     const unsigned segmentSize = blocksRequiredPerSegment * b->getBitBlockWidth();
    156155    ConstantInt * const itemsToRead = b->getSize(std::max(pageSize, segmentSize * 2));
    157156    ConstantInt * const codeUnitBytes = b->getSize(codeUnitWidth / 8);
     
    166165    BasicBlock * const readExit = b->CreateBasicBlock("ReadExit");
    167166
    168     // Do we have enough unread data to support a segments worth of processing?
     167    // Do we have enough unread data to support one segment?
    169168    Value * const produced = b->getProducedItemCount("sourceBuffer");
    170169    Value * const buffered = b->getBufferedSize("sourceBuffer");
     
    213212    Value * const expandedBuffer = b->CreatePointerCast(b->CreateCacheAlignedMalloc(expandedBytes), unreadData->getType());
    214213    b->CreateMemCpy(expandedBuffer, unreadData, remainingBytes, blockSize);
    215     b->CreateFree(baseBuffer);
    216214    b->setScalarField("buffer", expandedBuffer);
    217215    b->setCapacity("sourceBuffer", expandedCapacity);
     216    b->CreateFree(baseBuffer);
    218217    b->CreateBr(prepareBuffer);
    219218
     
    258257}
    259258
    260 ReadSourceKernel::ReadSourceKernel(const std::unique_ptr<kernel::KernelBuilder> & b, const unsigned blocksRequiredPerSegment, const unsigned codeUnitWidth)
    261 : SegmentOrientedKernel("read_source"  + std::to_string(blocksRequiredPerSegment) + "@" + std::to_string(codeUnitWidth)
     259ReadSourceKernel::ReadSourceKernel(const std::unique_ptr<kernel::KernelBuilder> & b, const unsigned stridesPerSegment, const unsigned codeUnitWidth)
     260: SegmentOrientedKernel("read_source"  + std::to_string(stridesPerSegment) + "@" + std::to_string(codeUnitWidth)
    262261, {}
    263262, {Binding{b->getStreamSetTy(1, codeUnitWidth), "sourceBuffer", FixedRate(), Deferred()}}
     
    265264, {}
    266265, {Binding{b->getIntNTy(codeUnitWidth)->getPointerTo(), "buffer"}})
    267 , mBlocksRequiredPerSegment(blocksRequiredPerSegment)
     266, mStridesPerSegment(stridesPerSegment)
    268267, mCodeUnitWidth(codeUnitWidth) {
    269268
     
    298297    kb->CreateCondBr(kb->CreateICmpEQ(kb->getScalarField("fileDescriptor"), kb->getInt32(STDIN_FILENO)), initializeRead, initializeMMap);
    299298    kb->SetInsertPoint(initializeRead);
    300     ReadSourceKernel::generateInitializeMethod(mCodeUnitWidth, mBlocksRequiredPerSegment, kb);
     299    ReadSourceKernel::generateInitializeMethod(mCodeUnitWidth, mStride * mStridesPerSegment, kb);
    301300    kb->CreateBr(initializeDone);
    302301    kb->SetInsertPoint(initializeMMap);
    303     MMapSourceKernel::generateInitializeMethod(mFileSizeFunction, mCodeUnitWidth, mBlocksRequiredPerSegment, kb);
     302    MMapSourceKernel::generateInitializeMethod(mFileSizeFunction, mCodeUnitWidth, mStride * mStridesPerSegment, kb);
    304303    kb->CreateBr(initializeDone);
    305304    kb->SetInsertPoint(initializeDone);
     
    313312    kb->CreateCondBr(kb->CreateICmpEQ(kb->getScalarField("fileDescriptor"), kb->getInt32(STDIN_FILENO)), DoSegmentRead, DoSegmentMMap);
    314313    kb->SetInsertPoint(DoSegmentRead);
    315     ReadSourceKernel::generateDoSegmentMethod(mCodeUnitWidth, mBlocksRequiredPerSegment, kb);
     314    ReadSourceKernel::generateDoSegmentMethod(mCodeUnitWidth, mStride * mStridesPerSegment, kb);
    316315    kb->CreateBr(DoSegmentDone);
    317316    kb->SetInsertPoint(DoSegmentMMap);
    318     MMapSourceKernel::generateDoSegmentMethod(mCodeUnitWidth, mBlocksRequiredPerSegment, kb);
     317    MMapSourceKernel::generateDoSegmentMethod(mCodeUnitWidth, mStride * mStridesPerSegment, kb);
    319318    kb->CreateBr(DoSegmentDone);
    320319    kb->SetInsertPoint(DoSegmentDone);
    321320}
    322321
    323 FDSourceKernel::FDSourceKernel(const std::unique_ptr<kernel::KernelBuilder> & kb, const unsigned blocksRequiredPerSegment, const unsigned codeUnitWidth)
    324 : SegmentOrientedKernel("FD_source" + std::to_string(blocksRequiredPerSegment) + "@" + std::to_string(codeUnitWidth)
     322FDSourceKernel::FDSourceKernel(const std::unique_ptr<kernel::KernelBuilder> & kb, const unsigned stridesPerSegment, const unsigned codeUnitWidth)
     323: SegmentOrientedKernel("FD_source" + std::to_string(stridesPerSegment) + "@" + std::to_string(codeUnitWidth)
    325324, {}
    326 , {Binding{kb->getStreamSetTy(1, codeUnitWidth), "sourceBuffer"}}
     325, {Binding{kb->getStreamSetTy(1, codeUnitWidth), "sourceBuffer", FixedRate(), Deferred()}}
    327326, {Binding{kb->getInt32Ty(), "fileDescriptor"}}
    328327, {}
    329 , {Binding{kb->getIntNTy(codeUnitWidth)->getPointerTo(), "buffer"},
    330     Binding{kb->getSizeTy(), "fileSize"}, Binding{kb->getInt8PtrTy(), "readableBuffer"}})
    331 , mBlocksRequiredPerSegment(blocksRequiredPerSegment)
     328, {Binding{kb->getIntNTy(codeUnitWidth)->getPointerTo(), "buffer"}, Binding{kb->getSizeTy(), "fileSize"}})
     329, mStridesPerSegment(stridesPerSegment)
    332330, mCodeUnitWidth(codeUnitWidth)
    333331, mFileSizeFunction(nullptr) {
     
    341339    kb->setBaseAddress("sourceBuffer", fileSource);
    342340    Value * const fileSize = kb->getScalarField("fileSize");
    343     kb->setBufferedSize("sourceBuffer", fileSize);
    344     kb->setCapacity("sourceBuffer", fileSize);
     341    Value * const fileItems = kb->CreateUDiv(fileSize, kb->getSize(mCodeUnitWidth / 8));
     342    kb->setBufferedSize("sourceBuffer", fileItems);
     343    kb->setCapacity("sourceBuffer", fileItems);
    345344}
    346345
     
    350349    BasicBlock * setTermination = kb->CreateBasicBlock("setTermination");
    351350    BasicBlock * mmapSourceExit = kb->CreateBasicBlock("sourceExit");
    352     ConstantInt * segmentItems = kb->getSize(mBlocksRequiredPerSegment * kb->getBitBlockWidth());
    353     Value * fileItems = kb->getScalarField("fileSize");
    354     if (mCodeUnitWidth > 8) {
    355         fileItems = kb->CreateUDiv(fileItems, kb->getSize(mCodeUnitWidth / 8));
    356     }
    357     Value * produced = kb->getProducedItemCount("sourceBuffer");
    358     produced = kb->CreateAdd(produced, segmentItems);
    359     Value * lessThanFullSegment = kb->CreateICmpULT(fileItems, produced);
    360     kb->CreateCondBr(lessThanFullSegment, setTermination, mmapSourceExit);
     351
     352    ConstantInt * const segmentItems = kb->getSize(mStride * mStridesPerSegment);
     353    Value * const fileItems = kb->getBufferedSize("sourceBuffer");
     354    Value * const produced = kb->CreateAdd(kb->getProducedItemCount("sourceBuffer"), segmentItems);
     355
     356    kb->CreateUnlikelyCondBr(kb->CreateICmpULT(fileItems, produced), setTermination, mmapSourceExit);
     357
    361358    kb->SetInsertPoint(setTermination);
    362359    kb->setTerminationSignal();
     
    364361
    365362    kb->SetInsertPoint(mmapSourceExit);
    366 
    367363    PHINode * itemsRead = kb->CreatePHI(produced->getType(), 2);
    368364    itemsRead->addIncoming(produced, entryBlock);
     
    371367}
    372368
    373 MemorySourceKernel::MemorySourceKernel(const std::unique_ptr<kernel::KernelBuilder> & kb, Type * const type, const unsigned blocksRequiredPerSegment, const unsigned codeUnitWidth)
     369MemorySourceKernel::MemorySourceKernel(const std::unique_ptr<kernel::KernelBuilder> & kb, Type * const type, const unsigned stridesPerSegment, const unsigned codeUnitWidth)
    374370: SegmentOrientedKernel("memory_source",
    375371    {},
    376372    {Binding{kb->getStreamSetTy(1, codeUnitWidth), "sourceBuffer"}},
    377373    {Binding{cast<PointerType>(type), "fileSource"}, Binding{kb->getSizeTy(), "fileSize"}}, {}, {})
    378 , mBlocksRequiredPerSegment(blocksRequiredPerSegment)
     374, mStridesPerSegment(stridesPerSegment)
    379375, mCodeUnitWidth(codeUnitWidth) {
    380376
  • icGREP/icgrep-devel/icgrep/kernels/source_kernel.h

    r5757 r5761  
    1414    friend class FDSourceKernel;
    1515public:
    16     MMapSourceKernel(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, const unsigned blocksRequiredPerSegment = 1, const unsigned codeUnitWidth = 8);
     16    MMapSourceKernel(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, const unsigned stridesPerSegment = 1, const unsigned codeUnitWidth = 8);
    1717    bool isCachable() const override { return true; }
    1818    bool hasSignature() const override { return false; }
     
    2121    }
    2222    void generateInitializeMethod(const std::unique_ptr<kernel::KernelBuilder> & iBuilder) override {
    23         generateInitializeMethod(mFileSizeFunction, mCodeUnitWidth, mBlocksRequiredPerSegment, iBuilder);
     23        generateInitializeMethod(mFileSizeFunction, mCodeUnitWidth, mStride * mStridesPerSegment, iBuilder);
    2424    }
    2525    void generateDoSegmentMethod(const std::unique_ptr<kernel::KernelBuilder> & iBuilder) override {
    26         generateDoSegmentMethod(mCodeUnitWidth, mBlocksRequiredPerSegment, iBuilder);
     26        generateDoSegmentMethod(mCodeUnitWidth, mStride * mStridesPerSegment, iBuilder);
    2727    }
    2828    void generateFinalizeMethod(const std::unique_ptr<kernel::KernelBuilder> & iBuilder) override {
     
    3131protected:
    3232    static llvm::Function * linkFileSizeMethod(const std::unique_ptr<kernel::KernelBuilder> & iBuilder);
    33     static void generateInitializeMethod(llvm::Function * fileSize, const unsigned codeUnitWidth, const unsigned blocksRequiredPerSegment, const std::unique_ptr<kernel::KernelBuilder> & iBuilder);
    34     static void generateDoSegmentMethod(const unsigned codeUnitWidth, const unsigned blocksRequiredPerSegment, const std::unique_ptr<kernel::KernelBuilder> & iBuilder);
     33    static void generateInitializeMethod(llvm::Function * fileSize, const unsigned codeUnitWidth, const unsigned segmentSize, const std::unique_ptr<kernel::KernelBuilder> & iBuilder);
     34    static void generateDoSegmentMethod(const unsigned codeUnitWidth, const unsigned segmentSize, const std::unique_ptr<kernel::KernelBuilder> & iBuilder);
    3535    static void unmapSourceBuffer(const std::unique_ptr<kernel::KernelBuilder> & iBuilder);
    3636protected:
    37     const unsigned   mBlocksRequiredPerSegment;
    38     const unsigned   mCodeUnitWidth;
     37    const unsigned mStridesPerSegment;
     38    const unsigned mCodeUnitWidth;
    3939    llvm::Function * mFileSizeFunction;
    4040};
     
    4343    friend class FDSourceKernel;
    4444public:
    45     ReadSourceKernel(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, const unsigned blocksRequiredPerSegment = 1, const unsigned codeUnitWidth = 8);
     45    ReadSourceKernel(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, const unsigned stridesPerSegment = 1, const unsigned codeUnitWidth = 8);
    4646    bool isCachable() const override { return true; }
    4747    bool hasSignature() const override { return false; }
    4848    void generateInitializeMethod(const std::unique_ptr<kernel::KernelBuilder> & iBuilder) override {
    49         generateInitializeMethod(mCodeUnitWidth, mBlocksRequiredPerSegment, iBuilder);
     49        generateInitializeMethod(mCodeUnitWidth, mStride * mStridesPerSegment, iBuilder);
    5050    }
    5151    void generateDoSegmentMethod(const std::unique_ptr<kernel::KernelBuilder> & iBuilder) override {
    52         generateDoSegmentMethod(mCodeUnitWidth, mBlocksRequiredPerSegment, iBuilder);
     52        generateDoSegmentMethod(mCodeUnitWidth, mStride * mStridesPerSegment, iBuilder);
    5353    }
    5454    void generateFinalizeMethod(const std::unique_ptr<kernel::KernelBuilder> & iBuilder) override {
     
    5656    }
    5757protected:
    58     static void generateInitializeMethod(const unsigned codeUnitWidth, const unsigned blocksRequiredPerSegment, const std::unique_ptr<kernel::KernelBuilder> & iBuilder);
    59     static void generateDoSegmentMethod(const unsigned codeUnitWidth, const unsigned blocksRequiredPerSegment, const std::unique_ptr<kernel::KernelBuilder> & iBuilder);
     58    static void generateInitializeMethod(const unsigned codeUnitWidth, const unsigned segmentSize, const std::unique_ptr<kernel::KernelBuilder> & iBuilder);
     59    static void generateDoSegmentMethod(const unsigned codeUnitWidth, const unsigned segmentSize, const std::unique_ptr<kernel::KernelBuilder> & iBuilder);
    6060    static void freeBuffer(const std::unique_ptr<kernel::KernelBuilder> & iBuilder);
    6161private:
    62     const unsigned mBlocksRequiredPerSegment;
     62    const unsigned mStridesPerSegment;
    6363    const unsigned mCodeUnitWidth;
    6464};
     
    6666class FDSourceKernel final : public SegmentOrientedKernel {
    6767public:
    68     FDSourceKernel(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, const unsigned blocksRequiredPerSegment = 1, const unsigned codeUnitWidth = 8);
     68    FDSourceKernel(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, const unsigned stridesPerSegment = 1, const unsigned codeUnitWidth = 8);
    6969    bool isCachable() const override { return true; }
    7070    bool hasSignature() const override { return false; }
     
    7474    void generateFinalizeMethod(const std::unique_ptr<kernel::KernelBuilder> & iBuilder) override;
    7575protected:
    76     const unsigned mBlocksRequiredPerSegment;
     76    const unsigned mStridesPerSegment;
    7777    const unsigned mCodeUnitWidth;
    7878    llvm::Function * mFileSizeFunction;
     
    8181class MemorySourceKernel final : public SegmentOrientedKernel {
    8282public:
    83     MemorySourceKernel(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, llvm::Type * const type, const unsigned blocksRequiredPerSegment = 1, const unsigned codeUnitWidth = 8);
     83    MemorySourceKernel(const std::unique_ptr<kernel::KernelBuilder> & iBuilder, llvm::Type * const type, const unsigned stridesPerSegment = 1, const unsigned codeUnitWidth = 8);
    8484    bool hasSignature() const override { return false; }
    8585protected:
     
    8787    void generateDoSegmentMethod(const std::unique_ptr<kernel::KernelBuilder> & iBuilder) override;
    8888private:
    89     const unsigned mBlocksRequiredPerSegment;
     89    const unsigned mStridesPerSegment;
    9090    const unsigned mCodeUnitWidth;
    9191};
  • icGREP/icgrep-devel/icgrep/toolchain/object_cache.cpp

    r5738 r5761  
    88#include <llvm/Support/FileSystem.h>
    99#include <llvm/Support/Path.h>
    10 #include <llvm/Support/Debug.h> 
     10#include <llvm/Support/Debug.h>
    1111#include <llvm/IR/Module.h>
    1212#include <sys/file.h>
     
    2626
    2727using namespace llvm;
    28 
     28namespace fs = boost::filesystem;
     29
     30#ifdef NDEBUG
     31#define CACHE_ENTRY_MAX_HOURS (24 * 15)
     32#else
     33#define CACHE_ENTRY_MAX_HOURS (1)
     34#endif
     35
     36#define SECONDS_PER_HOUR (3600)
    2937//===----------------------------------------------------------------------===//
    3038// Object cache (based on tools/lli/lli.cpp, LLVM 3.6.1)
     
    7482        assert ("empty metadata node" && sig->getNumOperands() == 1);
    7583        assert ("no signature payload" && sig->getOperand(0)->getNumOperands() == 1);
    76         return cast<MDString>(sig->getOperand(0)->getOperand(0));
     84        return dyn_cast<MDString>(sig->getOperand(0)->getOperand(0));
    7785    }
    7886    return nullptr;
     
    94102
    95103        // No, check for an existing cache file.
    96         Path objectName(mCachePath);
    97         sys::path::append(objectName, CACHE_PREFIX);
    98         objectName.append(moduleId);
    99         objectName.append(".o");
    100 
    101         auto objectBuffer = MemoryBuffer::getFile(objectName.c_str(), -1, false);
    102         if (objectBuffer) {
    103             if (kernel->hasSignature()) {
    104                 sys::path::replace_extension(objectName, ".sig");
    105                 const auto signatureBuffer = MemoryBuffer::getFile(objectName.c_str(), -1, false);
    106                 if (signatureBuffer) {
    107                     const StringRef loadedSig = signatureBuffer.get()->getBuffer();
    108                     if (LLVM_UNLIKELY(!loadedSig.equals(kernel->makeSignature(idb)))) {
     104        Path fileName(mCachePath);
     105        sys::path::append(fileName, CACHE_PREFIX);
     106        fileName.append(moduleId);
     107        fileName.append(".kernel");
     108
     109        auto kernelBuffer = MemoryBuffer::getFile(fileName.c_str(), -1, false);
     110        if (kernelBuffer) {
     111            #if LLVM_VERSION_INTEGER < LLVM_4_0_0
     112            auto loadedFile = getLazyBitcodeModule(std::move(kernelBuffer.get()), idb->getContext());
     113            #else
     114            auto loadedFile = getOwningLazyBitcodeModule(std::move(kernelBuffer.get()), idb->getContext());
     115            #endif
     116            // if there was no error when parsing the bitcode
     117            if (LLVM_LIKELY(loadedFile)) {
     118                std::unique_ptr<Module> M(std::move(loadedFile.get()));
     119                if (kernel->hasSignature()) {
     120                    const MDString * const sig = getSignature(M.get());
     121                    assert ("signature is missing from kernel file: possible module naming conflict?" && sig);
     122                    if (LLVM_UNLIKELY(sig == nullptr || !sig->getString().equals(kernel->makeSignature(idb)))) {
    109123                        goto invalid;
    110124                    }
    111                 } else {
    112                    
    113                     report_fatal_error("signature file expected but not found: " + moduleId);
    114                 }               
    115             }
    116             sys::path::replace_extension(objectName, ".kernel");
    117             auto kernelBuffer = MemoryBuffer::getFile(objectName.c_str(), -1, false);
    118             if (*kernelBuffer) {
    119                 //MemoryBuffer * kb = kernelBuffer.get().release();
    120                 //auto loadedFile = parseBitcodeFile(kb->getMemBufferRef(), mContext);
    121 #if LLVM_VERSION_INTEGER < LLVM_4_0_0
    122                 auto loadedFile = getLazyBitcodeModule(std::move(kernelBuffer.get()), idb->getContext());
    123 #else
    124                 auto loadedFile = getOwningLazyBitcodeModule(std::move(kernelBuffer.get()), idb->getContext());
    125 #endif
    126                 if (*loadedFile) {
    127                     Module * const m = loadedFile.get().release(); assert (m);
     125                }
     126                sys::path::replace_extension(fileName, ".o");
     127                auto objectBuffer = MemoryBuffer::getFile(fileName.c_str(), -1, false);
     128                if (LLVM_LIKELY(objectBuffer)) {
     129                    Module * const m = M.release();
    128130                    // defaults to <path>/<moduleId>.kernel
    129131                    m->setModuleIdentifier(moduleId);
    130132                    kernel->setModule(m);
    131                     kernel->prepareCachedKernel(idb);                   
     133                    kernel->prepareCachedKernel(idb);
    132134                    mCachedObject.emplace(moduleId, std::make_pair(m, std::move(objectBuffer.get())));
    133135                    // update the modified time of the .kernel, .o and .sig files
    134136                    time_t access_time = time(0);
    135                     boost::filesystem::last_write_time(objectName.c_str(), access_time);
    136                     sys::path::replace_extension(objectName, ".o");
    137                     boost::filesystem::last_write_time(objectName.c_str(), access_time);
    138                     if (kernel->hasSignature()) {
    139                         sys::path::replace_extension(objectName, ".sig");
    140                         boost::filesystem::last_write_time(objectName.c_str(), access_time);
    141                     }
     137                    fs::last_write_time(fileName.c_str(), access_time);
     138                    sys::path::replace_extension(fileName, ".kernel");
     139                    fs::last_write_time(fileName.c_str(), access_time);
    142140                    return true;
    143141                }
     
    177175        objFile.close();
    178176
     177        // and kernel prototype header
     178        std::unique_ptr<Module> H(new Module(M->getModuleIdentifier(), M->getContext()));
     179        for (const Function & f : M->getFunctionList()) {
     180            if (f.hasExternalLinkage() && !f.empty()) {
     181                Function::Create(f.getFunctionType(), Function::ExternalLinkage, f.getName(), H.get());
     182            }
     183        }
     184
    179185        // then the signature (if one exists)
    180186        const MDString * const sig = getSignature(M);
    181187        if (sig) {
    182             sys::path::replace_extension(objectName, ".sig");
    183             raw_fd_ostream sigfile(objectName, EC, sys::fs::F_None);
    184             sigfile << sig->getString();
    185             sigfile.close();
    186         }
    187 
    188         // and finally kernel prototype header.
    189         std::unique_ptr<Module> header(new Module(M->getModuleIdentifier(), M->getContext()));
    190         for (const Function & f : M->getFunctionList()) {
    191             if (f.hasExternalLinkage() && !f.empty()) {
    192                 Function::Create(f.getFunctionType(), Function::ExternalLinkage, f.getName(), header.get());
    193             }
     188            NamedMDNode * const md = H->getOrInsertNamedMetadata(SIGNATURE);
     189            assert (md->getNumOperands() == 0);
     190            MDString * const sigCopy = MDString::get(H->getContext(), sig->getString());
     191            md->addOperand(MDNode::get(H->getContext(), {sigCopy}));
    194192        }
    195193
    196194        sys::path::replace_extension(objectName, ".kernel");
    197195        raw_fd_ostream kernelFile(objectName.str(), EC, sys::fs::F_None);
    198         WriteBitcodeToFile(header.get(), kernelFile);
     196        WriteBitcodeToFile(H.get(), kernelFile);
    199197        kernelFile.close();
    200198    }
     
    202200
    203201void ParabixObjectCache::performIncrementalCacheCleanupStep() {
    204     if (mCacheCleanupIterator != boost::filesystem::directory_iterator()) {
    205         auto & e = mCacheCleanupIterator->path();
     202    if (mCacheCleanupIterator != fs::directory_iterator()) {
     203        const auto e = mCacheCleanupIterator->path();
    206204        mCacheCleanupIterator++;
    207205        // Simple clean-up policy: files that haven't been touched by the
     
    210208        // TODO: possibly determine total filecount and set items per clean up step based on
    211209        // filecount
    212         if (boost::filesystem::is_regular_file(e)) {
    213             auto age = std::time(nullptr) - boost::filesystem::last_write_time(e);
    214             if (age > mCacheEntryMaxHours * 3600 /* secs/hour*/ ) {
    215                 boost::filesystem::remove(e);
     210        if (fs::is_regular_file(e)) {
     211            const auto age = std::time(nullptr) - fs::last_write_time(e);
     212            if (age > (CACHE_ENTRY_MAX_HOURS * SECONDS_PER_HOUR)) {
     213                fs::remove(e);
    216214            }
    217215        }
     
    228226}
    229227
    230 inline std::string ParabixObjectCache::getDefaultPath() {
     228ParabixObjectCache::ParabixObjectCache(const StringRef dir)
     229: mCachePath(dir) {
     230    fs::path p(mCachePath.str());
     231    if (LLVM_LIKELY(!mCachePath.empty())) {
     232        sys::fs::create_directories(mCachePath);
     233    }
     234    fs::directory_iterator it(p);
     235    mCacheCleanupIterator = it;
     236}
     237
     238inline ParabixObjectCache::Path getDefaultPath() {
    231239    // $HOME/.cache/parabix/
    232     Path cachePath;
     240    ParabixObjectCache::Path cachePath;
    233241#if LLVM_VERSION_INTEGER < LLVM_3_7_0
    234242    sys::path::user_cache_directory(cachePath, "parabix");
     
    237245    sys::path::append(cachePath, ".cache", "parabix");
    238246#endif
    239     return cachePath.str();
    240 }
    241 
    242 ParabixObjectCache::ParabixObjectCache(const std::string dir)
    243 : mCachePath(dir) {
    244     boost::filesystem::path p(mCachePath.str());
    245     if (LLVM_LIKELY(!mCachePath.empty())) {
    246         sys::fs::create_directories(Twine(mCachePath));
    247     }
    248     boost::filesystem::directory_iterator it(p);
    249     mCacheCleanupIterator = it;
    250     mCacheEntryMaxHours = CACHE_ENTRY_MAX_HOURS;
     247    return cachePath;
    251248}
    252249
    253250ParabixObjectCache::ParabixObjectCache()
    254251: ParabixObjectCache(getDefaultPath()) {
    255 }
    256 
    257 
     252
     253}
     254
     255
  • icGREP/icgrep-devel/icgrep/toolchain/object_cache.h

    r5735 r5761  
    3535//
    3636
    37 unsigned const CACHE_ENTRY_MAX_HOURS (24 * 15);
    38 
    39 class ParabixObjectCache final : public llvm::ObjectCache {
    40     using Path = llvm::SmallString<128>;
     37class ParabixObjectCache final : public llvm::ObjectCache {   
    4138    template <typename K, typename V>
    4239    using Map = boost::container::flat_map<K, V>;
    43     using ModuleCache = Map<std::string, std::pair<llvm::Module *, std::unique_ptr<llvm::MemoryBuffer>>>;
     40    using ModuleCache = Map<std::string, std::pair<llvm::Module *, std::unique_ptr<llvm::MemoryBuffer>>>;   
    4441public:
    45     ParabixObjectCache(const std::string dir);
     42    using Path = llvm::SmallString<128>;
     43    ParabixObjectCache(const llvm::StringRef dir);
    4644    ParabixObjectCache();
    4745    bool loadCachedObjectFile(const std::unique_ptr<kernel::KernelBuilder> & idb, kernel::Kernel * const kernel);
     
    4947    std::unique_ptr<llvm::MemoryBuffer> getObject(const llvm::Module * M) override;
    5048    void performIncrementalCacheCleanupStep();
    51 protected:
    52     static std::string getDefaultPath();
    5349private:
    54     ModuleCache         mCachedObject;
    55     const Path          mCachePath;
     50    ModuleCache mCachedObject;
     51    const Path mCachePath;
    5652    boost::filesystem::directory_iterator mCacheCleanupIterator;
    57     unsigned            mCacheEntryMaxHours;
    5853};
    5954
  • icGREP/icgrep-devel/icgrep/toolchain/pipeline.cpp

    r5757 r5761  
    288288            Value * cycles = iBuilder->CreateLoad(iBuilder->getCycleCountPtr());
    289289            Value * fCycles = iBuilder->CreateUIToFP(cycles, iBuilder->getDoubleTy());
    290             std::string formatString = kernel->getName() + ": %7.2e items processed; %7.2e CPU cycles,  %6.2f cycles per item.\n";
     290            const auto formatString = kernel->getName() + ": %7.2e items processed; %7.2e CPU cycles,  %6.2f cycles per item.\n";
    291291            Value * stringPtr = iBuilder->CreatePointerCast(iBuilder->GetString(formatString), iBuilder->getInt8PtrTy());
    292292            iBuilder->CreateCall(iBuilder->GetDprintf(), {iBuilder->getInt32(2), stringPtr, fItems, fCycles, iBuilder->CreateFDiv(fCycles, fItems)});
     
    385385
    386386        Function * const threadFunc = makeThreadFunction(iBuilder, "ppt:" + kernel->getName());
    387         Function::arg_iterator ai = threadFunc->arg_begin();
    388         Value * sharedStruct = iBuilder->CreateBitCast(&*(ai), sharedStructType->getPointerTo());
     387        auto ai = threadFunc->arg_begin();
    389388       
    390389         // Create the basic blocks for the thread function.
     
    397396        iBuilder->SetInsertPoint(entryBlock);
    398397
     398        Value * const sharedStruct = iBuilder->CreateBitCast(&*(ai), sharedStructType->getPointerTo());
    399399
    400400        for (unsigned k = 0; k < n; k++) {
     
    614614            Value * cycles = iBuilder->CreateLoad(iBuilder->getCycleCountPtr());
    615615            Value * fCycles = iBuilder->CreateUIToFP(cycles, iBuilder->getDoubleTy());
    616             std::string formatString = kernel->getName() + ": %7.2e items processed; %7.2e CPU cycles,  %6.2f cycles per item.\n";
     616            const auto formatString = kernel->getName() + ": %7.2e items processed; %7.2e CPU cycles,  %6.2f cycles per item.\n";
    617617            Value * stringPtr = iBuilder->CreatePointerCast(iBuilder->GetString(formatString), iBuilder->getInt8PtrTy());
    618618            iBuilder->CreateCall(iBuilder->GetDprintf(), {iBuilder->getInt32(2), stringPtr, fItems, fCycles, iBuilder->CreateFDiv(fCycles, fItems)});
Note: See TracChangeset for help on using the changeset viewer.