TIling 分割代码中ub_block_num的实际意义是什么?
收藏回复举报
TIling 分割代码中ub_block_num的实际意义是什么?
t('forum.solved') 已解决
发表于2024-04-30 20:54:30
0 查看
  • 这是gitee中addcdiv的sample代码
  1. 第一个问题是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就不太明白为什么?

  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这个数据有什么讲究吗?硬件有什么硬性规定吗?如何把控这个变量该定多少?

  3. 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

我要发帖子