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

First stage of MultiBlockKernel? and pipeline restructuring

File:
1 edited

Legend:

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

    r5650 r5706  
    33#include <kernels/kernel.h>
    44#include <kernels/streamset.h>
     5#include <llvm/Support/raw_ostream.h>
    56
    67using namespace llvm;
     
    1112namespace kernel {
    1213
     14using Port = Kernel::Port;
     15
    1316Value * KernelBuilder::getScalarFieldPtr(llvm::Value * instance, Value * const index) {
    1417    assert (instance);
    15     CreateAssert(instance, "instance cannot be null!");
     18    CreateAssert(instance, "getScalarFieldPtr: instance cannot be null!");
    1619    return CreateGEP(instance, {getInt32(0), index});
    1720}
     
    3740}
    3841
    39 Value * KernelBuilder::getStreamSetBufferPtr(const std::string & name) {
     42Value * KernelBuilder::getStreamHandle(const std::string & name) {
    4043    Value * const ptr = getScalarField(name + Kernel::BUFFER_PTR_SUFFIX);
    4144    CreateAssert(ptr, name + " cannot be null!");
     
    5154}
    5255
    53 Value * KernelBuilder::getProducedItemCount(const std::string & name, Value * doFinal) {
    54     Kernel::Port port; unsigned index;
    55     std::tie(port, index) = mKernel->getStreamPort(name);
    56     assert (port == Kernel::Port::Output);
    57     const auto & rate = mKernel->getStreamOutput(index).rate;
    58     const auto & refSet = rate.referenceStreamSet();
    59     if ((refSet != name) && rate.isExact()) {
    60         Value * principalCount;
    61         std::tie(port, index) = mKernel->getStreamPort(refSet);
    62         if (port == Kernel::Port::Input) {
    63             principalCount = getProcessedItemCount(refSet);
     56Value * KernelBuilder::getCycleCountPtr() {
     57    return getScalarFieldPtr(Kernel::CYCLECOUNT_SCALAR);
     58}
     59
     60inline const Binding & getBinding(const Kernel * k, const std::string & name) {
     61    Port port; unsigned index;
     62    std::tie(port, index) = k->getStreamPort(name);
     63    if (port == Port::Input) {
     64        return k->getStreamInput(index);
     65    } else {
     66        return k->getStreamOutput(index);
     67    }
     68}
     69
     70Value * KernelBuilder::getInternalItemCount(const std::string & name, const std::string & suffix) {
     71    const ProcessingRate & rate = getBinding(mKernel, name).getRate();
     72    Value * itemCount = nullptr;
     73    if (rate.isExactlyRelative()) {
     74        Port port; unsigned index;
     75        std::tie(port, index) = mKernel->getStreamPort(rate.getReference());
     76        if (port == Port::Input) {
     77            itemCount = getProcessedItemCount(rate.getReference());
    6478        } else {
    65             principalCount = getProducedItemCount(refSet);
    66         }
    67         return rate.CreateRatioCalculation(this, principalCount, doFinal);
    68     }
    69     return getScalarField(name + Kernel::PRODUCED_ITEM_COUNT_SUFFIX);
    70 }
    71 
    72 Value * KernelBuilder::getProcessedItemCount(const std::string & name) {
    73     Kernel::Port port; unsigned index;
    74     std::tie(port, index) = mKernel->getStreamPort(name);
    75     assert (port == Kernel::Port::Input);
    76     const auto & rate = mKernel->getStreamInput(index).rate;
    77     const auto & refSet = rate.referenceStreamSet();
    78     if ((refSet != name) && rate.isExact()) {
    79         Value * const principalCount = getProcessedItemCount(refSet);
    80         return rate.CreateRatioCalculation(this, principalCount);
    81     }
    82     return getScalarField(name + Kernel::PROCESSED_ITEM_COUNT_SUFFIX);
    83 }
     79            itemCount = getProducedItemCount(rate.getReference());
     80        }
     81        if (rate.getNumerator() != 1) {
     82            itemCount = CreateMul(itemCount, ConstantInt::get(itemCount->getType(), rate.getNumerator()));
     83        }
     84        if (rate.getDenominator() != 1) {
     85            itemCount = CreateExactUDiv(itemCount, ConstantInt::get(itemCount->getType(), rate.getDenominator()));
     86        }
     87    } else {
     88        itemCount = getScalarField(name + suffix);
     89    }
     90    return itemCount;
     91}
     92
     93void KernelBuilder::setInternalItemCount(const std::string & name, const std::string & suffix, llvm::Value * const value) {
     94    const ProcessingRate & rate = getBinding(mKernel, name).getRate();
     95    if (LLVM_UNLIKELY(rate.isDerived())) {
     96        report_fatal_error("Cannot set item count: " + name + " is a Derived rate");
     97    }
     98    if (codegen::DebugOptionIsSet(codegen::TraceCounts)) {
     99        CallPrintIntToStderr(mKernel->getName() + ": " + name + suffix, value);
     100    }
     101    setScalarField(name + suffix, value);
     102}
     103
    84104
    85105Value * KernelBuilder::getAvailableItemCount(const std::string & name) {
    86106    const auto & inputs = mKernel->getStreamInputs();
    87107    for (unsigned i = 0; i < inputs.size(); ++i) {
    88         if (inputs[i].name == name) {
     108        if (inputs[i].getName() == name) {
    89109            return mKernel->getAvailableItemCount(i);
    90110        }
     
    93113}
    94114
    95 Value * KernelBuilder::getConsumedItemCount(const std::string & name) {
    96     return getScalarField(name + Kernel::CONSUMED_ITEM_COUNT_SUFFIX);
    97 }
    98 
    99 void KernelBuilder::setProducedItemCount(const std::string & name, Value * value) {
    100     setScalarField(name + Kernel::PRODUCED_ITEM_COUNT_SUFFIX, value);
     115Value * KernelBuilder::getTerminationSignal() {
     116    if (mKernel->hasNoTerminateAttribute()) {
     117        return getFalse();
     118    }
     119    return getScalarField(Kernel::TERMINATION_SIGNAL);
     120}
     121
     122void KernelBuilder::setTerminationSignal(llvm::Value * const value) {
     123    assert (!mKernel->hasNoTerminateAttribute());
     124    assert (value->getType() == getInt1Ty());
    101125    if (codegen::DebugOptionIsSet(codegen::TraceCounts)) {
    102         CallPrintIntToStderr(mKernel->getName() + ": " + name + "_producedItemCount", value);
    103     }
    104 }
    105 
    106 void KernelBuilder::setProcessedItemCount(const std::string & name, Value * value) {
    107     setScalarField(name + Kernel::PROCESSED_ITEM_COUNT_SUFFIX, value);
    108     if (codegen::DebugOptionIsSet(codegen::TraceCounts)) {
    109         CallPrintIntToStderr(mKernel->getName() + ": " + name + "_processedItemCount", value);
    110     }
    111 }
    112 
    113 void KernelBuilder::setConsumedItemCount(const std::string & name, Value * value) {
    114     setScalarField(name + Kernel::CONSUMED_ITEM_COUNT_SUFFIX, value);
    115     if (codegen::DebugOptionIsSet(codegen::TraceCounts)) {
    116         CallPrintIntToStderr(mKernel->getName() + ": " + name + "_consumedItemCount", value);
    117     }
    118 }
    119 
    120 Value * KernelBuilder::getTerminationSignal() {
    121     return getScalarField(Kernel::TERMINATION_SIGNAL);
    122 }
    123 
    124 void KernelBuilder::setTerminationSignal() {
    125     setScalarField(Kernel::TERMINATION_SIGNAL, getTrue());
    126     if (codegen::DebugOptionIsSet(codegen::TraceCounts)) {
    127         CallPrintIntToStderr(mKernel->getName() + ": setTerminationSignal", getTrue());
    128     }
     126        CallPrintIntToStderr(mKernel->getName() + ": setTerminationSignal", value);
     127    }
     128    setScalarField(Kernel::TERMINATION_SIGNAL, value);
    129129}
    130130
    131131Value * KernelBuilder::getLinearlyAccessibleItems(const std::string & name, Value * fromPosition, Value * avail, bool reverse) {
    132     Kernel::Port port; unsigned index;
    133     std::tie(port, index) = mKernel->getStreamPort(name);
    134     const StreamSetBuffer * buf = nullptr;
    135     if (port == Kernel::Port::Input) {
    136         const auto lookAhead = mKernel->getLookAhead(index);
    137         if (LLVM_UNLIKELY(lookAhead != 0)) {
    138             fromPosition = CreateAdd(ConstantInt::get(fromPosition->getType(), lookAhead), fromPosition);
    139         }
    140         buf = mKernel->getInputStreamSetBuffer(name);
    141     } else {
    142         buf = mKernel->getOutputStreamSetBuffer(name);
    143     }
    144     assert (buf);
    145     return buf->getLinearlyAccessibleItems(this, getStreamSetBufferPtr(name), fromPosition, avail, reverse);
     132    const StreamSetBuffer * const buf = mKernel->getInputStreamSetBuffer(name);
     133    return buf->getLinearlyAccessibleItems(this, getStreamHandle(name), fromPosition, avail, reverse);
    146134}
    147135
    148136Value * KernelBuilder::getLinearlyWritableItems(const std::string & name, Value * fromPosition, bool reverse) {
    149137    const StreamSetBuffer * const buf = mKernel->getOutputStreamSetBuffer(name);
    150     return buf->getLinearlyWritableItems(this, getStreamSetBufferPtr(name), fromPosition, reverse);
     138    return buf->getLinearlyWritableItems(this, getStreamHandle(name), fromPosition, reverse);
     139}
     140
     141Value * KernelBuilder::copy(const std::string & name, Value * target, Value * source, Value * itemsToCopy, const unsigned alignment) {
     142    const StreamSetBuffer * const buf = mKernel->getAnyStreamSetBuffer(name);
     143    return buf->copy(this, getStreamHandle(name), target, source, itemsToCopy, alignment);
     144}
     145
     146void KernelBuilder::CreateCopyBack(const std::string & name, llvm::Value * from, llvm::Value * to) {
     147    const StreamSetBuffer * const buf = mKernel->getAnyStreamSetBuffer(name);
     148    return buf->genCopyBackLogic(this, getStreamHandle(name), from, to, name);
    151149}
    152150
     
    168166}
    169167
     168Value * KernelBuilder::getInputStreamPtr(const std::string & name, Value * const blockIndex) {
     169//    Value * const blockIndex = computeBlockIndex(getProcessedItemCount(name));
     170    const StreamSetBuffer * const buf = mKernel->getInputStreamSetBuffer(name);
     171    return buf->getBlockAddress(this, getStreamHandle(name), blockIndex);
     172}
     173
    170174Value * KernelBuilder::getInputStreamBlockPtr(const std::string & name, Value * streamIndex) {
    171     Value * const blockIndex = computeBlockIndex(getProcessedItemCount(name));
    172     const StreamSetBuffer * const buf = mKernel->getInputStreamSetBuffer(name);
    173     return buf->getStreamBlockPtr(this, getStreamSetBufferPtr(name), streamIndex, blockIndex, true);
     175    const Kernel::StreamPort p = mKernel->getStreamPort(name);
     176    if (LLVM_UNLIKELY(p.first == Port::Output)) {
     177        report_fatal_error(name + " is not an input stream set");
     178    }
     179    Value * const addr = mKernel->getStreamSetInputBufferPtr(p.second);
     180    const StreamSetBuffer * const buf = mKernel->getInputStreamSetBuffer(name);
     181    return buf->getStreamBlockPtr(this, getStreamHandle(name), addr, streamIndex, true);
    174182}
    175183
     
    179187
    180188Value * KernelBuilder::getInputStreamPackPtr(const std::string & name, Value * streamIndex, Value * packIndex) {
    181     Value * const blockIndex = computeBlockIndex(getProcessedItemCount(name));
    182     const StreamSetBuffer * const buf = mKernel->getInputStreamSetBuffer(name);
    183     return buf->getStreamPackPtr(this, getStreamSetBufferPtr(name), streamIndex, blockIndex, packIndex, true);
     189    const Kernel::StreamPort p = mKernel->getStreamPort(name);
     190    if (LLVM_UNLIKELY(p.first == Port::Output)) {
     191        report_fatal_error(name + " is not an input stream set");
     192    }
     193    Value * const addr = mKernel->getStreamSetInputBufferPtr(p.second);
     194    const StreamSetBuffer * const buf = mKernel->getInputStreamSetBuffer(name);
     195    return buf->getStreamPackPtr(this, getStreamHandle(name), addr, streamIndex, packIndex, true);
    184196}
    185197
     
    190202Value * KernelBuilder::getInputStreamSetCount(const std::string & name) {
    191203    const StreamSetBuffer * const buf = mKernel->getInputStreamSetBuffer(name);
    192     return buf->getStreamSetCount(this, getStreamSetBufferPtr(name));
     204    return buf->getStreamSetCount(this, getStreamHandle(name));
    193205}
    194206
    195207Value * KernelBuilder::getAdjustedInputStreamBlockPtr(Value * blockAdjustment, const std::string & name, Value * streamIndex) {
    196     Value * const blockIndex = CreateAdd(computeBlockIndex(getProcessedItemCount(name)), blockAdjustment);
    197     const StreamSetBuffer * const buf = mKernel->getInputStreamSetBuffer(name);
    198     return buf->getStreamBlockPtr(this, getStreamSetBufferPtr(name), streamIndex, blockIndex, true);
     208    const Kernel::StreamPort p = mKernel->getStreamPort(name);
     209    if (LLVM_UNLIKELY(p.first == Port::Output)) {
     210        report_fatal_error(name + " is not an input stream set");
     211    }
     212    Value * const addr = mKernel->getStreamSetInputBufferPtr(p.second);
     213    const StreamSetBuffer * const buf = mKernel->getInputStreamSetBuffer(name);
     214    return buf->getStreamBlockPtr(this, getStreamHandle(name), CreateGEP(addr, blockAdjustment), streamIndex, true);
     215}
     216
     217Value * KernelBuilder::getOutputStreamPtr(const std::string & name, Value * const blockIndex) {
     218//    Value * const blockIndex = computeBlockIndex(getProducedItemCount(name));
     219    const StreamSetBuffer * const buf = mKernel->getOutputStreamSetBuffer(name);
     220    return buf->getBlockAddress(this, getStreamHandle(name), blockIndex);
    199221}
    200222
    201223Value * KernelBuilder::getOutputStreamBlockPtr(const std::string & name, Value * streamIndex) {
    202     Value * const blockIndex = computeBlockIndex(getProducedItemCount(name));
    203     const StreamSetBuffer * const buf = mKernel->getOutputStreamSetBuffer(name);
    204     return buf->getStreamBlockPtr(this, getStreamSetBufferPtr(name), streamIndex, blockIndex, false);
     224    const Kernel::StreamPort p = mKernel->getStreamPort(name);
     225    if (LLVM_UNLIKELY(p.first == Port::Input)) {
     226        report_fatal_error(name + " is not an output stream set");
     227    }
     228    Value * addr = mKernel->getStreamSetOutputBufferPtr(p.second);
     229    const StreamSetBuffer * const buf = mKernel->getOutputStreamSetBuffer(name);
     230    return buf->getStreamBlockPtr(this, getStreamHandle(name), addr, streamIndex, true);
    205231}
    206232
     
    210236
    211237Value * KernelBuilder::getOutputStreamPackPtr(const std::string & name, Value * streamIndex, Value * packIndex) {
    212     Value * const blockIndex = computeBlockIndex(getProducedItemCount(name));
    213     const StreamSetBuffer * const buf = mKernel->getOutputStreamSetBuffer(name);
    214     return buf->getStreamPackPtr(this, getStreamSetBufferPtr(name), streamIndex, blockIndex, packIndex, false);
     238    const Kernel::StreamPort p = mKernel->getStreamPort(name);
     239    if (LLVM_UNLIKELY(p.first == Port::Input)) {
     240        report_fatal_error(name + " is not an output stream set");
     241    }
     242    Value * addr = mKernel->getStreamSetOutputBufferPtr(p.second);
     243    const StreamSetBuffer * const buf = mKernel->getOutputStreamSetBuffer(name);
     244    return buf->getStreamPackPtr(this, getStreamHandle(name), addr, streamIndex, packIndex, false);
    215245}
    216246
     
    221251Value * KernelBuilder::getOutputStreamSetCount(const std::string & name) {
    222252    const StreamSetBuffer * const buf = mKernel->getOutputStreamSetBuffer(name);
    223     return buf->getStreamSetCount(this, getStreamSetBufferPtr(name));
    224 }
    225 
    226 Value * KernelBuilder::getRawInputPointer(const std::string & name, Value * streamIndex, Value * absolutePosition) {
    227     const StreamSetBuffer * const buf = mKernel->getInputStreamSetBuffer(name);
    228     return buf->getRawItemPointer(this, getStreamSetBufferPtr(name), streamIndex, absolutePosition);
    229 }
    230 
    231 Value * KernelBuilder::getRawOutputPointer(const std::string & name, Value * streamIndex, Value * absolutePosition) {
    232     const StreamSetBuffer * const buf = mKernel->getOutputStreamSetBuffer(name);
    233     return buf->getRawItemPointer(this, getStreamSetBufferPtr(name), streamIndex, absolutePosition);
     253    return buf->getStreamSetCount(this, getStreamHandle(name));
     254}
     255
     256Value * KernelBuilder::getRawInputPointer(const std::string & name, Value * absolutePosition) {
     257    const StreamSetBuffer * const buf = mKernel->getInputStreamSetBuffer(name);
     258    return buf->getRawItemPointer(this, getStreamHandle(name), absolutePosition);
     259}
     260
     261Value * KernelBuilder::getRawOutputPointer(const std::string & name, Value * absolutePosition) {
     262    const StreamSetBuffer * const buf = mKernel->getOutputStreamSetBuffer(name);
     263    return buf->getRawItemPointer(this, getStreamHandle(name), absolutePosition);
    234264}
    235265
    236266Value * KernelBuilder::getBaseAddress(const std::string & name) {
    237     return mKernel->getAnyStreamSetBuffer(name)->getBaseAddress(this, getStreamSetBufferPtr(name));
     267    return mKernel->getAnyStreamSetBuffer(name)->getBaseAddress(this, getStreamHandle(name));
    238268}
    239269
    240270void KernelBuilder::setBaseAddress(const std::string & name, Value * const addr) {
    241     return mKernel->getAnyStreamSetBuffer(name)->setBaseAddress(this, getStreamSetBufferPtr(name), addr);
     271    return mKernel->getAnyStreamSetBuffer(name)->setBaseAddress(this, getStreamHandle(name), addr);
    242272}
    243273
    244274Value * KernelBuilder::getBufferedSize(const std::string & name) {
    245     return mKernel->getAnyStreamSetBuffer(name)->getBufferedSize(this, getStreamSetBufferPtr(name));
     275    return mKernel->getAnyStreamSetBuffer(name)->getBufferedSize(this, getStreamHandle(name));
    246276}
    247277
    248278void KernelBuilder::setBufferedSize(const std::string & name, Value * size) {
    249     mKernel->getAnyStreamSetBuffer(name)->setBufferedSize(this, getStreamSetBufferPtr(name), size);
     279    mKernel->getAnyStreamSetBuffer(name)->setBufferedSize(this, getStreamHandle(name), size);
    250280}
    251281
    252282
    253283Value * KernelBuilder::getCapacity(const std::string & name) {
    254     return mKernel->getAnyStreamSetBuffer(name)->getCapacity(this, getStreamSetBufferPtr(name));
     284    return mKernel->getAnyStreamSetBuffer(name)->getCapacity(this, getStreamHandle(name));
    255285}
    256286
    257287void KernelBuilder::setCapacity(const std::string & name, Value * c) {
    258     mKernel->getAnyStreamSetBuffer(name)->setCapacity(this, getStreamSetBufferPtr(name), c);
     288    mKernel->getAnyStreamSetBuffer(name)->setCapacity(this, getStreamHandle(name), c);
    259289}
    260290
    261291   
    262292CallInst * KernelBuilder::createDoSegmentCall(const std::vector<Value *> & args) {
    263     Function * const doSegment = mKernel->getDoSegmentFunction(getModule());
    264     assert (doSegment->getArgumentList().size() == args.size());
    265     return CreateCall(doSegment, args);
     293//    Function * const doSegment = mKernel->getDoSegmentFunction(getModule());
     294//    assert (doSegment->getArgumentList().size() == args.size());
     295//    return CreateCall(doSegment, args);
     296    return mKernel->makeDoSegmentCall(*this, args);
    266297}
    267298
     
    278309        for (unsigned i = 0; i < n; ++i) {
    279310            const Binding & b = outputs[i];
    280             if (b.name == accumName) {
     311            if (b.getName() == accumName) {
    281312                if (n == 1) {
    282313                    return results;
     
    307338        BasicBlock * wait[n];
    308339        for (unsigned i = 0; i < n; ++i) {
    309             load[i] = BasicBlock::Create(getContext(), consumers[i].name + "Load", parent);
    310             wait[i] = BasicBlock::Create(getContext(), consumers[i].name + "Wait", parent);
     340            load[i] = BasicBlock::Create(getContext(), consumers[i].getName() + "Load", parent);
     341            wait[i] = BasicBlock::Create(getContext(), consumers[i].getName() + "Wait", parent);
    311342        }
    312343        load[n] = BasicBlock::Create(getContext(), "Resume", parent);
     
    315346
    316347            SetInsertPoint(load[i]);
    317             Value * const outputConsumers = getConsumerLock(consumers[i].name);
     348            Value * const outputConsumers = getConsumerLock(consumers[i].getName());
    318349
    319350            Value * const consumerCount = CreateLoad(CreateGEP(outputConsumers, {zero, zero}));
Note: See TracChangeset for help on using the changeset viewer.