参考https://blog.csdn.net/kentyu001/article/details/54575876
const void *a中const修饰的是*a, 对象不可修改, 但指针可以指向别的对象。在void* const a中,const 修饰的是a, 是常量指针, 对象可以修改, 但指针内的地址不可修改
const void* const* inputs是一个二维指针数组, 里外均为const的. 其指针元素为const void*, 像普通的指针一样. 只是对于里外都不可修改的才要加两个const去修饰
void* const* outputs只加了一个const, 那么就是修饰二维指针数组的常量指针, 跟const放在前后没有必然联系
void*转char*用static_cast, char*转float*用reinterpret_cast, 去掉const用const_cast
char* scratch1 = static_cast<char*>(workspace); // workspace首地址, 保存Q*K'的结果
char* scratch2 = scratch1 + bytesAligned; // TODO:Q*K'之后保存V的首地址
const float* input = static_cast<const float*>(inputs[0]);
float* output = static_cast<float*>(outputs[0]);
float* scr1 = reinterpret_cast<float*>(scratch1); // qkptr
float* scr2 = reinterpret_cast<float*>(scratch2); // pptr