Ignore:
Timestamp:
Dec 8, 2017, 1:55:22 AM (22 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/toolchain
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • 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.