Changeset 5313 for icGREP


Ignore:
Timestamp:
Feb 11, 2017, 12:05:55 PM (2 years ago)
Author:
cameron
Message:

DeleteByPEXTkernel

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

Legend:

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

    r5304 r5313  
    101101}
    102102
     103   
     104const unsigned PEXT_width = 64;
     105
     106inline std::vector<Value *> get_PEXT_masks(IDISA::IDISA_Builder * iBuilder, Value * del_mask) {
     107    Value * m = iBuilder->fwCast(PEXT_width, iBuilder->simd_not(del_mask));
     108    std::vector<Value *> masks;
     109    for (unsigned i = 0; i < iBuilder->getBitBlockWidth()/PEXT_width; i++) {
     110        masks.push_back(iBuilder->CreateExtractElement(m, i));
     111    }
     112    return masks;
    103113}
     114
     115inline Value * apply_PEXT_deletion(IDISA::IDISA_Builder * iBuilder, const std::vector<Value *> & masks, Value * strm) {
     116    Value * PEXT_func = nullptr;
     117    if (PEXT_width == 64) PEXT_func = Intrinsic::getDeclaration(iBuilder->getModule(), Intrinsic::x86_bmi_pext_64);
     118    else if (PEXT_width == 32) PEXT_func = Intrinsic::getDeclaration(iBuilder->getModule(), Intrinsic::x86_bmi_pext_32);
     119    Value * v = iBuilder->fwCast(PEXT_width, strm);
     120    Value * output = Constant::getNullValue(v->getType());
     121    for (unsigned i = 0; i < iBuilder->getBitBlockWidth()/PEXT_width; i++) {
     122        Value * field = iBuilder->CreateExtractElement(v, i);
     123        Value * compressed = iBuilder->CreateCall(PEXT_func, {field, masks[i]});
     124        output = iBuilder->CreateInsertElement(output, compressed, i);
     125    }
     126    return output;
     127}
     128
     129// Apply deletion to a set of stream_count input streams to produce a set of output streams.
     130// Kernel inputs: stream_count data streams plus one del_mask stream
     131// Outputs: the deleted streams, plus a partial sum popcount
     132
     133void DeleteByPEXTkernel::generateDoBlockMethod() {
     134    Value * delMaskPtr = getInputStream("delMaskSet", iBuilder->getInt32(0));
     135    Value * delMask = iBuilder->CreateBlockAlignedLoad(delMaskPtr);
     136    const auto masks = get_PEXT_masks(iBuilder, delMask);
     137    for (unsigned j = 0; j < mStreamCount; ++j) {
     138        Value * inputStreamPtr = getInputStream("inputStreamSet", iBuilder->getInt32(j));
     139        Value * input = iBuilder->CreateBlockAlignedLoad(inputStreamPtr);
     140        Value * output = apply_PEXT_deletion(iBuilder, masks, input);
     141        Value * outputStreamPtr = getOutputStream("outputStreamSet", iBuilder->getInt32(j));
     142        iBuilder->CreateBlockAlignedStore(iBuilder->bitCast(output), outputStreamPtr);
     143    }
     144    Value * delCount = partial_sum_popcount(iBuilder, mDelCountFieldWidth, apply_PEXT_deletion(iBuilder, masks, iBuilder->simd_not(delMask)));
     145    Value * delCountPtr = getOutputStream("deletionCounts", iBuilder->getInt32(0));
     146    iBuilder->CreateBlockAlignedStore(iBuilder->bitCast(delCount), delCountPtr);
     147}
     148
     149void DeleteByPEXTkernel::generateFinalBlockMethod(Value * remainingBytes) {
     150    IntegerType * vecTy = iBuilder->getIntNTy(iBuilder->getBitBlockWidth());
     151    Value * remaining = iBuilder->CreateZExt(remainingBytes, vecTy);
     152    Value * EOF_del = iBuilder->bitCast(iBuilder->CreateShl(Constant::getAllOnesValue(vecTy), remaining));
     153    Value * const delmaskPtr = getInputStream("delMaskSet", iBuilder->getInt32(0));
     154    Value * delMask = iBuilder->CreateOr(EOF_del, iBuilder->CreateBlockAlignedLoad(delmaskPtr));
     155    const auto masks = get_PEXT_masks(iBuilder, delMask);
     156    for (unsigned j = 0; j < mStreamCount; ++j) {
     157        Value * inputStreamPtr = getInputStream("inputStreamSet", iBuilder->getInt32(j));
     158        Value * input = iBuilder->CreateBlockAlignedLoad(inputStreamPtr);
     159        Value * output = apply_PEXT_deletion(iBuilder, masks, input);
     160        Value * outputStreamPtr = getOutputStream("outputStreamSet", iBuilder->getInt32(j));
     161        iBuilder->CreateBlockAlignedStore(iBuilder->bitCast(output), outputStreamPtr);
     162    }
     163    Value * delCount = partial_sum_popcount(iBuilder, mDelCountFieldWidth, apply_PEXT_deletion(iBuilder, masks, iBuilder->simd_not(delMask)));
     164    Value * delCountPtr = getOutputStream("deletionCounts", iBuilder->getInt32(0));
     165    iBuilder->CreateBlockAlignedStore(iBuilder->bitCast(delCount), delCountPtr);
     166}
     167
     168DeleteByPEXTkernel::DeleteByPEXTkernel(IDISA::IDISA_Builder * iBuilder, unsigned fw, unsigned streamCount)
     169: BlockOrientedKernel(iBuilder, "PEXTdel",
     170                      {Binding{iBuilder->getStreamSetTy(streamCount), "inputStreamSet"},
     171                          Binding{iBuilder->getStreamSetTy(), "delMaskSet"}},
     172                      {Binding{iBuilder->getStreamSetTy(streamCount), "outputStreamSet"},
     173                          Binding{iBuilder->getStreamSetTy(), "deletionCounts"}},
     174                      {}, {}, {})
     175, mDelCountFieldWidth(fw)
     176, mStreamCount(streamCount) {
     177    mDoBlockUpdatesProducedItemCountsAttribute = false;
     178}
     179
     180}
  • icGREP/icgrep-devel/icgrep/kernels/deletion.h

    r5297 r5313  
    3838};
    3939
     40class DeleteByPEXTkernel : public BlockOrientedKernel {
     41public:
     42   
     43    DeleteByPEXTkernel(IDISA::IDISA_Builder * iBuilder, unsigned fw, unsigned streamCount);
     44   
     45protected:
     46   
     47    void generateDoBlockMethod() override;
     48   
     49    void generateFinalBlockMethod(llvm::Value * remainingBytes) override;
     50   
     51private:
     52    const unsigned mDelCountFieldWidth;
     53    const unsigned mStreamCount;
     54};
    4055}
    4156   
Note: See TracChangeset for help on using the changeset viewer.