Ignore:
Timestamp:
Apr 9, 2017, 3:59:17 PM (2 years ago)
Author:
nmedfort
Message:

Updated all projects to use ParabixDriver?. Deprecated original pipeline generation methods. Enabled LLVM optimizations, IR and ASM printing for Kernel modules. Enabled object cache by default. Begun work on moving consumed position information back to producing kernels.

Location:
icGREP/icgrep-devel/icgrep/kernels
Files:
7 edited

Legend:

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

    r5398 r5401  
    2222using namespace llvm;
    2323
    24 ProcessingRate FixedRatio(unsigned strmItemsPer, unsigned perPrincipalInputItems, std::string referenceStreamSet) {
    25     return ProcessingRate(ProcessingRate::ProcessingRateKind::Fixed, strmItemsPer, perPrincipalInputItems, referenceStreamSet);
     24ProcessingRate FixedRatio(unsigned strmItemsPer, unsigned perPrincipalInputItems, std::string && referenceStreamSet) {
     25    return ProcessingRate(ProcessingRate::ProcessingRateKind::Fixed, strmItemsPer, perPrincipalInputItems, std::move(referenceStreamSet));
    2626}
    2727
    28 ProcessingRate MaxRatio(unsigned strmItemsPer, unsigned perPrincipalInputItems, std::string referenceStreamSet) {
    29     return ProcessingRate(ProcessingRate::ProcessingRateKind::Max, strmItemsPer, perPrincipalInputItems, referenceStreamSet);
     28ProcessingRate MaxRatio(unsigned strmItemsPer, unsigned perPrincipalInputItems, std::string && referenceStreamSet) {
     29    return ProcessingRate(ProcessingRate::ProcessingRateKind::Max, strmItemsPer, perPrincipalInputItems, std::move(referenceStreamSet));
    3030}
    3131
    32 ProcessingRate RoundUpToMultiple(unsigned itemMultiple, std::string referenceStreamSet) {
    33     return ProcessingRate(ProcessingRate::ProcessingRateKind::RoundUp, itemMultiple, itemMultiple, referenceStreamSet);
     32ProcessingRate RoundUpToMultiple(unsigned itemMultiple, std::string && referenceStreamSet) {
     33    return ProcessingRate(ProcessingRate::ProcessingRateKind::RoundUp, itemMultiple, itemMultiple, std::move(referenceStreamSet));
    3434}
    3535
    36 ProcessingRate Add1(std::string referenceStreamSet) {
    37     return ProcessingRate(ProcessingRate::ProcessingRateKind::Add1, 0, 0, referenceStreamSet);
     36ProcessingRate Add1(std::string && referenceStreamSet) {
     37    return ProcessingRate(ProcessingRate::ProcessingRateKind::Add1, 0, 0, std::move(referenceStreamSet));
    3838}
    3939
     
    9494    }
    9595
    96     // Create the doSegment function prototype.
     96    /// INVESTIGATE: should we explicitly mark whether to track a kernel output's consumed amount? It would have
     97    /// to be done at the binding level using the current architecture. It would reduce the number of arguments
     98    /// passed between kernels.
     99
     100    // Create the doSegment function prototype.   
     101    IntegerType * const sizeTy = iBuilder->getSizeTy();
     102
    97103    std::vector<Type *> params = {selfType, iBuilder->getInt1Ty()};
    98     // const auto count = mStreamSetInputs.size() + mStreamSetOutputs.size();
    99     for (unsigned i = 0; i < mStreamSetInputs.size(); ++i) {
    100         params.push_back(iBuilder->getSizeTy());
     104    params.insert(params.end(), mStreamSetInputs.size() + mStreamSetOutputs.size(), sizeTy);
     105
     106    Type * retType = nullptr;
     107    if (mStreamSetInputs.empty()) {
     108        retType = iBuilder->getVoidTy();
     109    } else {
     110        retType = ArrayType::get(sizeTy, mStreamSetInputs.size());
    101111    }
    102112
    103     FunctionType * doSegmentType = FunctionType::get(iBuilder->getVoidTy(), params, false);
     113    FunctionType * const doSegmentType = FunctionType::get(retType, params, false);
    104114    Function * doSegment = Function::Create(doSegmentType, GlobalValue::ExternalLinkage, getName() + DO_SEGMENT_SUFFIX, client);
    105115    doSegment->setCallingConv(CallingConv::C);
     
    112122        (++args)->setName(input.name + "_availableItems");
    113123    }
    114 //    for (const Binding & output : mStreamSetOutputs) {
    115 //        (++args)->setName(output.name + "_consumedItems");
    116 //    }
     124    for (const Binding & output : mStreamSetOutputs) {
     125        (++args)->setName(output.name + "_consumedItems");
     126    }
     127
     128    /// INVESTIGATE: replace the accumulator methods with a single Exit method that handles any clean up and returns
     129    /// a struct containing all scalar outputs?
    117130
    118131    // Create the accumulator get function prototypes
  • icGREP/icgrep-devel/icgrep/kernels/interface.h

    r5398 r5401  
    3939
    4040struct ProcessingRate  {
    41     enum ProcessingRateKind : uint8_t {Fixed, RoundUp, Max, Add1, Unknown};
    42     ProcessingRate() {}
     41    enum class ProcessingRateKind : uint8_t { Fixed, RoundUp, Add1, Max, Unknown };
    4342    ProcessingRateKind getKind() const {return mKind;}
    44     bool isExact() const {return (mKind == Fixed)||(mKind == RoundUp)||(mKind == Add1) ;}
     43    bool isExact() const {return (mKind == ProcessingRateKind::Fixed)||(mKind == ProcessingRateKind::RoundUp)||(mKind == ProcessingRateKind::Add1) ;}
    4544    bool isUnknown() const { return !isExact(); }
    4645    llvm::Value * CreateRatioCalculation(IDISA::IDISA_Builder * b, llvm::Value * principalInputItems, llvm::Value * doFinal = nullptr) const;
    47     friend ProcessingRate FixedRatio(unsigned strmItemsPer, unsigned perPrincipalInputItems, std::string referenceStreamSet);
    48     friend ProcessingRate MaxRatio(unsigned strmItemsPer, unsigned perPrincipalInputItems, std::string referenceStreamSet);
    49     friend ProcessingRate RoundUpToMultiple(unsigned itemMultiple, std::string referenceStreamSet);   
    50     friend ProcessingRate Add1(std::string referenceStreamSet);
     46    friend ProcessingRate FixedRatio(unsigned strmItemsPer, unsigned perPrincipalInputItems, std::string && referenceStreamSet);
     47    friend ProcessingRate MaxRatio(unsigned strmItemsPer, unsigned perPrincipalInputItems, std::string && referenceStreamSet);
     48    friend ProcessingRate RoundUpToMultiple(unsigned itemMultiple, std::string && referenceStreamSet);
     49    friend ProcessingRate Add1(std::string && referenceStreamSet);
    5150    friend ProcessingRate UnknownRate();
    5251    std::string referenceStreamSet() const { return mReferenceStreamSet;}
    5352protected:
    54     ProcessingRate(ProcessingRateKind k, unsigned numerator, unsigned denominator, std::string referenceStreamSet)
     53    ProcessingRate(ProcessingRateKind k, unsigned numerator, unsigned denominator, std::string && referenceStreamSet)
    5554    : mKind(k), mRatioNumerator(numerator), mRatioDenominator(denominator), mReferenceStreamSet(referenceStreamSet) {}
    5655private:
    57     ProcessingRateKind mKind;
    58     uint16_t mRatioNumerator;
    59     uint16_t mRatioDenominator;
    60     std::string mReferenceStreamSet;
     56    const ProcessingRateKind mKind;
     57    const uint16_t mRatioNumerator;
     58    const uint16_t mRatioDenominator;
     59    const std::string mReferenceStreamSet;
    6160};
    6261
    63 ProcessingRate FixedRatio(unsigned strmItemsPer, unsigned perPrincipalInputItems = 1, std::string referenceStreamSet = "");
    64 ProcessingRate MaxRatio(unsigned strmItemsPer, unsigned perPrincipalInputItems = 1, std::string referenceStreamSet = "");
    65 ProcessingRate RoundUpToMultiple(unsigned itemMultiple, std::string referenceStreamSet = "");
    66 ProcessingRate Add1(std::string referenceStreamSet = "");
     62ProcessingRate FixedRatio(unsigned strmItemsPer, unsigned perPrincipalInputItems = 1, std::string && referenceStreamSet = "");
     63ProcessingRate MaxRatio(unsigned strmItemsPer, unsigned perPrincipalInputItems = 1, std::string && referenceStreamSet = "");
     64ProcessingRate RoundUpToMultiple(unsigned itemMultiple, std::string &&referenceStreamSet = "");
     65ProcessingRate Add1(std::string && referenceStreamSet = "");
    6766ProcessingRate UnknownRate();
    6867
     
    7069    Binding(llvm::Type * type, const std::string & name, ProcessingRate r = FixedRatio(1))
    7170    : type(type), name(name), rate(r) { }
    72     llvm::Type *        type;
    73     std::string         name;
    74     ProcessingRate      rate;
     71    llvm::Type * const        type;
     72    const std::string         name;
     73    const ProcessingRate      rate;
    7574};
    7675
  • icGREP/icgrep-devel/icgrep/kernels/kernel.cpp

    r5399 r5401  
    120120}
    121121
    122 std::unique_ptr<Module> KernelBuilder::createKernelStub(const StreamSetBuffers & inputs, const StreamSetBuffers & outputs) {
     122Module * KernelBuilder::createKernelStub(const StreamSetBuffers & inputs, const StreamSetBuffers & outputs) {
    123123    setCallParameters(inputs, outputs);
    124124    std::string cacheName = getName() + "_" + iBuilder->getBuilderUniqueName();
     
    130130    }
    131131    prepareKernel();
    132     return make_unique<Module>(cacheName, iBuilder->getContext());
     132    return new Module(cacheName, iBuilder->getContext());
    133133}
    134134
     
    162162}   
    163163
    164 
    165164// Default kernel signature: generate the IR and emit as byte code.
    166 void KernelBuilder::generateKernelSignature(std::string &signature) {
    167     generateKernel();
    168     raw_string_ostream OS(signature);
    169     WriteBitcodeToFile(iBuilder->getModule(), OS);
    170 }
    171 
    172 
    173 std::unique_ptr<Module> KernelBuilder::createKernelModule(const StreamSetBuffers & inputs, const StreamSetBuffers & outputs) {
    174     auto saveModule = iBuilder->getModule();
    175     auto savePoint = iBuilder->saveIP();
    176     auto module = createKernelStub(inputs, outputs);
    177     iBuilder->setModule(module.get());
    178     generateKernel(inputs, outputs);
    179     iBuilder->setModule(saveModule);
    180     iBuilder->restoreIP(savePoint);
    181     return module;
    182 }
    183 
    184 void KernelBuilder::generateKernel(const StreamSetBuffers & inputs, const StreamSetBuffers & outputs) {
    185     setCallParameters(inputs, outputs);
    186     prepareKernel(); // possibly overridden by the KernelBuilder subtype
    187     generateKernel();
     165std::string KernelBuilder::generateKernelSignature(std::string moduleId) {
     166    if (moduleIDisSignature()) {
     167        return moduleId;
     168    } else {
     169        generateKernel();
     170        std::string signature;
     171        raw_string_ostream OS(signature);
     172        WriteBitcodeToFile(iBuilder->getModule(), OS);
     173        return signature;
     174    }
    188175}
    189176
    190177void KernelBuilder::generateKernel() {
    191     if (mIsGenerated) return;
    192     auto savePoint = iBuilder->saveIP();
    193     addKernelDeclarations(iBuilder->getModule());
    194     callGenerateInitMethod();
    195     callGenerateDoSegmentMethod();
    196     // Implement the accumulator get functions
    197     for (auto binding : mScalarOutputs) {
    198         Function * f = getAccumulatorFunction(binding.name);
    199         iBuilder->SetInsertPoint(BasicBlock::Create(iBuilder->getContext(), "get_" + binding.name, f));
    200         Value * self = &*(f->arg_begin());
    201         Value * ptr = iBuilder->CreateGEP(self, {iBuilder->getInt32(0), getScalarIndex(binding.name)});
    202         Value * retVal = iBuilder->CreateLoad(ptr);
    203         iBuilder->CreateRet(retVal);
    204     }
    205     iBuilder->restoreIP(savePoint);
    206     mIsGenerated = true;
     178    // If the module id is cannot uniquely identify this kernel, "generateKernelSignature()" will have already
     179    // generated the unoptimized IR.
     180    if (!mIsGenerated) {
     181        auto savePoint = iBuilder->saveIP();
     182        addKernelDeclarations(iBuilder->getModule());
     183        callGenerateInitMethod();
     184        callGenerateDoSegmentMethod();
     185        // Implement the accumulator get functions
     186        for (auto binding : mScalarOutputs) {
     187            Function * f = getAccumulatorFunction(binding.name);
     188            iBuilder->SetInsertPoint(BasicBlock::Create(iBuilder->getContext(), "get_" + binding.name, f));
     189            Value * self = &*(f->arg_begin());
     190            Value * ptr = iBuilder->CreateGEP(self, {iBuilder->getInt32(0), getScalarIndex(binding.name)});
     191            Value * retVal = iBuilder->CreateLoad(ptr);
     192            iBuilder->CreateRet(retVal);
     193        }
     194        iBuilder->restoreIP(savePoint);
     195        mIsGenerated = true;
     196    }
    207197}
    208198
     
    218208    }
    219209    generateDoSegmentMethod(doFinal, producerPos); // must be overridden by the KernelBuilder subtype
    220     iBuilder->CreateRetVoid();
     210    if (LLVM_UNLIKELY(mStreamSetInputs.empty())) {
     211        iBuilder->CreateRetVoid();
     212    } else {
     213        const unsigned n = mStreamSetInputs.size();
     214        Value * values[n];
     215        for (unsigned i = 0; i < n; ++i) {
     216            values[i] = getProcessedItemCount(mStreamSetInputs[i].name);
     217        }
     218        iBuilder->CreateAggregateRet(values, n);
     219    }
    221220}
    222221
  • icGREP/icgrep-devel/icgrep/kernels/kernel.h

    r5399 r5401  
    6060   
    6161    // Can the module ID itself serve as the unique signature?
    62     virtual bool moduleIDisSignature() {/* default */  return false;}
    63    
    64     virtual void generateKernelSignature(std::string & signature);
     62    virtual bool moduleIDisSignature() { return false; }
     63   
     64    virtual std::string generateKernelSignature(std::string moduleId);
    6565   
    6666    // Create a module stub for the kernel, populated only with its Module ID.     
    6767    //
    68     std::unique_ptr<llvm::Module> createKernelStub(const StreamSetBuffers & inputs, const StreamSetBuffers & outputs);
    69    
    70     // Create a module for the kernel, including the kernel state type declaration and
    71     // the full implementation of all required methods.     
    72     //
    73     std::unique_ptr<llvm::Module> createKernelModule(const StreamSetBuffers & inputs, const StreamSetBuffers & outputs);
    74    
     68    llvm::Module * createKernelStub(const StreamSetBuffers & inputs, const StreamSetBuffers & outputs);
     69     
    7570    void setCallParameters(const StreamSetBuffers & inputs, const StreamSetBuffers & outputs);
    7671
    7772    // Generate the Kernel to the current module (iBuilder->getModule()).
    7873    void generateKernel();
    79     void generateKernel(const StreamSetBuffers & inputs, const StreamSetBuffers & outputs);
    8074   
    8175    void createInstance() override;
  • icGREP/icgrep-devel/icgrep/kernels/linebreak_kernel.cpp

    r5399 r5401  
    2626LineBreakKernelBuilder::LineBreakKernelBuilder (
    2727IDISA::IDISA_Builder * iBuilder
    28 , std::string linebreak
    2928, unsigned basisBitsCount)
    30 : PabloKernel(iBuilder, "Parabix:" + linebreak + "_kernel", {Binding{iBuilder->getStreamSetTy(basisBitsCount), "basis"}}, {Binding{iBuilder->getStreamSetTy(1), "linebreak", Add1()}}) {
     29: PabloKernel(iBuilder, "Parabix:lb_kernel", {Binding{iBuilder->getStreamSetTy(basisBitsCount), "basis"}}, {Binding{iBuilder->getStreamSetTy(1), "linebreak", Add1()}}) {
    3130
    3231    CC_Compiler ccc(this, getInput(0));
  • icGREP/icgrep-devel/icgrep/kernels/linebreak_kernel.h

    r5398 r5401  
    1515class LineBreakKernelBuilder: public pablo::PabloKernel {
    1616public:
    17     LineBreakKernelBuilder(IDISA::IDISA_Builder * iBuilder, std::string linebreak, unsigned basisBitsCount);
     17    LineBreakKernelBuilder(IDISA::IDISA_Builder * iBuilder, unsigned basisBitsCount);
    1818    bool moduleIDisSignature() override {return true;}
    1919};
  • icGREP/icgrep-devel/icgrep/kernels/pipeline.cpp

    r5398 r5401  
    487487        Value * const instance = kernel->getInstance();
    488488        std::vector<Value *> args = {instance, terminated};
    489         for (unsigned j = 0; j < kernel->getStreamInputs().size(); j++) {
     489        for (unsigned i = 0; i < kernel->getStreamInputs().size(); ++i) {
    490490            unsigned producerKernel, outputIndex;
    491             std::tie(producerKernel, outputIndex) = producer[k][j];
     491            std::tie(producerKernel, outputIndex) = producer[k][i];
    492492            args.push_back(ProducerPos[producerKernel][outputIndex]);
     493        }
     494        for (unsigned i = 0; i < kernel->getStreamOutputs().size(); ++i) {
     495            args.push_back(iBuilder->getSize(0));
    493496        }
    494497        kernel->createDoSegmentCall(args);
     
    502505        }
    503506        ProducerPos.push_back(produced);
    504         Value * segNo = kernel->acquireLogicalSegmentNo(instance);
     507        Value * const segNo = kernel->acquireLogicalSegmentNo(instance);
    505508        kernel->releaseLogicalSegmentNo(instance, iBuilder->CreateAdd(segNo, iBuilder->getSize(1)));
    506509    }
Note: See TracChangeset for help on using the changeset viewer.