Ignore:
Timestamp:
May 3, 2017, 1:13:04 PM (2 years ago)
Author:
nmedfort
Message:

partial refactoring check in with change for Linda.

Location:
icGREP/icgrep-devel/icgrep/toolchain
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • icGREP/icgrep-devel/icgrep/toolchain/object_cache.cpp

    r5425 r5431  
    11#include "object_cache.h"
     2#include <kernels/kernel.h>
    23#include <llvm/Support/raw_ostream.h>
     4#include <llvm/Support/MemoryBuffer.h>
    35#include <llvm/Support/FileSystem.h>
    46#include <llvm/Support/Path.h>
    57#include <llvm/IR/Module.h>
    6 #include <string>
     8#include <sys/file.h>
     9#include <sys/stat.h>
     10#include <fcntl.h>
     11#include <boost/filesystem.hpp>
     12#include <ctime>
    713
    814using namespace llvm;
     
    1622// file exists.
    1723//
    18 ParabixObjectCache::ParabixObjectCache(const std::string &dir): CacheDir(dir) {}
     24ParabixObjectCache::ParabixObjectCache(const std::string &dir): mCachePath(dir) {}
    1925
    2026ParabixObjectCache::ParabixObjectCache() {
    2127    // $HOME/.cache/icgrep
    2228    // TODO use path::user_cache_directory once we have llvm >= 3.7.
    23     sys::path::home_directory(CacheDir);
    24     std::string Version = PARABIX_VERSION;
    25     std::string Date = __DATE__;
    26     std::string Time = __TIME__;
    27     std::string DateStamp = Date.substr(7) + Date.substr(0,3) + (Date[4] == ' ' ? Date.substr(5,1) : Date.substr(4,2));
    28     std::string CacheSubDir = "Parabix" + Version + "_" + DateStamp + "@" + Time;
    29     sys::path::append(CacheDir, ".cache", CacheSubDir);
     29    sys::path::home_directory(mCachePath);
     30    sys::path::append(mCachePath, ".cache", "parabix");
     31
     32    const std::string Version = PARABIX_VERSION;
     33    const std::string Date = __DATE__;
     34    const std::string Time = __TIME__;
     35    const std::string DateStamp = Date.substr(7) + Date.substr(0, 3) + (Date[4] == ' ' ? Date.substr(5, 1) : Date.substr(4, 2));
     36    mCachePrefix = Version + "_" + DateStamp + "@" + Time;
    3037}
    3138
    32 ParabixObjectCache::~ParabixObjectCache() {}
     39bool ParabixObjectCache::loadCachedObjectFile(kernel::KernelBuilder * const kernel) {
     40    if (LLVM_LIKELY(kernel->isCachable())) {
    3341
    34 // A new module has been compiled.   If it is cacheable and no conflicting module
    35 // exists, write it out. 
    36 void ParabixObjectCache::notifyObjectCompiled(const Module *M, MemoryBufferRef Obj) {
    37     const std::string &ModuleID = M->getModuleIdentifier();
    38     auto f = cachedObjectMap.find(ModuleID);
    39     if (f!= cachedObjectMap.end()) return;
    40     Path CacheName(CacheDir);
    41     if (!getCacheFilename(ModuleID, CacheName)) return;
    42     if (!CacheDir.empty())      // Re-creating an existing directory is fine.
    43         sys::fs::create_directories(Twine(CacheDir));
    44     std::error_code EC;
    45     raw_fd_ostream outfile(CacheName, EC, sys::fs::F_None);
    46     outfile.write(Obj.getBufferStart(), Obj.getBufferSize());
    47     outfile.close();
    48     auto s = kernelSignatureMap.find(ModuleID);  // Check for a kernel signature.
    49     if (s != kernelSignatureMap.end()) {
    50         if (s->second == ModuleID) return;  // No signature is written when the signature is the ModuleID.
    51         sys::path::replace_extension(CacheName, ".sig");
    52         raw_fd_ostream sigfile(CacheName, EC, sys::fs::F_None);
    53         sigfile << s->second;
    54         sigfile.close();
     42        Module * const module = kernel->getModule();
     43        assert ("kernel module cannot be null!" && module);
     44        const auto moduleId = module->getModuleIdentifier();
     45
     46        // Have we already seen this module before?
     47        if (LLVM_UNLIKELY(mCachedObjectMap.count(moduleId) != 0)) {
     48            const auto f = mKernelSignatureMap.find(moduleId);
     49            if (f == mKernelSignatureMap.end()) {
     50                return kernel->moduleIDisSignature();
     51            } else if (kernel->moduleIDisSignature() || (kernel->makeSignature() != f->second)) {
     52                return false;
     53            }
     54            return true;
     55        }
     56
     57        // No, check for an existing cache file.
     58        Path objectName(mCachePath);
     59        sys::path::append(objectName, mCachePrefix + moduleId + ".o");
     60        auto objectBuffer = MemoryBuffer::getFile(objectName.c_str(), -1, false);
     61        if (objectBuffer) {
     62            if (!kernel->moduleIDisSignature()) {
     63                sys::path::replace_extension(objectName, ".sig");
     64                const auto signatureBuffer = MemoryBuffer::getFile(objectName.c_str(), -1, false);
     65                if (signatureBuffer) {
     66                    const StringRef loadedSig = signatureBuffer.get()->getBuffer();
     67                    if (!loadedSig.equals(kernel->makeSignature())) {
     68                        return false;
     69                    }
     70                } else {
     71                    report_fatal_error("signature file expected but not found: " + moduleId);
     72                    return false;
     73                }
     74            }
     75            // updae the modified time of the file then add it to our cache
     76            boost::filesystem::last_write_time(objectName.c_str(), time(0));
     77            mCachedObjectMap.emplace(moduleId, std::move(objectBuffer.get()));
     78            return true;
     79        } else if (!kernel->moduleIDisSignature()) {
     80            mKernelSignatureMap.emplace(moduleId, kernel->makeSignature());
     81        }
    5582    }
     83    return false;
    5684}
    5785
    58 bool ParabixObjectCache::loadCachedObjectFile(std::string ModuleID, std::string signature) {
    59     // Have we already seen this module before.
    60     auto s = kernelSignatureMap.find(ModuleID);
    61     if (s!= kernelSignatureMap.end()) {
    62         if (s->second != signature) {
     86// A new module has been compiled. If it is cacheable and no conflicting module
     87// exists, write it out.
     88void ParabixObjectCache::notifyObjectCompiled(const Module * M, MemoryBufferRef Obj) {
     89    const auto moduleId = M->getModuleIdentifier();
     90    if (mCachedObjectMap.count(moduleId) == 0) {
    6391
     92        Path objectName(mCachePath);
     93        sys::path::append(objectName, mCachePrefix + moduleId + ".o");
    6494
    65 #ifdef OBJECT_CACHE_DEBUG
    66             std::cerr << "loadCachedObjectFile:  conflicting signatures for the same moduleID! " << ModuleID << std::endl;
    67 #endif
    68             return false;
     95        if (LLVM_LIKELY(!mCachePath.empty())) {
     96            sys::fs::create_directories(Twine(mCachePath));
    6997        }
    70         // A cached entry exists if it has already been loaded.
    71         return cachedObjectMap.count(ModuleID) != 0;
    72     }
    73     // Confirm that the module is cacheable.
    74     Path CachedObjectName(CacheDir);
    75     if (!getCacheFilename(ModuleID, CachedObjectName)) {
    76         return false;
    77     }
    78     //
    79     // Save the signature.
    80     kernelSignatureMap.emplace(ModuleID, signature);
    81     //
    82     // Now checkfor a cache file.
    83     ErrorOr<std::unique_ptr<MemoryBuffer>> KernelObjectBuffer = MemoryBuffer::getFile(CachedObjectName.c_str(), -1, false);
    84     if (!KernelObjectBuffer) return false;
    85     //
    86     if (ModuleID != signature) {
    87         // Confirm the signature.
    88         sys::path::replace_extension(CachedObjectName, ".sig");
    89         ErrorOr<std::unique_ptr<MemoryBuffer>> SignatureBuffer = MemoryBuffer::getFile(CachedObjectName.c_str(), -1, false);
    90         if (!SignatureBuffer) {
    91             report_fatal_error("signature file expected but not found: " + ModuleID);
    92             return false;
    93         }
    94         StringRef loadedSig = SignatureBuffer.get()->getBuffer(); 
    95         if (!loadedSig.equals(signature)) {
    96             report_fatal_error("computed signature does not match stored signature: " + ModuleID);
     98
     99        std::error_code EC;
     100        raw_fd_ostream outfile(objectName, EC, sys::fs::F_None);
     101        outfile.write(Obj.getBufferStart(), Obj.getBufferSize());
     102        outfile.close();
     103
     104        // Check for a kernel signature.
     105        const auto sig = mKernelSignatureMap.find(moduleId);
     106        if (LLVM_UNLIKELY(sig != mKernelSignatureMap.end())) {
     107            sys::path::replace_extension(objectName, ".sig");
     108            raw_fd_ostream sigfile(objectName, EC, sys::fs::F_None);
     109            sigfile << sig->second;
     110            sigfile.close();
    97111        }
    98112    }
    99     // Make a copy so that the JIT engine can freely modify it.
    100     cachedObjectMap.emplace(ModuleID, std::move(KernelObjectBuffer.get()));
    101     return true;
    102113}
    103114
     
    115126
    116127std::unique_ptr<MemoryBuffer> ParabixObjectCache::getObject(const Module* M) {
    117     const std::string &ModuleID = M->getModuleIdentifier();
    118     auto f = cachedObjectMap.find(ModuleID);
    119     if (f == cachedObjectMap.end()) {
     128    auto f = mCachedObjectMap.find(M->getModuleIdentifier());
     129    if (f == mCachedObjectMap.end()) {
    120130        return nullptr;
    121131    }
     
    124134}
    125135
    126 bool ParabixObjectCache::getCacheFilename(const std::string &ModID, Path &CacheName) {
    127     const std::string Prefix("Parabix:");
    128     size_t PrefixLength = Prefix.length();
    129     if (ModID.substr(0, PrefixLength) != Prefix)
    130         return false;
    131     CacheName = CacheDir;
    132     sys::path::append(CacheName, ModID.substr(PrefixLength) + ".o");
    133     return true;
    134 }
  • icGREP/icgrep-devel/icgrep/toolchain/object_cache.h

    r5425 r5431  
    1010#include <llvm/ADT/SmallString.h>
    1111#include <llvm/ExecutionEngine/ObjectCache.h>
    12 #include <llvm/Support/MemoryBuffer.h>
    1312#include <llvm/ADT/StringRef.h>
    1413#include <string>
    15 #include <map>
     14#include <boost/container/flat_map.hpp>
    1615
    1716namespace llvm { class Module; }
     17namespace llvm { class MemoryBuffer; }
     18namespace llvm { class MemoryBufferRef; }
     19namespace kernel { class KernelBuilder; }
    1820
    1921// The ParabixObjectCache is a two-level cache compatible with the requirements
     
    2931//
    3032
    31 class ParabixObjectCache : public llvm::ObjectCache {
    32     public:
    33         ParabixObjectCache(const std::string &dir);
    34         ParabixObjectCache();
    35         virtual ~ParabixObjectCache();
     33class ParabixObjectCache final : public llvm::ObjectCache {
     34    using Path = llvm::SmallString<128>;
     35    template <typename K, typename V>
     36    using Map = boost::container::flat_map<K, V>;
     37    using CacheEntry = std::pair<kernel::KernelBuilder *, std::unique_ptr<llvm::MemoryBuffer>>;
     38    using CacheMap = Map<llvm::Module *, CacheEntry>;
     39public:
    3640
    37         void notifyObjectCompiled(const llvm::Module *M, llvm::MemoryBufferRef Obj) override;
    38         bool loadCachedObjectFile(std::string ModuleID, std::string signature);
    39         std::unique_ptr<llvm::MemoryBuffer> getObject(const llvm::Module* M) override;
    40    
    41     private:
    42         std::map<std::string, std::string> kernelSignatureMap;
    43         std::map<std::string, std::unique_ptr<llvm::MemoryBuffer>> cachedObjectMap;
    44         using Path = llvm::SmallString<128>;
    45         Path CacheDir;
     41//    enum Status {
     42//        Failed
     43//        , Succeeded
     44//        , ObjectFileLocked
     45//    };
    4646
    47         bool getCacheFilename(const std::string & ModID, Path & CacheName);
     47    ParabixObjectCache(const std::string &dir);
     48    ParabixObjectCache();
     49    bool loadCachedObjectFile(kernel::KernelBuilder * const kernel);
     50    void notifyObjectCompiled(const llvm::Module *M, llvm::MemoryBufferRef Obj) override;
     51    std::unique_ptr<llvm::MemoryBuffer> getObject(const llvm::Module * M) override;
     52private:
     53//    CacheMap        mCachedObject;
     54
     55    Map<std::string, std::string>                           mKernelSignatureMap;
     56    Map<std::string, std::unique_ptr<llvm::MemoryBuffer>>   mCachedObjectMap;
     57    Path                                                    mCachePath;
     58    Path                                                    mCachePrefix;
    4859};
    4960
  • icGREP/icgrep-devel/icgrep/toolchain/toolchain.cpp

    r5429 r5431  
    9191   
    9292static cl::opt<bool> segmentPipelineParallel("enable-segment-pipeline-parallel", cl::desc("Enable multithreading with segment pipeline parallelism."), cl::cat(CodeGenOptions));
    93    
    94 #ifdef CUDA_ENABLED
    95 bool NVPTX;
    96 int GroupNum;
    97 static cl::opt<bool> USENVPTX("NVPTX", cl::desc("Run on GPU only."), cl::init(false));
    98 static cl::opt<int, true> GroupNumOption("group-num", cl::location(GroupNum), cl::desc("NUmber of groups declared on GPU"), cl::value_desc("positive integer"), cl::init(256));
    99 #endif
    100 
    101 }
    102 
    103 #ifdef CUDA_ENABLED
    104 void setNVPTXOption(){
    105     codegen::NVPTX = codegen::USENVPTX;
    106 }
    107 
    108 void Compile2PTX (Module * m, std::string IRFilename, std::string PTXFilename) {
    109     InitializeAllTargets();
    110     InitializeAllTargetMCs();
    111     InitializeAllAsmPrinters();
    112     InitializeAllAsmParsers();
    113 
    114     PassRegistry *Registry = PassRegistry::getPassRegistry();
    115     initializeCore(*Registry);
    116     initializeCodeGen(*Registry);
    117     initializeLoopStrengthReducePass(*Registry);
    118     initializeLowerIntrinsicsPass(*Registry);
    119     initializeUnreachableBlockElimPass(*Registry);
    120 
    121     std::error_code error;
    122     raw_fd_ostream out(IRFilename, error, sys::fs::OpenFlags::F_None);
    123     m->print(out, nullptr);
    124 
    125     if (LLVM_UNLIKELY(codegen::DebugOptionIsSet(codegen::ShowIR)))
    126             m->dump();
    127 
    128     llvm2ptx(IRFilename, PTXFilename);
    129 }
    130 #endif
     93
     94}
    13195
    13296void printParabixVersion () {
     
    223187
    224188StreamSetBuffer * ParabixDriver::addBuffer(std::unique_ptr<StreamSetBuffer> b) {
    225     b->allocateBuffer();
     189    b->allocateBuffer(iBuilder.get());
    226190    mOwnedBuffers.emplace_back(std::move(b));
    227191    return mOwnedBuffers.back().get();
     
    229193
    230194kernel::KernelBuilder * ParabixDriver::addKernelInstance(std::unique_ptr<kernel::KernelBuilder> kb) {
     195    kb->setBuilder(iBuilder.get());
    231196    mOwnedKernels.emplace_back(std::move(kb));
    232197    return mOwnedKernels.back().get();
     
    259224    // note: instantiation of all kernels must occur prior to initialization
    260225    for (const auto & k : mPipeline) {
    261         k->addKernelDeclarations(mMainModule);
    262     }
    263 
     226        k->addKernelDeclarations();
     227    }
    264228    for (const auto & k : mPipeline) {
    265229        k->createInstance();
    266230    }
    267 
    268231    for (const auto & k : mPipeline) {
    269232        k->initializeInstance();
    270233    }
    271 
    272234    if (codegen::pipelineParallel) {
    273235        generateParallelPipeline(iBuilder, mPipeline);
     
    278240        generatePipelineLoop(iBuilder, mPipeline);
    279241    }
    280 
    281242    for (const auto & k : mPipeline) {
    282243        k->finalizeInstance();
     
    333294
    334295    PM.run(*m);
     296
    335297    for (kernel::KernelBuilder * const kb : mPipeline) {
    336298        m = kb->getModule();
    337299        bool uncachedObject = true;
    338         if (mCache) {
    339             const std::string moduleID = m->getModuleIdentifier();
    340             const std::string signature = kb->generateKernelSignature(moduleID);
    341             if (mCache->loadCachedObjectFile(moduleID, signature)) {
    342                 uncachedObject = false;
    343             }
     300        if (mCache && mCache->loadCachedObjectFile(kb)) {
     301            uncachedObject = false;
    344302        }
    345303        if (uncachedObject) {
    346             Module * const cm = iBuilder->getModule();
    347             iBuilder->setModule(m);
     304            iBuilder->setModule(kb->getModule());
    348305            kb->generateKernel();
    349306            PM.run(*m);
    350             iBuilder->setModule(cm);
    351         }       
     307        }
    352308        mEngine->addModule(std::unique_ptr<Module>(m));
    353309    }   
    354310    mEngine->finalizeObject();
    355311
     312    iBuilder->setModule(mMainModule);
     313
    356314    delete IROutputStream;
    357315    #ifndef USE_LLVM_3_6
Note: See TracChangeset for help on using the changeset viewer.