source: icGREP/icgrep-devel/icgrep/kernels/cc_kernel.cpp @ 5828

Last change on this file since 5828 was 5828, checked in by nmedfort, 15 months ago

Pablo support for byte comparisions; LineFeed? kernel processes byte streams directly. Some clean up of PabloBuilder? functionality.

File size: 5.3 KB
RevLine 
[5140]1/*
2 *  Copyright (c) 2016 International Characters.
3 *  This software is licensed to the public under the Open Software License 3.0.
4 */
5
6#include "cc_kernel.h"
[5217]7#include <re/re_cc.h>
8#include <cc/cc_compiler.h>
9#include <pablo/builder.hpp>
[5436]10#include <kernels/kernel_builder.h>
[5140]11
[5217]12using namespace cc;
[5140]13using namespace kernel;
[5217]14using namespace pablo;
15using namespace re;
[5267]16using namespace llvm;
[5140]17
[5435]18DirectCharacterClassKernelBuilder::DirectCharacterClassKernelBuilder(
[5436]19        const std::unique_ptr<kernel::KernelBuilder> & b, std::string ccSetName, std::vector<re::CC *> charClasses, unsigned codeUnitSize)
[5435]20: BlockOrientedKernel(std::move(ccSetName),
[5823]21              {Binding{b->getStreamSetTy(1, 8 * codeUnitSize), "codeUnitStream", FixedRate(), Principal()}},
[5435]22              {Binding{b->getStreamSetTy(charClasses.size(), 1), "ccStream"}},
23              {}, {}, {})
24, mCharClasses(charClasses)
25, mCodeUnitSize(codeUnitSize) {
26
27}
28
[5440]29void DirectCharacterClassKernelBuilder::generateDoBlockMethod(const std::unique_ptr<KernelBuilder> & iBuilder) {
[5140]30    unsigned packCount = 8 * mCodeUnitSize; 
31    unsigned codeUnitWidth = 8 * mCodeUnitSize;
[5823]32    unsigned topBit = 1 << codeUnitWidth;
33    unsigned maxCodeVal = (topBit - 1) | topBit;
[5140]34    Value * codeUnitPack[packCount];
35    for (unsigned i = 0; i < packCount; i++) {
[5440]36        codeUnitPack[i] = iBuilder->loadInputStreamPack("codeUnitStream", iBuilder->getInt32(0), iBuilder->getInt32(i));
[5140]37    }
38    for (unsigned j = 0; j < mCharClasses.size();  j++) {
39        Value * theCCstream = iBuilder->allZeroes();
40        for (const auto & interval : *mCharClasses[j]) {
41            Value * strmPack[packCount];
42            unsigned lo = re::lo_codepoint(interval);
43            unsigned hi = re::hi_codepoint(interval);
44            if (lo == hi) {
45                Value * cp = ConstantInt::get(iBuilder->getIntNTy(codeUnitWidth), lo);
46                Value * cp_splat = iBuilder->simd_fill(codeUnitWidth, cp);
47                for (unsigned k = 0; k < packCount; k++) {
48                    strmPack[k] = iBuilder->simd_eq(codeUnitWidth, codeUnitPack[k], cp_splat);
49                }
[5823]50            } else if (lo == 0) {
51                if (hi == maxCodeVal) {
52                    for (unsigned k = 0; k < packCount; k++) {
53                        strmPack[k] = iBuilder->allOnes();
54                    }
55                } else {
56                    Value * cp = ConstantInt::get(iBuilder->getIntNTy(codeUnitWidth), hi + 1);
57                    Value * cp_splat = iBuilder->simd_fill(codeUnitWidth, cp);
58                    for (unsigned k = 0; k < packCount; k++) {
59                        strmPack[k] = iBuilder->simd_ult(codeUnitWidth, codeUnitPack[k], cp_splat);
60                    }
61                }
62            } else if (hi == maxCodeVal) {
63                Value * cp = ConstantInt::get(iBuilder->getIntNTy(codeUnitWidth), lo - 1);
64                Value * cp_splat = iBuilder->simd_fill(codeUnitWidth, cp);
65                for (unsigned k = 0; k < packCount; k++) {
66                    strmPack[k] = iBuilder->simd_ugt(codeUnitWidth, codeUnitPack[k], cp_splat);
67                }
68            } else {
[5140]69                Value * v1 = ConstantInt::get(iBuilder->getIntNTy(codeUnitWidth), lo-1);
70                Value * lo_splat = iBuilder->simd_fill(codeUnitWidth, v1);
71                Value * v2 = ConstantInt::get(iBuilder->getIntNTy(codeUnitWidth), hi+1);
72                Value * hi_splat = iBuilder->simd_fill(codeUnitWidth, v2);
73                for (unsigned k = 0; k < packCount; k++) {
74                    Value * lo_test = iBuilder->simd_ugt(codeUnitWidth, codeUnitPack[k], lo_splat);
75                    Value * hi_test = iBuilder->simd_ult(codeUnitWidth, codeUnitPack[k], hi_splat);
76                    strmPack[k] = iBuilder->simd_and(lo_test, hi_test);
77                }
78            }
79            unsigned packFields = iBuilder->getBitBlockWidth()/packCount;
80            Value * pack = iBuilder->allZeroes();
81            for (unsigned k = 0; k < packCount; k++) {
82                pack = iBuilder->mvmd_insert(packFields, pack, iBuilder->CreateTrunc(iBuilder->hsimd_signmask(codeUnitWidth, strmPack[k]), iBuilder->getIntNTy(packFields)), k);
83            }
84
85            theCCstream = iBuilder->simd_or(theCCstream, pack);
86        }
[5440]87        iBuilder->storeOutputStreamBlock("ccStream", iBuilder->getInt32(j), theCCstream);
[5140]88    }
89}
90
[5828]91inline std::vector<Binding> makeOutputBindings(const std::unique_ptr<kernel::KernelBuilder> & b, const std::vector<CC *> & charClasses) {
92    std::vector<Binding> bindings;
93    for (CC * cc : charClasses) {
94        bindings.emplace_back(Binding(b->getStreamTy(), cc->canonicalName(re::CC_type::ByteClass)));
95    }
96    return bindings;
97}
98
[5217]99ParabixCharacterClassKernelBuilder::ParabixCharacterClassKernelBuilder (
[5436]100        const std::unique_ptr<kernel::KernelBuilder> & b, std::string ccSetName, const std::vector<CC *> & charClasses, unsigned codeUnitSize)
[5828]101: PabloKernel(b, ccSetName +"_kernel",
102// stream inputs
103{Binding{b->getStreamSetTy(codeUnitSize), "basis"}}
104// stream outputs
105, makeOutputBindings(b, charClasses)
106)
[5435]107, mCharClasses(charClasses) {
[5828]108
[5435]109}
110
[5436]111void ParabixCharacterClassKernelBuilder::generatePabloMethod() {
[5310]112    CC_Compiler ccc(this, getInput(0));
[5217]113    auto & builder = ccc.getBuilder();
[5435]114    for (unsigned i = 0; i < mCharClasses.size(); ++i) {
115        builder.createAssign(getOutput(i), ccc.compileCC("cc", mCharClasses[i], builder));
[5217]116    }
117}
Note: See TracBrowser for help on using the repository browser.