Changeset 5274


Ignore:
Timestamp:
Jan 24, 2017, 9:00:55 AM (10 months ago)
Author:
cameron
Message:

Fix so that final segment/block processing is only executed in a single thread in segment-pipeline-parallel mode

File:
1 edited

Legend:

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

    r5273 r5274  
    110110    Constant * myThreadId = ConstantInt::get(size_ty, id);
    111111    std::vector<Value *> instancePtrs;
    112     for (unsigned i = 0; i < kernels.size(); i++) {
    113         Value * ptr = iBuilder->CreateGEP(sharedStruct, {iBuilder->getInt32(0), iBuilder->getInt32(i)});
     112    for (unsigned k = 0; k < kernels.size(); k++) {
     113        Value * ptr = iBuilder->CreateGEP(sharedStruct, {iBuilder->getInt32(0), iBuilder->getInt32(k)});
    114114        instancePtrs.push_back(iBuilder->CreateLoad(ptr));
    115115    }
     
    131131        Value * processedSegmentCount = kernels[k]->acquireLogicalSegmentNo(instancePtrs[k]);
    132132        Value * cond = iBuilder->CreateICmpEQ(segNo, processedSegmentCount);
    133         iBuilder->CreateCondBr(cond, segmentLoopBody[k], segmentWait[k]);
    134        
     133
     134        if (kernels[k]->hasNoTerminateAttribute()) {
     135            iBuilder->CreateCondBr(cond, segmentLoopBody[k], segmentWait[k]);
     136        }
     137        else {
     138            // If the kernel terminated in a previous block then the pipeline is done.
     139            BasicBlock * completionTest = BasicBlock::Create(iBuilder->getContext(), kernels[k]->getName() + "Completed", threadFunc, 0);
     140            iBuilder->CreateCondBr(cond, completionTest, segmentWait[k]);
     141            iBuilder->SetInsertPoint(completionTest);
     142            Value * alreadyDone = kernels[k]->getTerminationSignal(instancePtrs[k]);
     143            iBuilder->CreateCondBr(alreadyDone, exitThreadBlock, segmentLoopBody[k]);
     144        }
    135145        iBuilder->SetInsertPoint(segmentLoopBody[k]);
    136146        std::vector<Value *> doSegmentArgs = {instancePtrs[k], doFinal};
     
    153163        if (k == last_kernel) {
    154164            segNo->addIncoming(iBuilder->CreateAdd(segNo, ConstantInt::get(size_ty, threadNum)), segmentLoopBody[last_kernel]);
    155             iBuilder->CreateCondBr(doFinal, exitThreadBlock, segmentLoop);
     165            iBuilder->CreateCondBr(doFinal, exitThreadBlock, segmentLoop);
    156166        }
    157167        else {
    158             iBuilder->CreateBr(segmentWait[k+1]);
    159         }
     168            iBuilder->CreateBr(segmentWait[k+1]);
     169        }
    160170    }
    161171
Note: See TracChangeset for help on using the changeset viewer.