Changeset 5837


Ignore:
Timestamp:
Jan 18, 2018, 1:34:55 PM (14 months ago)
Author:
cameron
Message:

Pablo packh/packl and transposition with -enable-pablo-s2p

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

Legend:

Unmodified
Added
Removed
  • icGREP/icgrep-devel/icgrep/IR_Gen/idisa_builder.cpp

    r5832 r5837  
    353353
    354354Value * IDISA_Builder::hsimd_packh(unsigned fw, Value * a, Value * b) {
    355     if (fw < 8) report_fatal_error("Unsupported field width: packh " + std::to_string(fw));
     355    if (fw <= 8) {
     356        const unsigned fw_wkg = 32;
     357        Value * aLo = simd_srli(fw_wkg, a, fw/2);
     358        Value * bLo = simd_srli(fw_wkg, b, fw/2);
     359        return hsimd_packl(fw, aLo, bLo);
     360    }
    356361    Value * aVec = fwCast(fw/2, a);
    357362    Value * bVec = fwCast(fw/2, b);
     
    365370
    366371Value * IDISA_Builder::hsimd_packl(unsigned fw, Value * a, Value * b) {
    367     if (fw < 8) report_fatal_error("Unsupported field width: packl " + std::to_string(fw));
     372    if (fw <= 8) {
     373        const unsigned fw_wkg = 64;
     374        Value * aLo = simd_srli(fw_wkg, a, fw/2);
     375        Value * bLo = simd_srli(fw_wkg, b, fw/2);
     376        return hsimd_packl(fw*2,
     377                           bitCast(simd_or(simd_and(simd_himask(fw), aLo), simd_and(simd_lomask(fw), a))),
     378                           bitCast(simd_or(simd_and(simd_himask(fw), bLo), simd_and(simd_lomask(fw), b))));
     379    }
    368380    Value * aVec = fwCast(fw/2, a);
    369381    Value * bVec = fwCast(fw/2, b);
  • icGREP/icgrep-devel/icgrep/grep_engine.cpp

    r5831 r5837  
    5151
    5252static cl::opt<int> Threads("t", cl::desc("Total number of threads."), cl::init(2));
     53static cl::opt<bool> PabloTransposition("enable-pablo-s2p", cl::desc("Enable experimental pablo transposition."));
    5354
    5455namespace grep {
     
    119120
    120121    StreamSetBuffer * BasisBits = mGrepDriver->addBuffer<CircularBuffer>(idb, idb->getStreamSetTy(encodingBits, 1), baseBufferSize);
    121     kernel::Kernel * s2pk = mGrepDriver->addKernelInstance<kernel::S2PKernel>(idb);
     122    kernel::Kernel * s2pk = nullptr;
     123    if (PabloTransposition) {
     124        s2pk = mGrepDriver->addKernelInstance<kernel::S2P_PabloKernel>(idb);
     125    }
     126    else {
     127        s2pk = mGrepDriver->addKernelInstance<kernel::S2PKernel>(idb);
     128    }
    122129    mGrepDriver->makeKernelCall(s2pk, {ByteStream}, {BasisBits});
    123130
  • icGREP/icgrep-devel/icgrep/kernels/s2p_kernel.cpp

    r5822 r5837  
    11/*
    2  *  Copyright (c) 2016 International Characters.
     2 *  Copyright (c) 2018 International Characters.
    33 *  This software is licensed to the public under the Open Software License 3.0.
    44 */
     
    66#include "s2p_kernel.h"
    77#include <kernels/kernel_builder.h>
     8#include <pablo/pabloAST.h>
     9#include <pablo/builder.hpp>
     10#include <pablo/pe_pack.h>
     11
    812#include <llvm/Support/raw_ostream.h>
    913
     
    212216    }
    213217}
    214 #ifdef PABLO_PACKING
    215218void S2P_PabloKernel::generatePabloMethod() {
    216     auto pb = this->getEntryBlock();
     219    pablo::PabloBlock * const pb = getEntryScope();
    217220    const unsigned steps = std::log2(mCodeUnitWidth);
    218221    std::vector<PabloAST *> streamSet[steps + 1];
    219     streamSet[0].push_back(pb->createExtract(getInputStreamVar("codeUnitStream"), pb->getInteger(0)));
     222    for (unsigned i = 0; i <= steps; i++) {
     223        streamSet[i].resize(1<<i);
     224    }
     225    streamSet[0][0] = pb->createExtract(getInputStreamVar("codeUnitStream"), pb->getInteger(0));
    220226    unsigned streamWidth = mCodeUnitWidth;
    221     for (unsigned step = 1; step <= steps; step++) {
    222         for (auto strm : streamSet[i-1]) {
    223             streamSet[i].push_back(pb.createPackL(streamWidth, strm));
    224             streamSet[i].push_back(pb.createPackH(streamWidth, strm));
     227    for (unsigned i = 1; i <= steps; i++) {
     228        for (unsigned j = 0; j < streamSet[i-1].size(); j++) {
     229            auto strm = streamSet[i-1][j];
     230            streamSet[i][2*j] = pb->createPackL(pb->getInteger(streamWidth), strm);
     231            streamSet[i][2*j+1] = pb->createPackH(pb->getInteger(streamWidth), strm);
    225232        }
    226233        streamWidth = streamWidth/2;
    227234    }
    228     for (unsigned bit = 0; bit <= mCodeUnitWidth, bit++) {
    229         pb.createAssign(pb.createExtract(getInputStreamVar("basisBits"), pb.getInteger(bit)), streamSet[steps][bit]);
     235    for (unsigned bit = 0; bit < mCodeUnitWidth; bit++) {
     236        pb->createAssign(pb->createExtract(getOutputStreamVar("basisBits"), pb->getInteger(bit)), streamSet[steps][mCodeUnitWidth-1-bit]);
    230237    }
    231238}
     
    234241: PabloKernel(b, "s2p_pablo" + std::to_string(codeUnitWidth),
    235242    {Binding{b->getStreamSetTy(1, codeUnitWidth), "codeUnitStream"}},
    236     {Binding{b->getStreamSetTy(codeUnitWidth, 1), "basisBits"}}, {}, {}, {}),
     243    {Binding{b->getStreamSetTy(codeUnitWidth, 1), "basisBits"}}),
    237244  mCodeUnitWidth(codeUnitWidth) {
    238245}
    239246
    240 #endif
    241 
    242 }
     247
     248}
  • icGREP/icgrep-devel/icgrep/kernels/s2p_kernel.h

    r5822 r5837  
    88#include "kernel.h"  // for KernelBuilder
    99
    10 #ifdef PABLO_PACKING
    1110#include <pablo/pablo_kernel.h>
    12 #endif
    1311
    1412namespace IDISA { class IDISA_Builder; }  // lines 14-14
    1513namespace llvm { class Value; }
     14
    1615//#define S2P_MULTIBLOCK
    1716namespace kernel {
     
    3635};
    3736
    38 #ifdef PABLO_PACKING
    39 
    4037class S2P_PabloKernel final : public pablo::PabloKernel {
    4138public:
    42     S2P_PabloKernel(const std::unique_ptr<KernelBuilder> & b, unsigned codeUnitWidth);
     39    S2P_PabloKernel(const std::unique_ptr<KernelBuilder> & b, unsigned codeUnitWidth = 8);
    4340    bool isCachable() const override { return true; }
    4441    bool hasSignature() const override { return false; }
     
    4744    unsigned mCodeUnitWidth;
    4845};
    49 #endif
    5046
    5147}
  • icGREP/icgrep-devel/icgrep/pablo/codegenstate.cpp

    r5836 r5837  
    228228PackH * PabloBlock::createPackH(Integer * fieldWidth, PabloAST * value, const String * const name) {
    229229    assert (fieldWidth && value);
    230     Type * const type = VectorType::get(IntegerType::get(value->getType()->getContext(), fieldWidth->value()), 0);
     230    Type * const type = VectorType::get(IntegerType::get(value->getType()->getContext(), fieldWidth->value()/2), 0);
    231231    return insertAtInsertionPoint(new (mAllocator) PackH(fieldWidth, value, name, type, mAllocator));
    232232}
     
    234234PackL * PabloBlock::createPackL(Integer * fieldWidth, PabloAST * value, const String * const name) {
    235235    assert (fieldWidth && value);
    236     Type * const type = VectorType::get(IntegerType::get(value->getType()->getContext(), fieldWidth->value()), 0);
     236    Type * const type = VectorType::get(IntegerType::get(value->getType()->getContext(), fieldWidth->value()/2), 0);
    237237    return insertAtInsertionPoint(new (mAllocator) PackL(fieldWidth, value, name, type, mAllocator));
    238238}
  • icGREP/icgrep-devel/icgrep/pablo/pablo_compiler.cpp

    r5836 r5837  
    3434#include <kernels/streamset.h>
    3535#include <llvm/IR/Module.h>
     36#include <llvm/IR/Type.h>
    3637#include <llvm/Support/raw_os_ostream.h>
    3738
     
    551552                value = b->CreateZExtOrTrunc(value, ty);
    552553            }
    553         #if 0
    554554        } else if (const PackH * const p = dyn_cast<PackH>(stmt)) {
    555555            const auto sourceWidth = p->getValue()->getType()->getVectorElementType()->getIntegerBitWidth();
    556             const auto packedWidth = p->getFieldWidth()->value();
     556            const auto packWidth = p->getFieldWidth()->value();
     557            assert (sourceWidth == packWidth);
    557558            Value * const base = compileExpression(b, p->getValue(), false);
    558             const auto packs = sourceWidth / 2;
    559             if (LLVM_LIKELY(packs > 1)) {
    560                 value = b->CreateAlloca(b->getBitBlockType(), b->getInt32(packs));
     559            const auto result_packs = sourceWidth/2;
     560            if (LLVM_LIKELY(result_packs > 1)) {
     561                value = b->CreateAlloca(ArrayType::get(b->getBitBlockType(), result_packs));
    561562            }
    562563            Constant * const ZERO = b->getInt32(0);
    563             for (unsigned i = 0; i < packs; ++i) {
     564            for (unsigned i = 0; i < result_packs; ++i) {
    564565                Value * A = b->CreateLoad(b->CreateGEP(base, {ZERO, b->getInt32(i * 2)}));
    565566                Value * B = b->CreateLoad(b->CreateGEP(base, {ZERO, b->getInt32(i * 2 + 1)}));
    566                 Value * P = b->hsimd_packh(packedWidth, A, B);
    567                 if (LLVM_UNLIKELY(packs == 1)) {
     567                Value * P = b->bitCast(b->hsimd_packh(packWidth, A, B));
     568                if (LLVM_UNLIKELY(result_packs == 1)) {
    568569                    value = P;
    569570                    break;
    570571                }
    571                 b->CreateStore(P, b->CreateGEP(value, b->getInt32(i)));
     572                b->CreateStore(P, b->CreateGEP(value, {ZERO, b->getInt32(i)}));
    572573            }
    573574        } else if (const PackL * const p = dyn_cast<PackL>(stmt)) {
    574575            const auto sourceWidth = p->getValue()->getType()->getVectorElementType()->getIntegerBitWidth();
    575             const auto packedWidth = p->getFieldWidth()->value();
     576            const auto packWidth = p->getFieldWidth()->value();
     577            assert (sourceWidth == packWidth);
    576578            Value * const base = compileExpression(b, p->getValue(), false);
    577             const auto count = sourceWidth / 2;
    578             if (LLVM_LIKELY(count > 1)) {
    579                 value = b->CreateAlloca(b->getBitBlockType(), b->getInt32(count));
     579            const auto result_packs = sourceWidth/2;
     580            if (LLVM_LIKELY(result_packs > 1)) {
     581                value = b->CreateAlloca(ArrayType::get(b->getBitBlockType(), result_packs));
    580582            }
    581583            Constant * const ZERO = b->getInt32(0);
    582             for (unsigned i = 0; i < count; ++i) {
     584            for (unsigned i = 0; i < result_packs; ++i) {
    583585                Value * A = b->CreateLoad(b->CreateGEP(base, {ZERO, b->getInt32(i * 2)}));
    584586                Value * B = b->CreateLoad(b->CreateGEP(base, {ZERO, b->getInt32(i * 2 + 1)}));
    585                 Value * P = b->hsimd_packl(packedWidth, A, B);
    586                 if (LLVM_UNLIKELY(count == 1)) {
     587                Value * P = b->bitCast(b->hsimd_packl(packWidth, A, B));
     588                if (LLVM_UNLIKELY(result_packs == 1)) {
    587589                    value = P;
    588590                    break;
    589591                }
    590                 b->CreateStore(P, b->CreateGEP(value, b->getInt32(i)));
    591             }
    592         #endif
     592                b->CreateStore(P, b->CreateGEP(value, {ZERO, b->getInt32(i)}));
     593            }
    593594        } else {
    594595            std::string tmp;
  • icGREP/icgrep-devel/icgrep/pablo/printer_pablos.cpp

    r5836 r5837  
    1818#include <pablo/pe_matchstar.h>
    1919#include <pablo/pe_ones.h>
     20#include <pablo/pe_pack.h>
    2021#include <pablo/pe_repeat.h>
    2122#include <pablo/pe_scanthru.h>
     
    146147            out << ", ";
    147148            print(splat->getValue(), out);
     149            out << ")";
     150        } else if (const PackH * p = dyn_cast<PackH>(stmt)) {
     151            out << " = PackH(";
     152            print(p->getFieldWidth(), out);
     153            out << ", ";
     154            print(p->getValue(), out);
     155            out << ")";
     156        } else if (const PackL * p = dyn_cast<PackL>(stmt)) {
     157            out << " = PackL(";
     158            print(p->getFieldWidth(), out);
     159            out << ", ";
     160            print(p->getValue(), out);
    148161            out << ")";
    149162        } else if (const InFile * e = dyn_cast<InFile>(stmt)) {
Note: See TracChangeset for help on using the changeset viewer.