ppc_altivec_util.h

来自「最著名最快的分子模拟软件」· C头文件 代码 · 共 1,756 行 · 第 1/5 页

H
1,756
字号
                    vector float    vdata){	vector float tmp;  	tmp              = vec_sld(vdata,vdata,8);	vdata            = vec_add(vdata,tmp);	tmp              = vec_sld(vdata,vdata,4);	vdata            = vec_add(vdata,tmp);	tmp              = vec_lde(0,address);	/* all four positions in vdata contain the sum */	tmp              = vec_add(tmp,vdata);	vec_ste(tmp,0,address);}/** Load coords of a 3-atom water (9 floats) to all elements in SIMD vectors. * * We use our knowledge about water to improve the loading performance. * The allocated memory is always 8-byte aligned, so with nine atoms * we can always read 3 16-byte chunks (rounded down by vec_ld) * without going outside the current page (which might incur a page fault).  * The extra elements before and after the water dont matter as long as we dont * try to write to them. * * @param address    Address of first coord in water (oxygen x). * @param shiftvec   Address of shift vector x/y/z triplet to add to *                   all atom coordinates. * @param Ox         Output: Oxygen x coordinate in all elements. * @param Oy         Output: Oxygen y coordinate in all elements. * @param Oz         Output: Oxygen z coordinate in all elements. * @param H1x        Output: First hydrogen x coordinate in all elements. * @param H1y        Output: First hydrogen y coordinate in all elements. * @param H1z        Output: First hydrogen z coordinate in all elements. * @param H2x        Output: Second hydrogen x coordinate in all elements. * @param H2y        Output: Second hydrogen y coordinate in all elements. * @param H2z        Output: Second hydrogen z coordinate in all elements. */static inline void load_1_3atoms_shift_and_splat(float *address,                              float *shiftvec,                              vector float *Ox,                              vector float *Oy,                              vector float *Oz,                              vector float *H1x,                              vector float *H1y,                              vector float *H1z,                              vector float *H2x,                              vector float *H2y,                              vector float *H2z){	vector unsigned char perm;	vector float c1,c2,c3,sha,shb,sh1,sh2,sh3;	/* load shift */	shb               = load_xyz(shiftvec);  /* [ shX shY shZ -] */	/* load the coordinates */	perm              = vec_lvsl( 0, (int *) address ); 	c1                = vec_ld(  0, address ); 	c2                = vec_ld( 16, address ); 	c3                = vec_ld( 32, address );   	sha               = vec_sld(shb,shb,12);    /* [ - shX shY shZ ] */	sh1               = vec_sld(sha,shb,4);  /* [ shX shY shZ shX ] */	sh2               = vec_sld(sha,shb,8);  /* [ shY shZ shX shY ] */	sh3               = vec_sld(sha,shb,12);  /* [ shZ shX shY shZ ] */	c1                = vec_perm(c1,c2,perm);      /*  Ox  Oy  Oz H1x */	c2                = vec_perm(c2,c3,perm);      /* H1y H1z H2x H2y */	c3                = vec_perm(c3,c3,perm);      /* H2z   -   -   - */	c1                = vec_add(c1,sh1);	c2                = vec_add(c2,sh2);	c3                = vec_add(c3,sh3);	*Ox               = vec_splat(c1,0);	*Oy               = vec_splat(c1,1);	*Oz               = vec_splat(c1,2);	*H1x              = vec_splat(c1,3);	*H1y              = vec_splat(c2,0);	*H1z              = vec_splat(c2,1);	*H2x              = vec_splat(c2,2);	*H2y              = vec_splat(c2,3);	*H2z              = vec_splat(c3,0);}/** Load coords of a 4-atom water (12 floats) to all elements in SIMD vectors.** We use our knowledge about water to improve the loading performance.* The allocated memory is always 8-byte aligned, so with twelve atoms* we can always read 4 16-byte chunks (rounded down by vec_ld)* without going outside the current page (which might incur a page fault). * The extra elements before and after the water dont matter as long as we dont* try to write to them.** @param address    Address of first coord in 4-atom water (oxygen x).* @param shiftvec   Address of shift vector x/y/z triplet to add to*                   all atom coordinates.* @param Ox         Output: Oxygen x coordinate in all elements.* @param Oy         Output: Oxygen y coordinate in all elements.* @param Oz         Output: Oxygen z coordinate in all elements.* @param H1x        Output: First hydrogen x coordinate in all elements.* @param H1y        Output: First hydrogen y coordinate in all elements.* @param H1z        Output: First hydrogen z coordinate in all elements.* @param H2x        Output: Second hydrogen x coordinate in all elements.* @param H2y        Output: Second hydrogen y coordinate in all elements.* @param H2z        Output: Second hydrogen z coordinate in all elements.* @param Mx         Output: Virtual site x coordinate in all elements.* @param My         Output: Virtual site y coordinate in all elements.* @param Mz         Output: Virtual site z coordinate in all elements.*/static inline void load_1_4atoms_shift_and_splat(float *address,                                                 float *shiftvec,                                                 vector float *Ox,                                                 vector float *Oy,                                                 vector float *Oz,                                                 vector float *H1x,                                                 vector float *H1y,                                                 vector float *H1z,                                                 vector float *H2x,                                                 vector float *H2y,                                                 vector float *H2z,                                                 vector float *Mx,                                                 vector float *My,                                                 vector float *Mz){	vector unsigned char perm;	vector float c1,c2,c3,c4,sha,shb,sh1,sh2,sh3;	/* load shift data */	shb               = load_xyz(shiftvec);  /* [ shX shY shZ -] */	/* load the coordinates. */	c1                = vec_ld(  0, address ); 	c2                = vec_ld( 16, address ); 	c3                = vec_ld( 32, address ); 	if(((unsigned int)address) & 0xf) { 		/*  Load extra data and rotate if not aligned */		c4                = vec_ld( 48, address ); 		perm              = vec_lvsl( 0, (int *) address ); 		c1                = vec_perm(c1,c2,perm);      /*  Ox  Oy  Oz H1x */		c2                = vec_perm(c2,c3,perm);      /* H1y H1z H2x H2y */		c3                = vec_perm(c3,c4,perm);      /* H2z  Mx  My  Mz */	}	sha               = vec_sld(shb,shb,12);       /* [  -  shX shY shZ ] */	sh1               = vec_sld(sha,shb,4);        /* [ shX shY shZ shX ] */	sh2               = vec_sld(sha,shb,8);        /* [ shY shZ shX shY ] */	sh3               = vec_sld(sha,shb,12);       /* [ shZ shX shY shZ ] */	c1                = vec_add(c1,sh1);	c2                = vec_add(c2,sh2);	c3                = vec_add(c3,sh3);	*Ox               = vec_splat(c1,0);	*Oy               = vec_splat(c1,1);	*Oz               = vec_splat(c1,2);	*H1x              = vec_splat(c1,3);	*H1y              = vec_splat(c2,0);	*H1z              = vec_splat(c2,1);	*H2x              = vec_splat(c2,2);	*H2y              = vec_splat(c2,3);	*H2z              = vec_splat(c3,0);	*Mx              = vec_splat(c3,1);	*My              = vec_splat(c3,2);	*Mz              = vec_splat(c3,3);}/** Load coords of 4 3-atom waters (4*9 floats) to SIMD vectors.** We use our knowledge about water to improve the loading performance.* The allocated memory is always 8-byte aligned, so with nine atoms* we can always read 3 16-byte chunks (rounded down by vec_ld)* without going outside the current page (which might incur a page fault). * The extra elements before and after the water dont matter as long as we dont* try to write to them.** @param address1   Address of first coord in first water (oxygen x).* @param address2   Address of first coord in second water (oxygen x).* @param address3   Address of first coord in third water (oxygen x).* @param address4   Address of first coord in fourth water (oxygen x).* @param Ox         Output: Oxygen x coordinates.* @param Oy         Output: Oxygen y coordinates.* @param Oz         Output: Oxygen z coordinates.* @param H1x        Output: First hydrogen x coordinates.* @param H1y        Output: First hydrogen y coordinates.* @param H1z        Output: First hydrogen z coordinates.* @param H2x        Output: Second hydrogen x coordinates.* @param H2y        Output: Second hydrogen y coordinates.* @param H2z        Output: Second hydrogen z coordinates.*/static inline voidload_4_3atoms(float *address1,              float *address2,              float *address3,              float *address4,              vector float *Ox,              vector float *Oy,              vector float *Oz,              vector float *H1x,              vector float *H1y,              vector float *H1z,              vector float *H2x,              vector float *H2y,              vector float *H2z){	vector unsigned char perm;	vector float tmp1,tmp2,tmp3;  	vector float c1a,c2a,c3a;	vector float c1b,c2b,c3b;	vector float c1c,c2c,c3c;	vector float c1d,c2d,c3d;  	/* load the coordinates */	perm              = vec_lvsl( 0, address1 ); 	tmp1              = vec_ld(  0, address1 ); 	tmp2              = vec_ld( 16, address1 ); 	tmp3              = vec_ld( 32, address1 ); 	c1a               = vec_perm(tmp1,tmp2,perm);     /*  Oxa  Oya  Oza H1xa */	c2a               = vec_perm(tmp2,tmp3,perm);     /* H1ya H1za H2xa H2ya */	c3a               = vec_perm(tmp3,tmp3,perm);     /* H2za   -   -   - */	perm              = vec_lvsl( 0, address2 );	tmp1              = vec_ld(  0, address2 );	tmp2              = vec_ld( 16, address2 );	tmp3              = vec_ld( 32, address2 );	c1b               = vec_perm(tmp1,tmp2,perm);     /*  Oxb  Oyb  Ozb H1xb */	c2b               = vec_perm(tmp2,tmp3,perm);     /* H1yb H1zb H2xb H2yb */	c3b               = vec_perm(tmp3,tmp3,perm);     /* H2zb   -   -   - */	perm              = vec_lvsl( 0, address3 );	tmp1              = vec_ld(  0, address3 );	tmp2              = vec_ld( 16, address3 );	tmp3              = vec_ld( 32, address3 );	c1c               = vec_perm(tmp1,tmp2,perm);     /*  Oxc  Oyc  Ozc H1xc */	c2c               = vec_perm(tmp2,tmp3,perm);     /* H1yc H1zc H2xc H2yc */	c3c               = vec_perm(tmp3,tmp3,perm);     /* H2zc   -   -   - */	perm              = vec_lvsl( 0, address4 );	tmp1              = vec_ld(  0, address4 );	tmp2              = vec_ld( 16, address4 );	tmp3              = vec_ld( 32, address4 );	c1d               = vec_perm(tmp1,tmp2,perm);     /*  Oxd  Oyd  Ozd H1xd */	c2d               = vec_perm(tmp2,tmp3,perm);     /* H1yd H1zd H2xd H2yd */	c3d               = vec_perm(tmp3,tmp3,perm);     /* H2zd   -   -   - */	/* permute things */	tmp1              = vec_mergeh(c1a,c1c);          /*  Oxa  Oxc  Oya  Oyc */	c1a               = vec_mergel(c1a,c1c);          /*  Oza  Ozc H1xa H1xc */	c1c               = vec_mergeh(c1b,c1d);          /*  Oxb  Oxd  Oyb  Oyd */	c1b               = vec_mergel(c1b,c1d);          /*  Ozb  Ozd H1xb H1xd */	c1d               = vec_mergeh(c2a,c2c);          /* H1ya H1yc H1za H1zc */	c2a               = vec_mergel(c2a,c2c);          /* H2xa H2xc H2ya H2yc */	c2c               = vec_mergeh(c2b,c2d);          /* H1yb H1yd H1zb H1zd */	c2b               = vec_mergel(c2b,c2d);          /* H2xb H2xd H2yb H2yd */	c3a               = vec_mergeh(c3a,c3c);          /* H2za H2zc   -    -  */	c3b               = vec_mergeh(c3b,c3d);          /* H2zb H2zd   -    -  */  	*Ox               = vec_mergeh(tmp1,c1c);         /*  Oxa  Oxb  Oxc  Oxd */	*Oy               = vec_mergel(tmp1,c1c);         /*  Oya  Oyb  Oyc  Oyd */	*Oz               = vec_mergeh(c1a,c1b);          /*  Oza  Ozb  Ozc  Ozd */	*H1x              = vec_mergel(c1a,c1b);          /* H1xa H1xb H1xc H1xd */	*H1y              = vec_mergeh(c1d,c2c);          /* H1ya H1yb H1yc H1yd */	*H1z              = vec_mergel(c1d,c2c);          /* H1za H1zb H1zc H1zd */	*H2x              = vec_mergeh(c2a,c2b);          /* H2xa H2xb H2xc H2xd */	*H2y              = vec_mergel(c2a,c2b);          /* H2ya H2yb H2yc H2yd */	*H2z              = vec_mergeh(c3a,c3b);          /* H2za H2zb H2zc H2zd */}/** Load coords of 4 4-atom waters (4*12 floats) to SIMD vectors.** We use our knowledge about water to improve the loading performance.* The allocated memory is always 8-byte aligned, so with 12 atoms* we can always read 4 16-byte chunks (rounded down by vec_ld)* without going outside the current page (which might incur a page fault). * The extra elements before and after the water dont matter as long as we dont* try to write to them.** @param address1   Address of first coord in first water (oxygen x).* @param address2   Address of first coord in second water (oxygen x).* @param address3   Address of first coord in third water (oxygen x).* @param address4   Address of first coord in fourth water (oxygen x).* @param Ox         Output: Oxygen x coordinates.* @param Oy         Output: Oxygen y coordinates.* @param Oz         Output: Oxygen z coordinates.* @param H1x        Output: First hydrogen x coordinates.* @param H1y        Output: First hydrogen y coordinates.* @param H1z        Output: First hydrogen z coordinates.* @param H2x        Output: Second hydrogen x coordinates.* @param H2y        Output: Second hydrogen y coordinates.* @param H2z        Output: Second hydrogen z coordinates.* @param Mx         Output: Virtual site x coordinates.* @param My         Output: Virtual site y coordinates.* @param Mz         Output: Virtual site z coordinates.*/static inline void load_4_4atoms(float *address1,              float *address2,              float *address3,              float *address4,              vector float *Ox,              vector float *Oy,              vector float *Oz,              vector float *H1x,              vector float *H1y,              vector float *H1z,              vector float *H2x,              vector float *H2y,              vector float *H2z,              vector float *Mx,              vector float *My,              vector float *Mz){	vector unsigned char perm;	vector float tmp1,tmp2,tmp4;  	vector float c1a,c2a,c3a;	vector float c1b,c2b,c3b;	vector float c1c,c2c,c3c;	vector float c1d,c2d,c3d; 	/* load the coordinates */	c1a                 = vec_ld(  0, address1 ); 	c2a                 = vec_ld( 16, address1 ); 	c3a                 = vec_ld( 32, address1 ); 	if(((unsigned int)address1) & 0xf) { 		/*  Load extra data and rotate if not aligned */		tmp4              = vec_ld( 48, address1 );		perm              = vec_lvsl( 0, address1 ); 		c1a               = vec_perm(c1a,c2a,perm);      /*  Oxa  Oya  Oza H1xa */		c2a               = vec_perm(c2a,c3a,perm);      /* H1ya H1za H2xa H2ya */		c3a               = vec_perm(c3a,tmp4,perm);     /* H2za  Mxa  Mya  Mza */	}	c1b                 = vec_ld(  0, address2 ); 	c2b                 = vec_ld( 16, address2 ); 	c3b                 = vec_ld( 32, address2 ); 	if(((unsigned int)address2) & 0xf) { 		/*  Load extra data and rotate if not aligned */		tmp4              = vec_ld( 48, address2 );		perm              = vec_lvsl( 0, address2 ); 		c1b               = vec_perm(c1b,c2b,perm);      /*  Oxb  Oyb  Ozb H1xb */		c2b               = vec_perm(c2b,c3b,perm);      /* H1yb H1zb H2xb H2yb */		c3b               = vec_perm(c3b,tmp4,perm);     /* H2zb  Mxb  Myb  Mzb */	}	c1c                 = vec_ld(  0, address3 ); 

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?