@@ -227,28 +227,29 @@ static void applyCanonicalKmerOptimization(std::vector<Expr *> &stages,
227
227
228
228
// make sure params are globals or literals, since codegen'ing in function entry
229
229
// block
230
- static Value * validateAndCodegenInterAlignParamExpr (Expr *e,
231
- const std::string &name,
232
- BaseFunc *base,
233
- BasicBlock *block ) {
230
+ template < typename E = IntExpr>
231
+ static Value * validateAndCodegenInterAlignParamExpr (
232
+ Expr *e, const std::string &name, BaseFunc *base, BasicBlock *block ,
233
+ bool i32 = false , types::Type *expectedType = types::Int ) {
234
234
if (!e)
235
235
throw exc::SeqException (" inter-sequence alignment parameter '" + name +
236
236
" ' not specified" );
237
- if (!e->getType ()->is (types::Int ))
237
+ if (!e->getType ()->is (expectedType ))
238
238
throw exc::SeqException (" inter-sequence alignment parameter '" + name +
239
- " ' is not of type int " );
239
+ " ' is not of type " + expectedType-> getName () );
240
240
bool valid = false ;
241
241
if (auto *v = dynamic_cast <VarExpr *>(e)) {
242
242
valid = v->getVar ()->isGlobal ();
243
243
} else {
244
- valid = (dynamic_cast <IntExpr *>(e) != nullptr );
244
+ valid = (dynamic_cast <E *>(e) != nullptr );
245
245
}
246
246
if (!valid)
247
247
throw exc::SeqException (" inter-sequence alignment parameters must be "
248
248
" constants or global variables" );
249
249
Value *val = e->codegen (base, block);
250
250
IRBuilder<> builder (block);
251
- return builder.CreateTrunc (val, builder.getInt8Ty ());
251
+ return builder.CreateZExtOrTrunc (val, i32 ? builder.getInt32Ty ()
252
+ : builder.getInt8Ty ());
252
253
}
253
254
254
255
Value *PipeExpr::validateAndCodegenInterAlignParams (
@@ -271,14 +272,18 @@ Value *PipeExpr::validateAndCodegenInterAlignParams(
271
272
paramVal = validateAndCodegenInterAlignParamExpr (paramExprs.gape , " gape" ,
272
273
base, block);
273
274
params = paramsType->setMemb (params, " gape" , paramVal, block);
274
- paramVal = validateAndCodegenInterAlignParamExpr (paramExprs.bandwidth ,
275
- " bandwidth" , base, block);
275
+ paramVal = validateAndCodegenInterAlignParamExpr<BoolExpr>(
276
+ paramExprs.score_only , " score_only" , base, block, /* i32=*/ false ,
277
+ /* expectedType=*/ types::Bool);
278
+ params = paramsType->setMemb (params, " score_only" , paramVal, block);
279
+ paramVal = validateAndCodegenInterAlignParamExpr (
280
+ paramExprs.bandwidth , " bandwidth" , base, block, /* i32=*/ true );
276
281
params = paramsType->setMemb (params, " bandwidth" , paramVal, block);
277
282
paramVal = validateAndCodegenInterAlignParamExpr (paramExprs.zdrop , " zdrop" ,
278
- base, block);
283
+ base, block, /* i32= */ true );
279
284
params = paramsType->setMemb (params, " zdrop" , paramVal, block);
280
- paramVal = validateAndCodegenInterAlignParamExpr (paramExprs. zdrop ,
281
- " end_bonus" , base, block);
285
+ paramVal = validateAndCodegenInterAlignParamExpr (
286
+ paramExprs. end_bonus , " end_bonus" , base, block, /* i32= */ true );
282
287
params = paramsType->setMemb (params, " end_bonus" , paramVal, block);
283
288
return params;
284
289
}
@@ -461,8 +466,7 @@ Value *PipeExpr::codegenPipe(BaseFunc *base,
461
466
}
462
467
463
468
// following defs are from bio/align.seq
464
- const int MAX_SEQ_LEN_REF = 256 ;
465
- const int MAX_SEQ_LEN_QER = 128 ;
469
+ const int LEN_LIMIT = 512 ;
466
470
const int MAX_SEQ_LEN8 = 128 ;
467
471
const int MAX_SEQ_LEN16 = 32768 ;
468
472
types::RecordType *pairType = PipeExpr::getInterAlignSeqPairType ();
@@ -483,8 +487,8 @@ Value *PipeExpr::codegenPipe(BaseFunc *base,
483
487
IRBuilder<> builder (preamble);
484
488
const unsigned W = PipeExpr::SCHED_WIDTH_INTERALIGN;
485
489
Value *statesSize = builder.getInt64 (genType->size (module) * W);
486
- Value *bufRefSize = builder.getInt64 (MAX_SEQ_LEN_REF * W);
487
- Value *bufQerSize = builder.getInt64 (MAX_SEQ_LEN_QER * W);
490
+ Value *bufRefSize = builder.getInt64 (LEN_LIMIT * W);
491
+ Value *bufQerSize = builder.getInt64 (LEN_LIMIT * W);
488
492
Value *pairsSize = builder.getInt64 (pairType->size (module) * W);
489
493
Value *histSize = builder.getInt64 ((MAX_SEQ_LEN8 + MAX_SEQ_LEN16 + 32 ) * 4 );
490
494
Value *states = builder.CreateCall (alloc, statesSize);
@@ -495,10 +499,10 @@ Value *PipeExpr::codegenPipe(BaseFunc *base,
495
499
statesTemp, genType->getLLVMType (context)->getPointerTo ());
496
500
Value *bufRef = builder.CreateCall (allocAtomic, bufRefSize);
497
501
Value *bufQer = builder.CreateCall (allocAtomic, bufQerSize);
498
- Value *pairs = builder.CreateCall (allocAtomic , pairsSize);
502
+ Value *pairs = builder.CreateCall (alloc , pairsSize);
499
503
pairs = builder.CreateBitCast (
500
504
pairs, pairType->getLLVMType (context)->getPointerTo ());
501
- Value *pairsTemp = builder.CreateCall (allocAtomic , pairsSize);
505
+ Value *pairsTemp = builder.CreateCall (alloc , pairsSize);
502
506
pairsTemp = builder.CreateBitCast (
503
507
pairsTemp, pairType->getLLVMType (context)->getPointerTo ());
504
508
Value *hist = builder.CreateCall (allocAtomic, histSize);
@@ -537,7 +541,8 @@ Value *PipeExpr::codegenPipe(BaseFunc *base,
537
541
538
542
builder.SetInsertPoint (notFull);
539
543
N = builder.CreateLoad (filled);
540
- N = builder.CreateCall (queue, {task, pairs, bufRef, bufQer, states, N});
544
+ N = builder.CreateCall (queue,
545
+ {task, pairs, bufRef, bufQer, states, N, params});
541
546
builder.CreateStore (N, filled);
542
547
builder.CreateBr (exit );
543
548
state.block = exit ;
@@ -887,24 +892,29 @@ PipeExpr *PipeExpr::clone(Generic *ref) {
887
892
}
888
893
889
894
types::RecordType *PipeExpr::getInterAlignYieldType () {
890
- return types::RecordType::get ({types::Seq, types::Seq, types::Int},
891
- {" query" , " reference" , " score" },
895
+ auto *i32 = types::IntNType::get (32 , true );
896
+ static types::RecordType *cigarType = types::RecordType::get (
897
+ {types::PtrType::get (i32), types::Int}, {" _data" , " _len" }, " CIGAR" );
898
+ static types::RecordType *resultType = types::RecordType::get (
899
+ {cigarType, types::Int}, {" _cigar" , " _score" }, " Alignment" );
900
+ return types::RecordType::get ({types::Seq, types::Seq, resultType},
901
+ {" query" , " target" , " alignment" },
892
902
" InterAlignYield" );
893
903
}
894
904
895
905
types::RecordType *PipeExpr::getInterAlignParamsType () {
896
906
auto *i8 = types::IntNType::get (8 , true );
897
- return types::RecordType::get (
898
- {i8, i8, i8, i8, i8, i8, i8, i8},
899
- {" a" , " b" , " ambig" , " gapo" , " gape" , " bandwidth" , " zdrop" , " end_bonus" },
900
- " InterAlignParams" );
907
+ auto *i32 = types::IntNType::get (32 , true );
908
+ return types::RecordType::get ({i8, i8, i8, i8, i8, i8, i32, i32, i32},
909
+ {" a" , " b" , " ambig" , " gapo" , " gape" ,
910
+ " score_only" , " bandwidth" , " zdrop" ,
911
+ " end_bonus" },
912
+ " InterAlignParams" );
901
913
}
902
914
903
915
types::RecordType *PipeExpr::getInterAlignSeqPairType () {
904
916
auto *i32 = types::IntNType::get (32 , true );
905
917
return types::RecordType::get (
906
- {i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32},
907
- {" idr" , " idq" , " id" , " len1" , " len2" , " h0" , " seqid" , " regid" , " score" ,
908
- " tle" , " gtle" , " qle" , " gscore" , " max_off" },
909
- " SeqPair" );
918
+ {i32, i32, i32, i32, types::PtrType::get (i32), i32, i32},
919
+ {" id" , " len1" , " len2" , " score" , " cigar" , " n_cigar" , " flags" }, " SeqPair" );
910
920
}
0 commit comments