打开微信,使用扫一扫进入页面后,点击右上角菜单,
点击“发送给朋友”或“分享到朋友圈”完成分享
本篇接http://forum.cambricon.com/index.php?m=content&c=index&a=show&catid=33&id=681
在本篇中我们来看一看对向量的一些操作如何使用BANG C实现
CPU code:
for(int i=0;i<low_dim;i++){ for(int j=0;j<high_dim;j++){ output[i][j] = input[j][i]; }}
BANG C code:
// mlu可以通过__bang__transpose指令对片上的二维数组进行转置操作,// 但是需要二维数组的长和宽都对齐到128 byte.int align_len = 128 / sizeof(T);int align_high_dim = (high_dim + align_len - 1) / align_len * align_len;// 现将input数据拷贝到片上的nram空间中__memcpy(nram_input, input_addr, high_dim * low_dim * sizeof(float), GDRAM2NRAM);// 通过带步伐的拷贝操作memcpy,将nram_input(high_dim,low_dim)拷贝到nram_input_temp(align_high_dim, align_low_dim)__memcpy(nram_input_temp,nram_input, low_dim * sizeof(float), NRAM2NRAM, align_low_dim * sizeof(float), low_dim * sizeof(float), high_dim - 1);// 对nram_input_temp(align_high_dim, align_low_dim)进行转置操作得到nram_output_temp(align_low_dim, align_high_dim)__bang_transpose(nram_output, nram_input_temp, align_high_dim, align_low_dim);// 通过带步伐的拷贝操作memcpy,将nram_output_temp(align_low_dim, align_high_dim)拷贝到nram_output_temp(low_dim, high_dim)__memcpy(nram_output_temp,nram_input, high_dim * sizeof(float), NRAM2NRAM, align_high_dim * sizeof(float), low_dim * sizeof(float), low_dim - 1);// 最后将片上数据拷贝到output__memcpy(output_addr,nram_output_temp,high_dim * low_dim * sizeof(float), NRAM2GDRAM);
CPU code:
float max = -9999999.9;for(int i=0;i<count;i++){ if(max<data[i]){ max = data[i]; }}
BANG C code:
#define INF 9999999.0;#define ALIGIN_UP(x, num) (((x - 1) / num + 1) * num)#define ALIGN_DOWN_TO(x, num) (((x - 1) / num) * num//使用BANG C的__bang_max指令求出向量当中的最大值,存放在输入向量的首地址的位置。int count_up = ALIGIN_UP(count, 128);for (int i = count_up - 1; i > count; --i){ data[i] = -INF;}__bang_max((float *)dst,(float *)data, count);float max = dst[0];unsigned int max_index = *((unsigned int*)(dst +1));
CPU code:
for(int i=0;i<low_dim;i++){ float max = (-1)*INF; for(int j=0;j<high_dim;j++){ if(max<input_data[i][j]){ max = input_data[i][j]; } } output_data[i] = max;}
BANG C code:
//BANG C指令大多有对齐的要求,虽然不同的指令要求不一样,但是按照128对其,可以满足大部分指令的要求。int align_low_dim = ALIGIN_UP(low_dim, 128);//从DDR读取数据到片上nram空间__memcpy(nram_input, data_addr, low_dim * sizeof(float), GDRAM2NRAM, align_low_dim * sizeof(float), low_dim * sizeof(float), high_dim -1);//bang_maxpool是最大池化指令,功能比较复杂强大,其中一个基本功能就是可以求一个向量的最大值。__bang_maxpool(nram_output,nram_input,align_low_dim,high_dim,1,high_dim,1,1,1);//将计算完成的数据从片上拷回到ddr上。__memcoy(output_data, nram_output, low_dim * sizeof(float), NRAM2GDRAM);
CPU code:
T sum = 0.0;for(int i=0;i<count;i++){ sum+=data[i];}
BANG C code:
int align_len = 128 / sizeof(T);int repeat = count / align_len;//先按照128字节分段求和,将累加值存到向量起始128字节大小的位置。__bang_sumpool(temp_data, data, align_len,repeat,1,repeat,1,1,1);//对最后的128字节大小的数据进行求和。__bang_reduce_sum(dst, temp_data, align_len);T sum = dst[0];
CPU code:
for(int i=0;i<low_dim;i++){ T sum = 0.0; for(int j=0;j<high_dim;j++){ sum += input_addr[i][j]; } output_addr[i] = sum;}
BANG C code:
int align_low_dim = ALIGIN_UP(low_dim, 128);__memcpy(nram_input, input_addr, low_dim * sizeof(float), GDRAM2NRAM, align_low_dim * sizeof(float), low_dim * sizeof(float),high_dim -1);__bang_sumpool(nram_input, nram_input, align_low_dim, high_dim,1, high_dim,1,1,1);__memcoy(output_addr, nram_input, low_dim * sizeof(float), NRAM2GDRAM);
热门帖子
精华帖子