TIling 分割代码中ub_block_num的实际意义是什么?
已解决发表于2024-04-30 20:54:30
0 查看
- 第一个问题是uint32_t ub_block_num_real =((ub_size) / BLOCK_SIZE / 2) * 13 / 20
ub_block_num_real 为什么还要/2 实际的量应该是ub_size/BLOCK_SIZE才对把,因为两者都以字节来定义,后面13/20是为了取部分数据,但是除2就不太明白为什么?
- ub_block_num 注释是分配的内存块个数,那tile_num又是什么?
tile_num = blockLength / ALIGN_NUM / ub_block_num
查询资料得知tileNum是指每个核上总计算数据分块个数。
我的理解是tile_num指的块是ub_block_num个最小块也就是ub_block_num个32B,可以这么理解吗?
那么ub_block_num这个数据有什么讲究吗?硬件有什么硬性规定吗?如何把控这个变量该定多少?
-
isformershare 跟 istailshare的定义是什么?当为true是核内进行ub_block_num个最小块均分,这么做的目的是什么?
个人理解是为了拆分数据以满足Vector计算要求数据要求
由资料得知,若数据充分,Vector一次最多可计算8个block(256Byte),所以这个ub_block_num最多是8,不能超过8。设定是偶数的意义是为了乒乓操作?
ub_block_num_real 为什么还要/2
实际的量应该是ub_size/BLOCK_SIZE才对把,因为两者都以字节来定义,后面13/20是为了取部分数据,但是除2就不太明白为什么?
tile_num = blockLength / ALIGN_NUM / ub_block_num
查询资料得知tileNum是指每个核上总计算数据分块个数。
我的理解是tile_num指的块是ub_block_num个最小块也就是ub_block_num个32B,可以这么理解吗?
那么ub_block_num这个数据有什么讲究吗?硬件有什么硬性规定吗?如何把控这个变量该定多少?
isformershare 跟 istailshare的定义是什么?当为true是核内进行ub_block_num个最小块均分,这么做的目的是什么?
个人理解是为了拆分数据以满足Vector计算要求数据要求
由资料得知,若数据充分,Vector一次最多可计算8个block(256Byte),所以这个ub_block_num最多是8,不能超过8。设定是偶数的意义是为了乒乓操作?
uint32_t ub_block_num_real = ((ub_size) / BLOCK_SIZE / 2) * 13 / 20; // ub_block在Ascend C中不能全部被用来作为输入输出,给了13/20系数。 uint32_t ub_block_num = 5; //为测试方便,验证代码流程 uint32_t tile_num; if (ub_block_num % 2 != 0) {//分配的内存块个数 ub_block_num = ub_block_num - 1;//5-1=4 } // get attr // const float* pvalue = context->GetAttrs()->GetFloat(0); // tiling.set_value(*pvalue);//value = 1.0f // 1.输入向量满足32字节对齐 block_size 对齐 if (totalLength % ALIGN_NUM != 0) { //不对齐,先32位对齐 totalLengthAligned = ((totalLength + ALIGN_NUM - 1) / ALIGN_NUM) * ALIGN_NUM; } else { totalLengthAligned = totalLength; } if (totalLengthAligned <= ub_block_num * ALIGN_NUM) { // shape较小,用单核 context->SetBlockDim(1);//规定了核函数将会在几个核上执行,我们可以先设置为1 } else { if (((totalLengthAligned / ALIGN_NUM) % ub_block_num) == 0) { //可以核间均分 if ((totalLengthAligned / ALIGN_NUM / ub_block_num) <= aivNum) { //且计算出均分后的核数小于当前aicore数量,按计算值 context->SetBlockDim(totalLengthAligned / ALIGN_NUM / ub_block_num); } else { // ... 按照aivNum切分 // context->SetBlockDim(ascendcPlatform.CalcTschBlockDim(aivNum, aicNum, // aivNum)); context->SetBlockDim(aivNum); } } else { //核间不能均分 if (((totalLengthAligned / ALIGN_NUM / ub_block_num) + 1) <= aivNum) { //且计算出均分后的核数小于当前aicore数量,按计算值 context->SetBlockDim((totalLengthAligned / ALIGN_NUM / ub_block_num) + 1); } else { // ... 按照aivNum切分 // context->SetBlockDim(ascendcPlatform.CalcTschBlockDim(aivNum, aicNum, // aivNum)); context->SetBlockDim(aivNum);//设置block dim,即参与计算的VectorCore或者CubeCore核数。 } } } auto block_dim = context->GetBlockDim();//获取block dim printf("block_dim log is %d,\r\n",block_dim); uint32_t blockLength = 0; uint32_t tileLength = 0; uint32_t lasttileLength = 0; uint32_t formertileLength = 0; uint32_t formerlasttileLength = 0; if ((totalLengthAligned / ALIGN_NUM) % block_dim == 0) { //核间可均分 blockLength = totalLengthAligned / block_dim;//核均分 总计算数据量 tile_num = blockLength / ALIGN_NUM / ub_block_num;//当blockLength/ALIGN_NUM < ub_block_num tile_num每个核上总计算数据分块个数 ub_block_num 数据块等于几个最小数据块 printf("totalLengthAligned ub_block_num ALIGN_NUM log is %d,%d,%d\r\n",totalLengthAligned,ub_block_num,ALIGN_NUM); if ((totalLengthAligned / block_dim / ALIGN_NUM) % ub_block_num == 0 || tile_num == 0) { //满足32字节对齐,可以核内均分 if (tile_num == 0) { tile_num = 1; } if (blockLength < ub_block_num* ALIGN_NUM) { tileLength = ((blockLength / ALIGN_NUM) + 1) / 2 * 2 * ALIGN_NUM; lasttileLength = tileLength; } else { tileLength = ub_block_num * ALIGN_NUM; lasttileLength = tileLength; } } else { //满足32字节对齐,核内不能均分 tile_num = tile_num + 1; tileLength = ub_block_num * ALIGN_NUM; lasttileLength = blockLength - (tile_num - 1) * tileLength; } context->SetTilingKey(1); tiling.set_blockLength(blockLength); tiling.set_tileNum(tile_num); tiling.set_tileLength(tileLength); tiling.set_lasttileLength(lasttileLength); tiling.SaveToBuffer(context->GetRawTilingData()->GetData(), context->GetRawTilingData()->GetCapacity()); context->GetRawTilingData()->SetDataSize(tiling.GetDataSize()); size_t* currentWorkspace = context->GetWorkspaceSizes(1); currentWorkspace[0] = 0; printf("blockLength tile_num tileLength lasttileLength log is %d,%d,%d,%d\r\n",blockLength,tile_num,tileLength,lasttileLength); return ge::GRAPH_SUCCESS; } else {//核间不可均分 uint32_t formerNum = (totalLengthAligned / ALIGN_NUM) % block_dim; uint32_t tailNum = block_dim - formerNum; // 计算大块和小块的数据量 // uint32_t formerLength = ((totalLengthAligned / BLOCK_DIM + ALIGN_NUM - 1) / ALIGN_NUM) * ALIGN_NUM; //uint32_t tailLength = (totalLengthAligned / BLOCK_DIM / ALIGN_NUM) * ALIGN_NUM; uint32_t formerLength = (((totalLengthAligned + block_dim - 1) / block_dim + ALIGN_NUM - 1) / ALIGN_NUM) *ALIGN_NUM; uint32_t tailLength = (totalLengthAligned / block_dim / ALIGN_NUM) * ALIGN_NUM; bool isformershare = true; uint32_t former_tile_num = formerLength / ALIGN_NUM / ub_block_num; if ((formerLength / ALIGN_NUM) % ub_block_num == 0 || former_tile_num == 0) { //核内均分 if (former_tile_num == 0) { former_tile_num = 1; } if (formerLength < ub_block_num * ALIGN_NUM) { formertileLength = ((formerLength / ALIGN_NUM) + 1) / 2 * 2 * ALIGN_NUM; formerlasttileLength = formertileLength; } else { formertileLength = ub_block_num * ALIGN_NUM; formerlasttileLength = formertileLength; } } else { isformershare = false; former_tile_num = former_tile_num + 1; formertileLength = ub_block_num * ALIGN_NUM; formerlasttileLength = (formerLength - (former_tile_num - 1) * formertileLength); } bool istailshare = true; uint32_t tail_tile_num = tailLength / ALIGN_NUM / ub_block_num; uint32_t tailtileLength; uint32_t taillasttileLength; if ((tailLength / ALIGN_NUM) % ub_block_num == 0 || tail_tile_num == 0) { //核内可以均分 if (tail_tile_num == 0) { tail_tile_num = 1; } if (tailLength < (ub_block_num * ALIGN_NUM)) { tailtileLength = ((tailLength / ALIGN_NUM) + 1) / 2 * 2 * ALIGN_NUM; taillasttileLength = tailtileLength; } else { tailtileLength = ub_block_num * ALIGN_NUM; taillasttileLength = tailtileLength; } } else { //核内不均分 istailshare = false; tail_tile_num = tail_tile_num + 1; tailtileLength = ub_block_num * ALIGN_NUM; taillasttileLength = (tailLength - (tail_tile_num - 1) * tailtileLength); } tiling.set_formerNum(formerNum);// 添加tiling字段,分配到较多数据量的核心数,即大块 tiling.set_formerLength(formerLength);// 添加tiling字段,大块的长度 tiling.set_formertileNum(former_tile_num); tiling.set_formertileLength(formertileLength); tiling.set_formerlasttileLength(formerlasttileLength); tiling.set_tailNum(tailNum);// 添加tiling字段,分配到较少数据量的核心数,即小块 tiling.set_tailLength(tailLength);// 添加tiling字段,小块的长度 tiling.set_tailtileNum(tail_tile_num); tiling.set_tailtileLength(tailtileLength); tiling.set_taillasttileLength(taillasttileLength); context->SetTilingKey(2); tiling.SaveToBuffer(context->GetRawTilingData()->GetData(), context->GetRawTilingData()->GetCapacity()); context->GetRawTilingData()->SetDataSize(tiling.GetDataSize()); size_t* currentWorkspace = context->GetWorkspaceSizes(1); currentWorkspace[0] = 0; return ge::GRAPH_SUCCESS; } } } // namespace optiling