source: icGREP/icgrep-devel/icgrep/editd/editd_gpu_kernel.cpp @ 5547

Last change on this file since 5547 was 5440, checked in by nmedfort, 2 years ago

Large refactoring step. Removed IR generation code from Kernel (formally KernelBuilder?) and moved it into the new KernelBuilder? class.

File size: 4.7 KB
Line 
1/*
2 *  Copyright (c) 2016 International Characters.
3 *  This software is licensed to the public under the Open Software License 3.0.
4 */
5#include "editd_gpu_kernel.h"
6#include <kernels/kernel_builder.h>
7#include <llvm/IR/Module.h>
8
9using namespace llvm;
10
11namespace kernel {
12
13void bitblock_advance_ci_co(const std::unique_ptr<KernelBuilder> & iBuilder, Value * val, unsigned shift, Value * stideCarryArr, unsigned carryIdx, std::vector<std::vector<Value *>> & adv, std::vector<std::vector<int>> & calculated, int i, int j){
14    if (!calculated[i][j]) {
15        Value * ptr = iBuilder->CreateGEP(stideCarryArr, {iBuilder->getInt32(0), iBuilder->getInt32(carryIdx)});
16        Value * ci = iBuilder->CreateLoad(ptr);
17        std::pair<Value *, Value *> rslt = iBuilder->bitblock_advance(val, ci, shift);
18        iBuilder->CreateStore(std::get<0>(rslt), ptr);
19        adv[i][j] = std::get<1>(rslt);
20        calculated[i][j] = 1;
21    }
22}
23
24void editdGPUKernel::generateDoBlockMethod(const std::unique_ptr<KernelBuilder> & idb) {
25
26    IntegerType * const int32ty = idb->getInt32Ty();
27    IntegerType * const int8ty = idb->getInt8Ty();
28    Value * pattLen = idb->getInt32(mPatternLen + 1);
29    Value * pattPos = idb->getInt32(0);
30    Value * pattBuf = idb->getScalarField("pattStream");
31    Value * strideCarryArr = idb->getScalarField("strideCarry");
32   
33    unsigned carryIdx = 0;
34
35    std::vector<std::vector<Value *>> e(mPatternLen, std::vector<Value *>(mEditDistance + 1));
36    std::vector<std::vector<Value *>> adv(mPatternLen, std::vector<Value *>(mEditDistance + 1));
37    std::vector<std::vector<int>> calculated(mPatternLen, std::vector<int>(mEditDistance + 1, 0));
38
39    Module * m = idb->getModule();
40    Function * bidFunc = cast<Function>(m->getOrInsertFunction("llvm.nvvm.read.ptx.sreg.ctaid.x", int32ty, nullptr));
41    Value * bid = idb->CreateCall(bidFunc);
42    Value * pattStartPtr = idb->CreateGEP(pattBuf, idb->CreateMul(pattLen, bid));
43    Value * pattPtr = idb->CreateGEP(pattStartPtr, pattPos);
44    Value * pattCh = idb->CreateLoad(pattPtr);
45    Value * pattIdx = idb->CreateAnd(idb->CreateLShr(pattCh, 1), ConstantInt::get(int8ty, 3));
46    Value * pattStream = idb->loadInputStreamBlock("CCStream", idb->CreateZExt(pattIdx, int32ty));
47    pattPos = idb->CreateAdd(pattPos, ConstantInt::get(int32ty, 1));
48
49    e[0][0] = pattStream;
50    for(unsigned j = 1; j <= mEditDistance; j++){
51        e[0][j] = idb->allOnes();
52    }
53    for(unsigned i = 1; i < mPatternLen; i++){
54        pattPtr = idb->CreateGEP(pattStartPtr, pattPos);
55        pattCh = idb->CreateLoad(pattPtr);
56        pattIdx = idb->CreateAnd(idb->CreateLShr(pattCh, 1), ConstantInt::get(int8ty, 3));
57        pattStream = idb->loadInputStreamBlock("CCStream", idb->CreateZExt(pattIdx, int32ty));
58        bitblock_advance_ci_co(idb, e[i-1][0], 1, strideCarryArr, carryIdx++, adv, calculated, i-1, 0);
59        e[i][0] = idb->CreateAnd(adv[i-1][0], pattStream);
60        for(unsigned j = 1; j<= mEditDistance; j++){
61            bitblock_advance_ci_co(idb, e[i-1][j], 1, strideCarryArr, carryIdx++, adv, calculated, i-1, j);
62            bitblock_advance_ci_co(idb, e[i-1][j-1], 1, strideCarryArr, carryIdx++, adv, calculated, i-1, j-1);
63            bitblock_advance_ci_co(idb, e[i][j-1], 1, strideCarryArr, carryIdx++, adv, calculated, i, j-1);
64            Value * tmp1 = idb->CreateAnd(adv[i-1][j], pattStream);
65            Value * tmp2 = idb->CreateAnd(adv[i-1][j-1], idb->CreateNot(pattStream));
66            Value * tmp3 = idb->CreateOr(adv[i][j-1], e[i-1][j-1]);
67            e[i][j] = idb->CreateOr(idb->CreateOr(tmp1, tmp2), tmp3);
68        }
69        pattPos = idb->CreateAdd(pattPos, ConstantInt::get(int32ty, 1));
70    }
71    idb->storeOutputStreamBlock("ResultStream", idb->getInt32(0), e[mPatternLen-1][0]);
72    for(unsigned j = 1; j<= mEditDistance; j++){
73        idb->storeOutputStreamBlock("ResultStream", idb->getInt32(j), idb->CreateAnd(e[mPatternLen - 1][j], idb->CreateNot(e[mPatternLen - 1][j - 1])));
74    }
75}
76
77void editdGPUKernel::generateFinalBlockMethod(const std::unique_ptr<KernelBuilder> & idb, Value * remainingBytes) {
78    idb->setScalarField("EOFmask", idb->bitblock_mask_from(remainingBytes));
79    CreateDoBlockMethodCall(idb);
80}
81
82editdGPUKernel::editdGPUKernel(const std::unique_ptr<kernel::KernelBuilder> & b, unsigned dist, unsigned pattLen) :
83BlockOrientedKernel("editd_gpu",
84              {Binding{b->getStreamSetTy(4), "CCStream"}},
85              {Binding{b->getStreamSetTy(dist + 1), "ResultStream"}},
86              {Binding{PointerType::get(b->getInt8Ty(), 1), "pattStream"},
87              Binding{PointerType::get(ArrayType::get(b->getBitBlockType(), pattLen * (dist + 1) * 4), 0), "strideCarry"}},
88              {},
89              {Binding{b->getBitBlockType(), "EOFmask"}})
90, mEditDistance(dist)
91, mPatternLen(pattLen) {
92}
93
94}
95
96
Note: See TracBrowser for help on using the repository browser.