export  function get_row(){
    var stack =  new Error().stack?.split(':')[7];
    return parseInt(stack!);
}

export function numToString(data:number[]):string{
    var res_ = "";
    for(var i = 0;i<data.length;i = i + 1){
        res_ = res_ + "_" + (data[i]).toString() ;
    }
    return res_;
}

export  function ppl_res_check(res:number,info:string){
    if(res != 0){
        console.error(info," with ret:",res);
    }
}

export function ppl_debug(ifDebug:boolean,...optionalParams: any[]){
    if(ifDebug){
       /* optionalParams.forEach((value,index)=>{
            console.log(value);
        }); */
        console.log(optionalParams);
    }
}

export function check_if_undefined(obj:any,info:string):number{
    if(obj == undefined){
        console.error(info);
        return -1;
    }
    return 0;
}

/**
* @brief    compare two arraybuffe value to record diff position 
* @author   xusiyu@sensetime.com
* @param    src  the source value want to do correctness verification
* @param    dst  target reference value
* @param    shape  the array shape.[0,1,2,3] reprensent [n c h w]
* @return   boolean    return true if src equal dst.
* @version  v1.0.0
**/
export function ppl_diff(src:ArrayBuffer,dst:ArrayBuffer,shape:number[]):boolean{
    let batch:number = shape[0];
    let channel:number = shape[1];
    let height:number = shape[2];
    let width:number = shape[3];

    if(src.byteLength != dst.byteLength){
        console.error("input0 and input1 have different length",src.byteLength," vs ",dst.byteLength);
        return false;
    }
    let totalNum:number = batch*channel*height*width;
    //float32 data
    if(src.byteLength != totalNum*4){
        console.error("input and shape isn't match");
        return false;
    }

    let src_ = new Float32Array(src);
    let dst_ = new Float32Array(dst);

    var equal_value:number = 0;
    var re:number = 0;
    var averageRelativeError:number = 0;
    var averageAbsoluteError:number = 0;
    var not_equal_value:number = 0;
    var not_equal_abs5_value:number = 0;
    var not_equal_abs4_value:number = 0;
    var not_equal_abs3_value:number = 0;
    var not_equal_abs2_value:number = 0;
    var not_equal_abs1_value:number = 0;
    for(var n:number = 0;n < batch; n++){
        for(var c:number = 0;c < channel; c++){
            for(var h:number = 0;h < height; h++){
                for(var w:number = 0;w < width; w++){
                    let idx:number = w + h * width + c * height * width + n * channel * height * width;
                    var absoluteError: number = Math.abs(dst_[idx]-src_[idx]);
                    var relativeError:number = absoluteError/Math.abs(dst_[idx]);
                    if(dst_[idx]==0 &&absoluteError!=0) relativeError = 1; 
                    if(dst_[idx]==0 &&absoluteError==0) relativeError = 0;
                    averageAbsoluteError += absoluteError;
                    averageRelativeError += relativeError;
                    if(absoluteError<=1e-6){
                        equal_value++;
                    }else if(absoluteError<=1e-5){
                        not_equal_abs5_value++;
                    }
                    else if(absoluteError<=1e-4){
                        not_equal_abs4_value++;
                    }
                    else if(absoluteError<=1e-3){
                        not_equal_abs3_value++;
                    }
                    else if(absoluteError<=1e-2){
                        not_equal_abs2_value++;
                    }
                    else if(absoluteError<=1e-1){
                        not_equal_abs1_value++;
                        re++;
                    }else{
                        if(re == 0)
                            console.error("(",n,c,h,w,") value is not equal:",src_[idx]," vs ",dst_[idx]);
                        not_equal_value++;
                        re++;
                    }
                }
            }
        }
    }
    console.log("total value is: ",totalNum);
    console.log("averageRelativeError value is: ",averageAbsoluteError/totalNum);
    console.log("averageAbsoluteError value is: ",averageRelativeError/totalNum);
    console.log("equal value is: ",equal_value," ratio: ",equal_value/totalNum*100,"%");
    console.log("not_equal 10-5 value is: ",not_equal_abs5_value," ratio: ",not_equal_abs5_value/totalNum*100,"%");
    console.log("not_equal 10-4 value is: ",not_equal_abs4_value," ratio: ",not_equal_abs4_value/totalNum*100,"%");
    console.log("not_equal 10-3 value is: ",not_equal_abs3_value," ratio: ",not_equal_abs3_value/totalNum*100,"%");
    console.log("not_equal 10-2 value is: ",not_equal_abs2_value," ratio: ",not_equal_abs2_value/totalNum*100,"%");
    console.log("not_equal 10-1 value is: ",not_equal_abs1_value," ratio: ",not_equal_abs1_value/totalNum*100,"%");
    console.log("not equal value is: ",not_equal_value," ratio: ",not_equal_value/totalNum*100,"%");
    if(not_equal_value == 0)
        return true;
    else
        return false;
}