if constexpr (std::is_same_v<T, int8_t>) {
auto float_x1 = B_x1.Get<half>();
auto float_x2 = B_x2.Get<half>();
Cast(float_x1, x1, RoundMode::CAST_NONE, length);
Cast(float_x2, x2, RoundMode::CAST_NONE, length);
Min(float_x2, float_x1, float_x2, length);
Sub(float_x1, float_x1, float_x2, length);
Compare(bits, float_x1, zero, CMPMODE::NE, length);
Select(result, bits, zero, half(1), SELMODE::VSEL_TENSOR_SCALAR_MODE, length);
Cast(inty, result, RoundMode::CAST_ROUND, length);
}
else {
Min(x2, x1, x2, length);
Sub(x1, x1, x2, length);
if constexpr (std::is_same_v<T, int32_t>) {
auto val = B_x1.Get<float>();
auto float_zero = B_x2.Get<float>();
Cast(val, x1, RoundMode::CAST_NONE, length);
Compare(bits, val, float_zero, CMPMODE::NE, length);
}
else if constexpr (std::is_same_v<T, float>) {
auto float_zero = B_x2.Get<float>();
Compare(bits, x1, float_zero, CMPMODE::NE, length);
}
else { //half
Compare(bits, x1, zero, CMPMODE::NE, length);
}
Select(result, bits, zero, half(1), SELMODE::VSEL_TENSOR_SCALAR_MODE, length);
Cast(inty, result, RoundMode::CAST_ROUND, length);
}
if constexpr (std::is_same_v<T, int8_t>) { auto float_x1 = B_x1.Get<half>(); auto float_x2 = B_x2.Get<half>(); Cast(float_x1, x1, RoundMode::CAST_NONE, length); Cast(float_x2, x2, RoundMode::CAST_NONE, length); Min(float_x2, float_x1, float_x2, length); Sub(float_x1, float_x1, float_x2, length); Compare(bits, float_x1, zero, CMPMODE::NE, length); Select(result, bits, zero, half(1), SELMODE::VSEL_TENSOR_SCALAR_MODE, length); Cast(inty, result, RoundMode::CAST_ROUND, length); } else { Min(x2, x1, x2, length); Sub(x1, x1, x2, length); if constexpr (std::is_same_v<T, int32_t>) { auto val = B_x1.Get<float>(); auto float_zero = B_x2.Get<float>(); Cast(val, x1, RoundMode::CAST_NONE, length); Compare(bits, val, float_zero, CMPMODE::NE, length); } else if constexpr (std::is_same_v<T, float>) { auto float_zero = B_x2.Get<float>(); Compare(bits, x1, float_zero, CMPMODE::NE, length); } else { //half Compare(bits, x1, zero, CMPMODE::NE, length); } Select(result, bits, zero, half(1), SELMODE::VSEL_TENSOR_SCALAR_MODE, length); Cast(inty, result, RoundMode::CAST_ROUND, length); }shape_x = [3,16, 16, 4] shape_y = [1,1,4] shape_out = [3,16,16,4] dtype = np.float16 input_x = np.random.uniform(-100, 100, shape_x) input_y = np.random.uniform(-100, 100, shape_y)auto axes = context->GetAttrs()->GetListInt(1); if(flag){ context->SetTilingKey(2); uint32_t reduce1[20] = {0}; uint32_t reduce2[20] = {0}; uint32_t shape[20] = {0}; uint32_t d = 1; for(int i=0;i<outshape.GetDimNum();i++){ shape[i] = outshape.GetDim(i); d *= outshape.GetDim(i); if(inshape1.GetDim(i) != outshape.GetDim(i)) reduce1[i] = 1; if(inshape2.GetDim(i) != outshape.GetDim(i)) reduce2[i] = 1; } uint32_t dim = outshape.GetDimNum(); for(int i=dim-1;i>=1;i--){ if(!reduce1[i - 1] && !reduce2[i - 1] && !reduce1[i] && !reduce2[i]){ dim--; shape[i - 1] *= shape[i]; }else{ break; } }uint32_t outDimNum = outshape.GetDimNum(); const gert::StorageShape* shape1 = context->GetInputShape(0); std::vector<uint64_t> inshapeVector1(outDimNum, 1); int n = outDimNum; for (int j = shape1->GetStorageShape().GetDimNum() - 1; j >= 0; --j) { inshapeVector1[--n] = shape1->GetStorageShape().GetDim(j); } const gert::StorageShape* shape2 = context->GetInputShape(1); std::vector<uint64_t> inshapeVector2(outDimNum, 1); n = outDimNum; for (int j = shape2->GetStorageShape().GetDimNum() - 1; j >= 0; --j) { inshapeVector2[--n] = shape2->GetStorageShape().GetDim(j); } bool flag = false; for(int i=0;i<outDimNum;i++){ if(inshapeVector1[i] != inshapeVector2[i]) flag = true; } uint32_t shape[20] = {0}; uint32_t reduce1[20] = {0}; uint32_t reduce2[20] = {0}; uint32_t dim = outshape.GetDimNum(); auto axes = context->GetAttrs()->GetListInt(1); if(flag){ context->SetTilingKey(2); uint32_t d = 1; for(int i=0;i<outDimNum;i++){ shape[i] = outshape.GetDim(i); d *= outshape.GetDim(i); if(inshapeVector1[i] != outshape.GetDim(i)) reduce1[i] = 1; if(inshapeVector2[i] != outshape.GetDim(i)) reduce2[i] = 1; }顺带提一嘴,这个知识点还有如何输出+INF,-INF,NAN类型,可以顺带回忆一下
def verify_result(real_result, golden): real_result = np.fromfile(real_result, dtype=np.int8) # 从bin文件读取实际运算结果 golden = np.fromfile(golden, dtype=np.bool_) # 从bin文件读取预期运算结果uint32_t d[21] = {0}; uint32_t dn1[21] = {0}; uint32_t dn2[21] = {0}; dim = dim - 1;//2 d[dim] = dn1[dim] = dn2[dim] = 1;//d2=dn12=dn22 = 1 for(int k=dim-1;k>=0;k--){//k=1 K=0 d[k] = d[k + 1] * shape[k];//d1=d2*shape[1] d0=d1*shape[0] if(reduce1[k] == 0){ dn1[k] = dn1[k + 1] * shape[k]; }else{ dn1[k] = dn1[k + 1]; } if(reduce2[k] == 0){ dn2[k] = dn2[k + 1] * shape[k]; }else{ dn2[k] = dn2[k + 1]; } } std::cout <<"d:" << " "; for(int i=0;i<=dim;i++){ std::cout << d[i] << " "; } std::cout << std::endl; std::cout <<"dn1:" << " "; for(int i=0;i<=dim;i++){ std::cout << dn1[i] << " "; } std::cout << std::endl; std::cout <<"dn2:" << " "; for(int i=0;i<=dim;i++){ std::cout << dn2[i] << " "; } std::cout << std::endl; std::cout <<"dim:" << (dim-1) << " "; std::cout << std::endl; for(int j=0;j<count;j++){//256 count = totalLength /shape[dim - 1] uint32_t start1 = 0, start2 = 0; for(int k=dim-1;k>=0;k--){ std::cout << " k:["<< k << "] "; if(reduce1[k] == 0){ start1 += dn1[k + 1] * (j / d[k + 1] % shape[k]); } std::cout <<" s1:["<< start1 << "] "; if(reduce2[k] == 0){ start2 += dn2[k + 1] * (j / d[k + 1] % shape[k]); } std::cout <<" s2:[" <<start2 << "] "; } std::cout << std::endl; }shape_x = [3,16, 16, 4] shape_y = [1,1,4] shape_out = [3,16,16,4] dtype = np.float16 input_x = np.random.uniform(-100, 100, shape_x) input_y = np.random.uniform(-100, 100, shape_y)shape_x = [3,16, 16, 4] shape_y = [1,16,1,4] shape_out = [3,16,16,4] dtype = np.float16