mirror of
				https://github.com/paboyle/Grid.git
				synced 2025-11-04 05:54:32 +00:00 
			
		
		
		
	Compare commits
	
		
			753 Commits
		
	
	
		
			feature/CG
			...
			feature/la
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					9e56c65730 | ||
| 
						 | 
					ef4f2b8c41 | ||
| 
						 | 
					e8b95bd35b | ||
| 
						 | 
					7e35286860 | ||
| 
						 | 
					0486ff8e79 | ||
| 
						 | 
					e9cc21900f | ||
| 
						 | 
					0a8faac271 | ||
| 
						 | 
					abc4de0fd2 | ||
| 
						 | 
					cfe3cd76d1 | ||
| 
						 | 
					3fa5e3109f | ||
| 
						 | 
					8b7049f737 | ||
| 
						 | 
					c85024683e | ||
| 
						 | 
					1300b0b04b | ||
| 
						 | 
					e6d984b484 | ||
| 
						 | 
					1d18d95d4f | ||
| 
						 | 
					ae39ec85a3 | ||
| 
						 | 
					b96daf53a0 | ||
| 
						 | 
					46879e1658 | ||
| 
						 | 
					ae4de94798 | ||
| 
						 | 
					0ab555b4f5 | ||
| 
						 | 
					8e9be9f84f | ||
| 
						 | 
					d572170170 | ||
| 
						 | 
					12ccc73cf5 | ||
| 
						 | 
					e7564f8330 | ||
| 
						 | 
					91199a8ea0 | ||
| 
						 | 
					0494feec98 | ||
| 
						 | 
					a16b1e134e | ||
| 
						 | 
					769ad578f5 | ||
| 
						 | 
					eaac0044b5 | ||
| 
						 | 
					56042f002c | ||
| 
						 | 
					3bfd1f13e6 | ||
| 
						 | 
					70ab598c96 | ||
| 
						 | 
					1d0ca65e28 | ||
| 
						 | 
					2bc4d0a20e | ||
| 
						 | 
					092dcd4e04 | ||
| 
						 | 
					4a8c4ccfba | ||
| 
						 | 
					9b44189d5a | ||
| 
						 | 
					7da4856e8e | ||
| 
						 | 
					aaf1e33a77 | ||
| 
						 | 
					094c3d091a | ||
| 
						 | 
					4b98e524a0 | ||
| 
						 | 
					1a1f6d55f9 | ||
| 
						 | 
					21421656ab | ||
| 
						 | 
					6f687a67cd | ||
| 
						 | 
					b30754e762 | ||
| 
						 | 
					1e429a0d57 | ||
| 
						 | 
					d38a4de36c | ||
| 
						 | 
					ef1b7db374 | ||
| 
						 | 
					53a9aeb965 | ||
| 
						 | 
					e30fa9f4b8 | ||
| 
						 | 
					58e8d0a10d | ||
| 
						 | 
					62cf9cf638 | ||
| 
						 | 
					0fb458879d | ||
| 
						 | 
					725c513d94 | ||
| d8648307ff | |||
| 064315c00b | |||
| 
						 | 
					7c6cc85df6 | ||
| 
						 | 
					a6691ef87c | ||
| 
						 | 
					8e0ced627a | ||
| 
						 | 
					0de314870d | ||
| 
						 | 
					ffb91e53d2 | ||
| 
						 | 
					f4e8bf2858 | ||
| a74c34315c | |||
| 
						 | 
					69470ccc10 | ||
| 
						 | 
					b8b5934193 | ||
| 
						 | 
					75856f2945 | ||
| 
						 | 
					3c112a7a25 | ||
| 
						 | 
					ab3596d4d3 | ||
| 
						 | 
					a8c10b1933 | ||
| 
						 | 
					15e801af3f | ||
| 
						 | 
					0ffc235741 | ||
| 
						 | 
					8e19c99c7d | ||
| 
						 | 
					a0bc0ad06f | ||
| 
						 | 
					a8fb2835ca | ||
| 
						 | 
					bc862ce3ab | ||
| 
						 | 
					3267683e22 | ||
| 
						 | 
					f46a67ffb3 | ||
| 
						 | 
					f7b8383ef5 | ||
| 
						 | 
					10f2872aae | ||
| 
						 | 
					cd73897b8d | ||
| 
						 | 
					7a8f6af5f8 | ||
| 
						 | 
					49a5d9bac7 | ||
| 
						 | 
					2b3fdd4a58 | ||
| 
						 | 
					34502ec471 | ||
| 
						 | 
					8a43e88b4f | ||
| 
						 | 
					238df20370 | ||
| 
						 | 
					97a32a6145 | ||
| 
						 | 
					655492a443 | ||
| 
						 | 
					1cab06f6bd | ||
| 
						 | 
					f8024c262b | ||
| 
						 | 
					4cc5f01f4a | ||
| 
						 | 
					9c12c37aaf | ||
| 
						 | 
					806eaa0530 | ||
| 
						 | 
					01d0e54594 | ||
| 
						 | 
					5aafa335fe | ||
| 
						 | 
					8ba0494485 | ||
| 
						 | 
					d99d98d9fd | ||
| 
						 | 
					95a017a4ae | ||
| 
						 | 
					92f92379e6 | ||
| 
						 | 
					529e78d43f | ||
| 
						 | 
					4ec746d262 | ||
| 
						 | 
					66d819c054 | ||
| 
						 | 
					3f3686f869 | ||
| 
						 | 
					26bb829f8c | ||
| 
						 | 
					67cb04fc66 | ||
| 
						 | 
					a40bd68aed | ||
| 
						 | 
					36495e0fd2 | ||
| 
						 | 
					93f6c15772 | ||
| 
						 | 
					cb93eeff21 | ||
| 
						 | 
					c7cc7e6101 | ||
| 
						 | 
					c349aa6511 | ||
| 
						 | 
					3bae0a2d5c | ||
| 
						 | 
					c1c7566089 | ||
| 
						 | 
					2439999ec8 | ||
| 
						 | 
					1d96f662e3 | ||
| 
						 | 
					41d1889941 | ||
| 
						 | 
					0c3981e0c3 | ||
| 
						 | 
					c727bd4609 | ||
| 
						 | 
					db23749b67 | ||
| 
						 | 
					751f2b9703 | ||
| 
						 | 
					697c0603ce | ||
| 
						 | 
					14bedebb11 | ||
| 
						 | 
					47b5c07ffb | ||
| 
						 | 
					da86a2bf54 | ||
| 
						 | 
					c1cb60a0b3 | ||
| 
						 | 
					5ed5b4bfbf | ||
| 
						 | 
					de84aacdfd | ||
| 
						 | 
					2888003765 | ||
| 
						 | 
					da06bf5b95 | ||
| 
						 | 
					20999c1370 | ||
| 
						 | 
					33f0ed1a33 | ||
| 
						 | 
					50be56433b | ||
| 
						 | 
					43924007db | ||
| 
						 | 
					78ef10e60f | ||
| 679ae98b14 | |||
| 
						 | 
					90f6bc16bb | ||
| 
						 | 
					9b5b639546 | ||
| 
						 | 
					945767c6d8 | ||
| 
						 | 
					422cdf4979 | ||
| 
						 | 
					38db174f3b | ||
| 
						 | 
					92e364a35f | ||
| 58299b8ba2 | |||
| 124bf4d829 | |||
| e8e56b3414 | |||
| 89c430136d | |||
| ea9aef7baa | |||
| c9e9e8061d | |||
| 
						 | 
					453cf2a1c6 | ||
| 
						 | 
					de7bbfa5f9 | ||
| dda8d77c87 | |||
| aa29f4346a | |||
| 
						 | 
					86116dbed6 | ||
| 
						 | 
					7bd31e3f7c | ||
| 
						 | 
					74f451715f | ||
| 
						 | 
					655be8ed76 | ||
| 
						 | 
					4063238943 | ||
| 
						 | 
					3344788fa1 | ||
| 
						 | 
					99220f6531 | ||
| 
						 | 
					2a6d093749 | ||
| 
						 | 
					c947947fad | ||
| 
						 | 
					f555b50547 | ||
| 
						 | 
					738c1a11c2 | ||
| 
						 | 
					f8797e1e3e | ||
| 
						 | 
					fd1eb7de13 | ||
| 
						 | 
					2ce898efa3 | ||
| 
						 | 
					ab66bac4e6 | ||
| 
						 | 
					56277a11c8 | ||
| 
						 | 
					916e9e1d3e | ||
| 
						 | 
					5b55867a7a | ||
| 
						 | 
					3accb1ef89 | ||
| 
						 | 
					e3d0e31525 | ||
| 
						 | 
					5812eb8a8c | ||
| 
						 | 
					4dd3763294 | ||
| 
						 | 
					c429ace748 | ||
| 
						 | 
					ac58565d0a | ||
| 
						 | 
					3703b718aa | ||
| 
						 | 
					b722889234 | ||
| 
						 | 
					abba44a837 | ||
| 
						 | 
					f301be94ce | ||
| 
						 | 
					1d1b225497 | ||
| 
						 | 
					53a785a3dd | ||
| 
						 | 
					736bf3c866 | ||
| 
						 | 
					b9bbe5d188 | ||
| 
						 | 
					3844bcf800 | ||
| 
						 | 
					e1a2319d01 | ||
| 
						 | 
					180c732b4c | ||
| 
						 | 
					957a706d0b | ||
| 
						 | 
					d2312e9874 | ||
| 
						 | 
					fc4ab9ccd5 | ||
| 
						 | 
					4a340aa5ca | ||
| 
						 | 
					3b7de792d5 | ||
| 
						 | 
					557c3fa109 | ||
| 
						 | 
					ec18e9f7f6 | ||
| 
						 | 
					a839d5bc55 | ||
| 
						 | 
					de41b84c5c | ||
| 
						 | 
					8e161152e4 | ||
| 
						 | 
					3141ebac10 | ||
| 
						 | 
					7ede696126 | ||
| 
						 | 
					bf516c3b81 | ||
| 
						 | 
					441a52ee5d | ||
| 
						 | 
					a8db024c92 | ||
| 
						 | 
					a9c22d5f43 | ||
| 
						 | 
					3ca41458a3 | ||
| 
						 | 
					9e2d29c644 | ||
| 
						 | 
					951be75292 | ||
| 
						 | 
					b9113ed310 | ||
| 
						 | 
					42fb49d3fd | ||
| 
						 | 
					2a54c9aaab | ||
| 
						 | 
					0957378679 | ||
| 
						 | 
					2ed6c76fc5 | ||
| 
						 | 
					d3b9a7fa14 | ||
| 
						 | 
					75ea306ce9 | ||
| 
						 | 
					4226c633c4 | ||
| 
						 | 
					5a4eafbf7e | ||
| 
						 | 
					eb8e26018b | ||
| 
						 | 
					db5ea001a3 | ||
| 
						 | 
					2846f079e5 | ||
| 
						 | 
					1d502e4ed6 | ||
| 
						 | 
					73cdf0fffe | ||
| 
						 | 
					1c25773319 | ||
| 
						 | 
					c38400b26f | ||
| 
						 | 
					9c3065b860 | ||
| 
						 | 
					94eb829d08 | ||
| 
						 | 
					68392ddb5b | ||
| 
						 | 
					cb6b81ae82 | ||
| 90ec6eda0c | |||
| fe8d625694 | |||
| 53e76b41d2 | |||
| 8ef4300412 | |||
| 98a24ebf31 | |||
| 
						 | 
					b12dc89d26 | ||
| 
						 | 
					d80d802f9d | ||
| 
						 | 
					3d99b09dba | ||
| 
						 | 
					db5f6d3ae3 | ||
| 
						 | 
					683550f116 | ||
| 
						 | 
					5e477ec553 | ||
| 
						 | 
					55d0329624 | ||
| 
						 | 
					86aaa35294 | ||
| 
						 | 
					172d3dc93a | ||
| 
						 | 
					8c540333d5 | ||
| 
						 | 
					5592f7b8c1 | ||
| 
						 | 
					35da4ece0b | ||
| 
						 | 
					061b15b9e9 | ||
| ff4e54ef80 | |||
| 
						 | 
					561426f6eb | ||
| 
						 | 
					83f6fab8fa | ||
| 
						 | 
					0fade84ab2 | ||
| 
						 | 
					9dc7ca4c3b | ||
| 
						 | 
					935d82f5b1 | ||
| 
						 | 
					9cbcdd65d7 | ||
| 
						 | 
					f18f5ed926 | ||
| 
						 | 
					d1d63a4f2d | ||
| 
						 | 
					7e5faa0f34 | ||
| 
						 | 
					6af459cae4 | ||
| 
						 | 
					1c4bc7ed38 | ||
| 
						 | 
					cd1bd921bd | ||
| 
						 | 
					fff5751b1a | ||
| 
						 | 
					2c81696fdd | ||
| 
						 | 
					c9dc22efa1 | ||
| 
						 | 
					0ab04a000f | ||
| 
						 | 
					93ea5d9468 | ||
| 
						 | 
					1ec5d32369 | ||
| 
						 | 
					9fd23faadf | ||
| 
						 | 
					10e4fa0dc8 | ||
| 
						 | 
					c4aca1dde4 | ||
| 
						 | 
					b9e8ea3aaa | ||
| 
						 | 
					077aa728b9 | ||
| 
						 | 
					a8d83d886e | ||
| 
						 | 
					7fd46eeec4 | ||
| 
						 | 
					e0c4eeb3ec | ||
| 
						 | 
					cb9a297a0a | ||
| 
						 | 
					2b115929dc | ||
| 
						 | 
					5c6571dab1 | ||
| 
						 | 
					417ec56cca | ||
| 
						 | 
					756bc25008 | ||
| 
						 | 
					35695ba57a | ||
| 
						 | 
					81ead48850 | ||
| 
						 | 
					d805867e02 | ||
| 
						 | 
					e55a751e23 | ||
| 
						 | 
					358eb75995 | ||
| 
						 | 
					98f9318279 | ||
| 
						 | 
					4b17e8eba8 | ||
| 
						 | 
					75112a632a | ||
| 
						 | 
					18bde08d1b | ||
| 
						 | 
					d45cd7e677 | ||
| 
						 | 
					4e96679797 | ||
| 
						 | 
					4c1ea8677e | ||
| 
						 | 
					fc93f0b2ec | ||
| 
						 | 
					8c8473998d | ||
| 
						 | 
					120fb59978 | ||
| 
						 | 
					fd56b3ff38 | ||
| 
						 | 
					0ec6829edc | ||
| 
						 | 
					18b7845b7b | ||
| 
						 | 
					3d0fe15374 | ||
| 
						 | 
					91886068fe | ||
| 
						 | 
					6d1e9e5f92 | ||
| 
						 | 
					b640230b1e | ||
| 
						 | 
					e7c36771ed | ||
| 
						 | 
					8dc57a1e25 | ||
| 
						 | 
					f57bd770b0 | ||
| 
						 | 
					4ed10a3d06 | ||
| 
						 | 
					dfefc70b57 | ||
| 
						 | 
					0b61f75c9e | ||
| 
						 | 
					33edde245d | ||
| 
						 | 
					b64e004555 | ||
| 
						 | 
					447c5e6cd7 | ||
| 
						 | 
					8b99d80d8c | ||
| 
						 | 
					b3dede4dd3 | ||
| 
						 | 
					4e34132f4d | ||
| 
						 | 
					c07cb10247 | ||
| 
						 | 
					d7767a2a62 | ||
| 
						 | 
					ec035983fd | ||
| 
						 | 
					3901b17ade | ||
| 
						 | 
					af230a1fb8 | ||
| 
						 | 
					06a132e3f9 | ||
| 
						 | 
					596dcd85b2 | ||
| 
						 | 
					96d44d5c55 | ||
| 
						 | 
					7270c6a150 | ||
| 
						 | 
					7fe797daf8 | ||
| 
						 | 
					486a01294a | ||
| 
						 | 
					586a7c90b7 | ||
| 
						 | 
					e099dcdae7 | ||
| 
						 | 
					4e7ab3166f | ||
| 
						 | 
					aac80cbb44 | ||
| 
						 | 
					c80948411b | ||
| 
						 | 
					95625a7bd1 | ||
| 
						 | 
					0796696733 | ||
| 
						 | 
					f8b9ad7d50 | ||
| 
						 | 
					04a1959895 | ||
| 
						 | 
					cc773ae70c | ||
| 
						 | 
					d21c51b9be | ||
| 
						 | 
					597a7b4b3a | ||
| 
						 | 
					1c30e9a961 | ||
| 
						 | 
					93cc270016 | ||
| 
						 | 
					29b60f7e1a | ||
| 
						 | 
					041884acf0 | ||
| 
						 | 
					15e668eef1 | ||
| 
						 | 
					bf7e3f20d4 | ||
| 
						 | 
					902afcfbaf | ||
| 
						 | 
					3ae92fa2e6 | ||
| 
						 | 
					3906cd2149 | ||
| 
						 | 
					5a1fb29db7 | ||
| 
						 | 
					661fc4d3d1 | ||
| 
						 | 
					41009cc142 | ||
| 
						 | 
					37720c4db7 | ||
| 
						 | 
					1a30455a10 | ||
| 
						 | 
					97a6b61551 | ||
| 
						 | 
					cd0da81196 | ||
| 
						 | 
					f246fe3304 | ||
| 
						 | 
					8a29c16bde | ||
| 
						 | 
					d68907fc3e | ||
| 
						 | 
					5c0adf7bf2 | ||
| 
						 | 
					be3a8249c6 | ||
| 
						 | 
					bd600702cf | ||
| 
						 | 
					f011bdb869 | ||
| 
						 | 
					bafb101e4f | ||
| 
						 | 
					08fdf05528 | ||
| 
						 | 
					aca7a3ef0a | ||
| 
						 | 
					9e72a6b22e | ||
| 
						 | 
					1c12c5612c | ||
| 
						 | 
					a8193c4bcb | ||
| 
						 | 
					c3d7ec65fa | ||
| 
						 | 
					8b6a6c8236 | ||
| 
						 | 
					e0571c872b | ||
| 
						 | 
					c67f41887b | ||
| 
						 | 
					84687ccf1f | ||
| 
						 | 
					3274561cf8 | ||
| e08fbb3771 | |||
| 
						 | 
					d7464aa0fe | ||
| 
						 | 
					00d29153f0 | ||
| 2ce989f220 | |||
| 
						 | 
					d7a1dc85be | ||
| 
						 | 
					fc19503673 | ||
| 
						 | 
					beba824136 | ||
| 
						 | 
					6ebf8b12b6 | ||
| 
						 | 
					e5a7ed4362 | ||
| 
						 | 
					b9f7ea47c3 | ||
| 
						 | 
					06f7ee202e | ||
| 
						 | 
					2b2fc6453f | ||
| 
						 | 
					bdd2765461 | ||
| 
						 | 
					2c246551d0 | ||
| 
						 | 
					71ac2e7940 | ||
| 
						 | 
					2bf4688e83 | ||
| 
						 | 
					a48ee6f0f2 | ||
| 
						 | 
					73547cca66 | ||
| 
						 | 
					123c673db7 | ||
| 
						 | 
					61f82216e2 | ||
| 
						 | 
					8e7ca92278 | ||
| 
						 | 
					485ad6fde0 | ||
| 
						 | 
					6ea2184e18 | ||
| 
						 | 
					fdc170b8a3 | ||
| 
						 | 
					060da786e9 | ||
| 
						 | 
					85c7bc4321 | ||
| 
						 | 
					0883d6a7ce | ||
| 
						 | 
					9ff97b4711 | ||
| 
						 | 
					b5e9c900a4 | ||
| 
						 | 
					4bbdfb434c | ||
| 
						 | 
					4a45c06dd7 | ||
| 
						 | 
					d6a7d7d1e0 | ||
| 
						 | 
					1a122a0dd8 | ||
| 
						 | 
					20e20733e8 | ||
| 
						 | 
					b7cd1a19e3 | ||
| 
						 | 
					f510002a62 | ||
| 
						 | 
					c94133af49 | ||
| e7d8030a64 | |||
| d775fbb2f9 | |||
| 863855f46f | |||
| 419af7610d | |||
| 
						 | 
					1e257a1251 | ||
| 
						 | 
					522f6bf91a | ||
| 
						 | 
					d35d87d2c2 | ||
| 
						 | 
					74a5cda84b | ||
| 
						 | 
					5be05d85b8 | ||
| 
						 | 
					35ac85aea8 | ||
| 
						 | 
					fa237401ff | ||
| 
						 | 
					97053adcb5 | ||
| 
						 | 
					f8fbe4d7a3 | ||
| 
						 | 
					ef31c012bf | ||
| 7da7d263c4 | |||
| 1140573027 | |||
| 
						 | 
					9e9f621d5d | ||
| 
						 | 
					651e1a7cbc | ||
| a0cfbb6e88 | |||
| 
						 | 
					c4d3672720 | ||
| 515a26b3c6 | |||
| 
						 | 
					16be6d378c | ||
| 
						 | 
					f05d0565aa | ||
| c946d3bf3f | |||
| 1c68098780 | |||
| 
						 | 
					9bf4108d1f | ||
| 
						 | 
					899e685627 | ||
| 
						 | 
					6929a84c70 | ||
| 
						 | 
					5c779a789b | ||
| 3bf993d81a | |||
| fad743fbb1 | |||
| 
						 | 
					e863a948e3 | ||
| 
						 | 
					977f34dca6 | ||
| 
						 | 
					90ad956340 | ||
| 
						 | 
					7996f06335 | ||
| 
						 | 
					ef8d3831eb | ||
| 
						 | 
					70ed9fc40c | ||
| 
						 | 
					7b40a3e3e5 | ||
| 4d3787db65 | |||
| 
						 | 
					677757cfeb | ||
| 
						 | 
					f7fbbaaca3 | ||
| 
						 | 
					17629b8d9e | ||
| 
						 | 
					0baa20d292 | ||
| 
						 | 
					4571c918a4 | ||
| 
						 | 
					5251ea4d30 | ||
| 05cb6d318a | |||
| 0432e30256 | |||
| 2c3ebc1e07 | |||
| 068b28af2d | |||
| f7db342f49 | |||
| d65e81518f | |||
| 
						 | 
					7f456b4173 | ||
| a37e71f362 | |||
| 
						 | 
					c291ef77b5 | ||
| 
						 | 
					7dd2764bb2 | ||
| 
						 | 
					244f8fb6dc | ||
| 
						 | 
					05c1924819 | ||
| b7da264b0a | |||
| 74ac2aa676 | |||
| 4c75095c61 | |||
| afa095d33d | |||
| 6b5259cc10 | |||
| 
						 | 
					27dfe816fa | ||
| 
						 | 
					af29be2c90 | ||
| 
						 | 
					f96fac0aee | ||
| 7423a352c5 | |||
| 81e66d6631 | |||
| ade1058e5f | |||
| 6eea9e4da7 | |||
| 2c673666da | |||
| 
						 | 
					07f2ebea1b | ||
| d6401e6d2c | |||
| 24d3d31b01 | |||
| 
						 | 
					851f2ad8ef | ||
| 5405526424 | |||
| f3f0b6fef9 | |||
| 654e0b0fd0 | |||
| 4be08ebccc | |||
| f599cb5b17 | |||
| 
						 | 
					23e0561dd6 | ||
| a4a509497a | |||
| 5803933aea | |||
| 
						 | 
					8ae1a95ec6 | ||
| 
						 | 
					82b7d4eaf0 | ||
| 
						 | 
					78774fbdc0 | ||
| 
						 | 
					924130833e | ||
| 
						 | 
					7cf833dfe9 | ||
| 
						 | 
					0157274762 | ||
| 
						 | 
					87e8aad5a0 | ||
| 
						 | 
					c6f59c2933 | ||
| 91a3534054 | |||
| 16a8e3d0d4 | |||
| 
						 | 
					b7f90aa011 | ||
| 
						 | 
					f22b79da8f | ||
| 
						 | 
					3855673ebf | ||
| 
						 | 
					4db82da0db | ||
| 
						 | 
					0cdc3d2fa5 | ||
| 41df1db811 | |||
| 
						 | 
					0dfda4bb90 | ||
| 
						 | 
					1189ebc8b5 | ||
| 
						 | 
					1bb8578173 | ||
| 
						 | 
					c3b6d573b9 | ||
| 
						 | 
					1e179c903d | ||
| 
						 | 
					669cfca9b7 | ||
| 
						 | 
					ff2f559a57 | ||
| 
						 | 
					03c81bd902 | ||
| 
						 | 
					a869addef1 | ||
| 
						 | 
					1caa3fbc2d | ||
| 
						 | 
					3d21297bbb | ||
| 
						 | 
					25efefc5b4 | ||
| 
						 | 
					eabf316ed9 | ||
| 
						 | 
					04ae7929a3 | ||
| 
						 | 
					caba0d42a5 | ||
| 
						 | 
					9ae81c06d2 | ||
| 
						 | 
					0903c48caa | ||
| 
						 | 
					7dc36628a1 | ||
| 
						 | 
					b8cdb3e90a | ||
| 
						 | 
					5241245534 | ||
| 
						 | 
					960316e207 | ||
| 
						 | 
					5214846341 | ||
| 3215ae6b7e | |||
| 7a85fddc7e | |||
| 
						 | 
					ce1a115e0b | ||
| f8d11ff673 | |||
| 
						 | 
					3f2d53a994 | ||
| 
						 | 
					8a337f3070 | ||
| 
						 | 
					a59f5374d7 | ||
| 
						 | 
					4b220972ac | ||
| 
						 | 
					629f43e36c | ||
| 
						 | 
					a3172b3455 | ||
| 
						 | 
					3e6945cd65 | ||
| 
						 | 
					87be03006a | ||
| 
						 | 
					f17436fec2 | ||
| 
						 | 
					4d8b01b7ed | ||
| 
						 | 
					fa6acccf55 | ||
| 
						 | 
					55cb22ad67 | ||
| 
						 | 
					df9108154d | ||
| 
						 | 
					b3e7f600da | ||
| 
						 | 
					d4071daf2a | ||
| 
						 | 
					a2a6329094 | ||
| 
						 | 
					eabc577940 | ||
| 67d72000e7 | |||
| 80cef1c78f | |||
| 91e98b1dd5 | |||
| b791c274b0 | |||
| 596dd570c7 | |||
| cad158e42f | |||
| f63fac0c69 | |||
| ab92de89ab | |||
| 846272b037 | |||
| f3e49e4b73 | |||
| decbb61ec1 | |||
| 7e2482aad1 | |||
| e1653a9f94 | |||
| ea40854e0b | |||
| 34df71e755 | |||
| 3af663e17b | |||
| 
						 | 
					0bd296dda4 | ||
| 
						 | 
					af0ccdd8e9 | ||
| c22c3db9ad | |||
| 013e710c7d | |||
| 16693bd69d | |||
| de8f80cf94 | |||
| 
						 | 
					2fb92dbc6e | ||
| 
						 | 
					5c74b6028b | ||
| 
						 | 
					e0be2b6e6c | ||
| 
						 | 
					ef72f322d2 | ||
| 
						 | 
					426197e446 | ||
| 
						 | 
					99e2c1e666 | ||
| 
						 | 
					1440565a10 | ||
| 
						 | 
					e9f0c0ea39 | ||
| 
						 | 
					7bc2065113 | ||
| 4a87486365 | |||
| 
						 | 
					fe187e9ed3 | ||
| 
						 | 
					0091b50f49 | ||
| 
						 | 
					fb8d4b2357 | ||
| 
						 | 
					ff71a8e847 | ||
| 
						 | 
					83fa038bdf | ||
| 
						 | 
					7a61feb6d3 | ||
| 
						 | 
					69ae817d1c | ||
| 
						 | 
					2bd4233919 | ||
| 
						 | 
					143c70e29f | ||
| 51322da6f8 | |||
| 49c3eeb378 | |||
| c56707e003 | |||
| 
						 | 
					b812d5e39c | ||
| 5b3edf08a4 | |||
| bd1d1cca34 | |||
| 646b11f5c2 | |||
| a683a0f55a | |||
| e6effcfd95 | |||
| aa016f61b9 | |||
| d42a1b73c4 | |||
| d292657ef7 | |||
| d1f7c6b94e | |||
| 7ae734103e | |||
| 
						 | 
					01480da0a8 | ||
| 7a1ac45679 | |||
| 320268fe93 | |||
| dd6fb140c5 | |||
| 0b4f680d28 | |||
| a69086ba1f | |||
| 7433eed274 | |||
| ee5b1fe043 | |||
| 1540616b22 | |||
| 8190523e4c | |||
| b5555d85a7 | |||
| 9ad3d3453e | |||
| d8b716d2cd | |||
| 
						 | 
					c097fd041a | ||
| 
						 | 
					77fb25fb29 | ||
| 
						 | 
					389e0a77bd | ||
| 43928846f2 | |||
| fabcd4179d | |||
| a8843c9af6 | |||
| 7a1a7a685e | |||
| 
						 | 
					95f43d27ae | ||
| 
						 | 
					668ca57702 | ||
| 
						 | 
					62749d05a6 | ||
| 
						 | 
					3834feb4b7 | ||
| 
						 | 
					454302414d | ||
| 
						 | 
					6f8b771a37 | ||
| 
						 | 
					4e1ffdd17c | ||
| 1aa695cd78 | |||
| 
						 | 
					a783282b8b | ||
| 
						 | 
					19b85d8486 | ||
| 13a8997789 | |||
| 
						 | 
					ee686a7d85 | ||
| 
						 | 
					1c5b7a6be5 | ||
| 
						 | 
					164d3691db | ||
| 
						 | 
					1d666771f9 | ||
| 
						 | 
					d50055cd96 | ||
| 
						 | 
					47c7159177 | ||
| 
						 | 
					f415db583a | ||
| 
						 | 
					f55c16f984 | ||
| 
						 | 
					df67e013ca | ||
| 
						 | 
					3e990c9d0a | ||
| 
						 | 
					4b740fc8fd | ||
| 
						 | 
					cccd14b09e | ||
| 
						 | 
					e6acffdfc2 | ||
| 
						 | 
					392130a537 | ||
| 
						 | 
					deef2673b2 | ||
| 
						 | 
					977b0a6dd9 | ||
| 
						 | 
					977d844394 | ||
| 
						 | 
					590675e2ca | ||
| 
						 | 
					8c65bdf6d3 | ||
| 
						 | 
					74f1ed3bc5 | ||
| 
						 | 
					79270ef510 | ||
| 
						 | 
					e250e6b7bb | ||
| 
						 | 
					261342c15f | ||
| 
						 | 
					eda4dd622e | ||
| 
						 | 
					c68a2b9637 | ||
| 
						 | 
					293df6cd20 | ||
| 
						 | 
					65f61bb3bf | ||
| 
						 | 
					26b9740d53 | ||
| 
						 | 
					6eb873dd96 | ||
| 
						 | 
					11b4c80b27 | ||
| 
						 | 
					c065e454c3 | ||
| 
						 | 
					d9b5fbd374 | ||
| 
						 | 
					cfbc1a26b8 | ||
| 
						 | 
					257f69f931 | ||
| 
						 | 
					e415260961 | ||
| a034e9901b | |||
| 7ff7c7d90d | |||
| a2e9430abe | |||
| 2485ef9c9c | |||
| e0b7004f96 | |||
| 75fc295f6e | |||
| 0b731b5d80 | |||
| 8e2078be71 | |||
| 1826ed06a3 | |||
| 3ff96c502b | |||
| 15a0908bfc | |||
| bb2125962b | |||
| 232fda5fe1 | |||
| 2b31bf61ff | |||
| afe5a94745 | |||
| 7ae667c767 | |||
| 07f0b69784 | |||
| 5c06e89d69 | |||
| 3d75e0f0d1 | |||
| 362f255100 | |||
| 3d78ed03ef | |||
| 835003b3c5 | |||
| 328d213c9e | |||
| 56a8d7a5bc | |||
| 78198d1b04 | |||
| 84fa2bdce6 | |||
| 29dfe99e7c | |||
| d604580e5a | |||
| 7dfdc9baa0 | |||
| 9e986654e6 | |||
| df3fbc477e | |||
| bb580ae077 | |||
| 2c226753ab | |||
| ea0cea668e | |||
| 75cd72a421 | |||
| cbe52b0659 | |||
| 3aa6463ede | |||
| 312637e5fb | |||
| 798d8f7340 | |||
| ba878724ce | |||
| b865dd9da8 | |||
| 8b313a35ac | |||
| 02ec23cdad | |||
| 6e83b6a203 | |||
| 48fcc34d72 | |||
| d08d93c44c | |||
| 0ab10cdedb | |||
| 22653edf12 | |||
| 12d2a95846 | |||
| 978cf52f6b | |||
| 63b730de80 | |||
| 7905c5b8e5 | |||
| 5e4b58ac40 | |||
| 468d8dc682 | |||
| beb11fd4ef | |||
| d7662b5175 | |||
| dc5f32e5f0 | |||
| 1869d28429 | |||
| 405b175665 | |||
| e33b0f6ff7 | |||
| 9ee54e0db7 | |||
| feae35d92c | |||
| 3834d81181 | |||
| 179e82b5ca | |||
| f2c59c8730 | |||
| fdd0848593 | |||
| 92f666905f | |||
| 5980fa8640 | |||
| a0d8eb2c24 | |||
| 1e10b4571d | |||
| 02f8b84ac9 | |||
| cfd368596d | |||
| ae682674e0 | |||
| 17c43f49ac | |||
| 30146e977c | |||
| 54eacec261 | |||
| 76c78f04e2 | |||
| 379580cd89 | |||
| 14a80733f9 | |||
| d4db009a58 | |||
| 20ce7e0270 | |||
| bb195607ab | |||
| 6f090e22c0 | |||
| 339e983172 | |||
| 4a7f3d1b7b | |||
| c4e2202550 | |||
| 538b16610b | 
							
								
								
									
										21
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										21
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -9,6 +9,7 @@
 | 
			
		||||
################
 | 
			
		||||
*~
 | 
			
		||||
*#
 | 
			
		||||
*.sublime-*
 | 
			
		||||
 | 
			
		||||
# Precompiled Headers #
 | 
			
		||||
#######################
 | 
			
		||||
@@ -91,6 +92,7 @@ build*/*
 | 
			
		||||
#####################
 | 
			
		||||
*.xcodeproj/*
 | 
			
		||||
build.sh
 | 
			
		||||
.vscode
 | 
			
		||||
 | 
			
		||||
# Eigen source #
 | 
			
		||||
################
 | 
			
		||||
@@ -103,4 +105,21 @@ lib/fftw/*
 | 
			
		||||
# libtool macros #
 | 
			
		||||
##################
 | 
			
		||||
m4/lt*
 | 
			
		||||
m4/libtool.m4
 | 
			
		||||
m4/libtool.m4
 | 
			
		||||
 | 
			
		||||
# github pages #
 | 
			
		||||
################
 | 
			
		||||
gh-pages/
 | 
			
		||||
 | 
			
		||||
# Buck files #
 | 
			
		||||
##############
 | 
			
		||||
.buck*
 | 
			
		||||
buck-out
 | 
			
		||||
BUCK
 | 
			
		||||
make-bin-BUCK.sh
 | 
			
		||||
 | 
			
		||||
# generated sources #
 | 
			
		||||
#####################
 | 
			
		||||
lib/qcd/spin/gamma-gen/*.h
 | 
			
		||||
lib/qcd/spin/gamma-gen/*.cc
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										28
									
								
								.travis.yml
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								.travis.yml
									
									
									
									
									
								
							@@ -7,9 +7,11 @@ cache:
 | 
			
		||||
matrix:
 | 
			
		||||
  include:
 | 
			
		||||
    - os:        osx
 | 
			
		||||
      osx_image: xcode7.2
 | 
			
		||||
      osx_image: xcode8.3
 | 
			
		||||
      compiler: clang
 | 
			
		||||
    - compiler: gcc
 | 
			
		||||
      dist: trusty
 | 
			
		||||
      sudo: required
 | 
			
		||||
      addons:
 | 
			
		||||
        apt:
 | 
			
		||||
          sources:
 | 
			
		||||
@@ -24,6 +26,8 @@ matrix:
 | 
			
		||||
            - binutils-dev
 | 
			
		||||
      env: VERSION=-4.9
 | 
			
		||||
    - compiler: gcc
 | 
			
		||||
      dist: trusty
 | 
			
		||||
      sudo: required
 | 
			
		||||
      addons:
 | 
			
		||||
        apt:
 | 
			
		||||
          sources:
 | 
			
		||||
@@ -38,6 +42,7 @@ matrix:
 | 
			
		||||
            - binutils-dev
 | 
			
		||||
      env: VERSION=-5
 | 
			
		||||
    - compiler: clang
 | 
			
		||||
      dist: trusty
 | 
			
		||||
      addons:
 | 
			
		||||
        apt:
 | 
			
		||||
          sources:
 | 
			
		||||
@@ -52,6 +57,7 @@ matrix:
 | 
			
		||||
            - binutils-dev
 | 
			
		||||
      env: CLANG_LINK=http://llvm.org/releases/3.8.0/clang+llvm-3.8.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz
 | 
			
		||||
    - compiler: clang
 | 
			
		||||
      dist: trusty
 | 
			
		||||
      addons:
 | 
			
		||||
        apt:
 | 
			
		||||
          sources:
 | 
			
		||||
@@ -73,13 +79,15 @@ before_install:
 | 
			
		||||
    - if [[ "$TRAVIS_OS_NAME" == "linux" ]] && [[ "$CC" == "clang" ]]; then export LD_LIBRARY_PATH="${GRIDDIR}/clang/lib:${LD_LIBRARY_PATH}"; fi
 | 
			
		||||
    - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; fi
 | 
			
		||||
    - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install libmpc; fi
 | 
			
		||||
    - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install openmpi; fi
 | 
			
		||||
    - if [[ "$TRAVIS_OS_NAME" == "osx" ]] && [[ "$CC" == "gcc" ]]; then brew install gcc5; fi
 | 
			
		||||
    
 | 
			
		||||
install:
 | 
			
		||||
    - export CC=$CC$VERSION
 | 
			
		||||
    - export CXX=$CXX$VERSION
 | 
			
		||||
    - echo $PATH
 | 
			
		||||
    - which autoconf
 | 
			
		||||
    - autoconf  --version
 | 
			
		||||
    - which automake
 | 
			
		||||
    - automake  --version
 | 
			
		||||
    - which $CC
 | 
			
		||||
    - $CC  --version
 | 
			
		||||
    - which $CXX
 | 
			
		||||
@@ -92,15 +100,15 @@ script:
 | 
			
		||||
    - cd build
 | 
			
		||||
    - ../configure --enable-precision=single --enable-simd=SSE4 --enable-comms=none
 | 
			
		||||
    - make -j4 
 | 
			
		||||
    - ./benchmarks/Benchmark_dwf --threads 1
 | 
			
		||||
    - ./benchmarks/Benchmark_dwf --threads 1 --debug-signals
 | 
			
		||||
    - echo make clean
 | 
			
		||||
    - ../configure --enable-precision=double --enable-simd=SSE4 --enable-comms=none
 | 
			
		||||
    - make -j4
 | 
			
		||||
    - ./benchmarks/Benchmark_dwf --threads 1
 | 
			
		||||
    - ./benchmarks/Benchmark_dwf --threads 1 --debug-signals
 | 
			
		||||
    - make check
 | 
			
		||||
    - echo make clean
 | 
			
		||||
    - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then export CXXFLAGS='-DMPI_UINT32_T=MPI_UNSIGNED -DMPI_UINT64_T=MPI_UNSIGNED_LONG'; fi
 | 
			
		||||
    - ../configure --enable-precision=single --enable-simd=SSE4 --enable-comms=mpi-auto
 | 
			
		||||
    - make -j4
 | 
			
		||||
    - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then mpirun.openmpi -n 2 ./benchmarks/Benchmark_dwf --threads 1 --mpi 2.1.1.1; fi
 | 
			
		||||
    - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then mpirun -n 2 ./benchmarks/Benchmark_dwf --threads 1 --mpi 2.1.1.1; fi
 | 
			
		||||
    - if [[ "$TRAVIS_OS_NAME" == "linux" ]] && [[ "$CC" == "clang" ]]; then ../configure --enable-precision=single --enable-simd=SSE4 --enable-comms=mpi-auto ; fi
 | 
			
		||||
    - if [[ "$TRAVIS_OS_NAME" == "linux" ]] && [[ "$CC" == "clang" ]]; then make -j4; fi
 | 
			
		||||
    - if [[ "$TRAVIS_OS_NAME" == "linux" ]] && [[ "$CC" == "clang" ]]; then mpirun.openmpi -n 2 ./benchmarks/Benchmark_dwf --threads 1 --mpi 2.1.1.1; fi
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										13
									
								
								Makefile.am
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								Makefile.am
									
									
									
									
									
								
							@@ -1,12 +1,17 @@
 | 
			
		||||
# additional include paths necessary to compile the C++ library
 | 
			
		||||
SUBDIRS = lib benchmarks tests
 | 
			
		||||
SUBDIRS = lib benchmarks tests extras
 | 
			
		||||
 | 
			
		||||
include $(top_srcdir)/doxygen.inc
 | 
			
		||||
 | 
			
		||||
tests: all
 | 
			
		||||
	$(MAKE) -C tests tests
 | 
			
		||||
bin_SCRIPTS=grid-config
 | 
			
		||||
 | 
			
		||||
.PHONY: tests doxygen-run doxygen-doc $(DX_PS_GOAL) $(DX_PDF_GOAL)
 | 
			
		||||
 | 
			
		||||
.PHONY: bench check tests doxygen-run doxygen-doc $(DX_PS_GOAL) $(DX_PDF_GOAL)
 | 
			
		||||
 | 
			
		||||
tests-local: all
 | 
			
		||||
bench-local: all
 | 
			
		||||
check-local: all
 | 
			
		||||
 | 
			
		||||
AM_CXXFLAGS += -I$(top_builddir)/include
 | 
			
		||||
 | 
			
		||||
ACLOCAL_AMFLAGS = -I m4
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										29
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								README.md
									
									
									
									
									
								
							@@ -22,6 +22,26 @@ Last update Nov 2016.
 | 
			
		||||
 | 
			
		||||
_Please do not send pull requests to the `master` branch which is reserved for releases._
 | 
			
		||||
 | 
			
		||||
### Compilers
 | 
			
		||||
 | 
			
		||||
Intel ICPC v16.0.3 and later
 | 
			
		||||
 | 
			
		||||
Clang v3.5 and later (need 3.8 and later for OpenMP)
 | 
			
		||||
 | 
			
		||||
GCC   v4.9.x (recommended)
 | 
			
		||||
 | 
			
		||||
GCC   v6.3 and later
 | 
			
		||||
 | 
			
		||||
### Important: 
 | 
			
		||||
 | 
			
		||||
Some versions of GCC appear to have a bug under high optimisation (-O2, -O3).
 | 
			
		||||
 | 
			
		||||
The safety of these compiler versions cannot be guaranteed at this time. Follow Issue 100 for details and updates.
 | 
			
		||||
 | 
			
		||||
GCC   v5.x
 | 
			
		||||
 | 
			
		||||
GCC   v6.1, v6.2
 | 
			
		||||
 | 
			
		||||
### Bug report
 | 
			
		||||
 | 
			
		||||
_To help us tracking and solving more efficiently issues with Grid, please report problems using the issue system of GitHub rather than sending emails to Grid developers._
 | 
			
		||||
@@ -32,7 +52,7 @@ When you file an issue, please go though the following checklist:
 | 
			
		||||
2. Give a description of the target platform (CPU, network, compiler). Please give the full CPU part description, using for example `cat /proc/cpuinfo | grep 'model name' | uniq` (Linux) or `sysctl machdep.cpu.brand_string` (macOS) and the full output the `--version` option of your compiler.
 | 
			
		||||
3. Give the exact `configure` command used.
 | 
			
		||||
4. Attach `config.log`.
 | 
			
		||||
5. Attach `config.summary`.
 | 
			
		||||
5. Attach `grid.config.summary`.
 | 
			
		||||
6. Attach the output of `make V=1`.
 | 
			
		||||
7. Describe the issue and any previous attempt to solve it. If relevant, show how to reproduce the issue using a minimal working example.
 | 
			
		||||
 | 
			
		||||
@@ -95,10 +115,10 @@ install Grid. Other options are detailed in the next section, you can also use `
 | 
			
		||||
`CXX`, `CXXFLAGS`, `LDFLAGS`, ... environment variables can be modified to
 | 
			
		||||
customise the build.
 | 
			
		||||
 | 
			
		||||
Finally, you can build and install Grid:
 | 
			
		||||
Finally, you can build, check, and install Grid:
 | 
			
		||||
 | 
			
		||||
``` bash
 | 
			
		||||
make; make install
 | 
			
		||||
make; make check; make install
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
To minimise the build time, only the tests at the root of the `tests` directory are built by default. If you want to build tests in the sub-directory `<subdir>` you can execute:
 | 
			
		||||
@@ -121,7 +141,7 @@ If you want to build all the tests at once just use `make tests`.
 | 
			
		||||
- `--enable-gen-simd-width=<size>`: select the size (in bytes) of the generic SIMD vector type (default: 32 bytes).
 | 
			
		||||
- `--enable-precision={single|double}`: set the default precision (default: `double`).
 | 
			
		||||
- `--enable-precision=<comm>`: Use `<comm>` for message passing (default: `none`). A list of possible SIMD targets is detailed in a section below.
 | 
			
		||||
- `--enable-rng={ranlux48|mt19937}`: choose the RNG (default: `ranlux48 `).
 | 
			
		||||
- `--enable-rng={sitmo|ranlux48|mt19937}`: choose the RNG (default: `sitmo `).
 | 
			
		||||
- `--disable-timers`: disable system dependent high-resolution timers.
 | 
			
		||||
- `--enable-chroma`: enable Chroma regression tests.
 | 
			
		||||
- `--enable-doxygen-doc`: enable the Doxygen documentation generation (build with `make doxygen-doc`)
 | 
			
		||||
@@ -159,7 +179,6 @@ Alternatively, some CPU codenames can be directly used:
 | 
			
		||||
 | 
			
		||||
| `<code>`    | Description                            |
 | 
			
		||||
| ----------- | -------------------------------------- |
 | 
			
		||||
| `KNC`       | [Intel Xeon Phi codename Knights Corner](http://ark.intel.com/products/codename/57721/Knights-Corner) |
 | 
			
		||||
| `KNL`       | [Intel Xeon Phi codename Knights Landing](http://ark.intel.com/products/codename/48999/Knights-Landing) |
 | 
			
		||||
| `BGQ`       | Blue Gene/Q                            |
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										68
									
								
								TODO
									
									
									
									
									
								
							
							
						
						
									
										68
									
								
								TODO
									
									
									
									
									
								
							@@ -1,6 +1,33 @@
 | 
			
		||||
TODO:
 | 
			
		||||
---------------
 | 
			
		||||
 | 
			
		||||
Large item work list:
 | 
			
		||||
1)- MultiRHS with spread out extra dim -- Go through filesystem with SciDAC I/O
 | 
			
		||||
 | 
			
		||||
2)- Christoph's local basis expansion Lanczos
 | 
			
		||||
3)- BG/Q port and check
 | 
			
		||||
4)- Precision conversion and sort out localConvert      <-- partial
 | 
			
		||||
  - Consistent linear solver flop count/rate -- PARTIAL, time but no flop/s yet
 | 
			
		||||
5)- Physical propagator interface
 | 
			
		||||
6)- Conserved currents
 | 
			
		||||
7)- Multigrid Wilson and DWF, compare to other Multigrid implementations
 | 
			
		||||
8)- HDCR resume
 | 
			
		||||
 | 
			
		||||
Recent DONE 
 | 
			
		||||
-- Lanczos Remove DenseVector, DenseMatrix; Use Eigen instead. <-- DONE
 | 
			
		||||
-- GaugeFix into central location                      <-- DONE
 | 
			
		||||
-- Scidac and Ildg metadata handling                   <-- DONE
 | 
			
		||||
-- Binary I/O MPI2 IO                                  <-- DONE
 | 
			
		||||
-- Binary I/O speed up & x-strips                      <-- DONE
 | 
			
		||||
-- Cut down the exterior overhead                      <-- DONE
 | 
			
		||||
-- Interior legs from SHM comms                        <-- DONE
 | 
			
		||||
-- Half-precision comms                                <-- DONE
 | 
			
		||||
-- Merge high precision reduction into develop         <-- DONE
 | 
			
		||||
-- BlockCG, BCGrQ                                      <-- DONE
 | 
			
		||||
-- multiRHS DWF; benchmark on Cori/BNL for comms elimination <-- DONE
 | 
			
		||||
   -- slice* linalg routines for multiRHS, BlockCG    
 | 
			
		||||
 | 
			
		||||
-----
 | 
			
		||||
* Forces; the UdSdU  term in gauge force term is half of what I think it should
 | 
			
		||||
  be. This is a consequence of taking ONLY the first term in:
 | 
			
		||||
 | 
			
		||||
@@ -21,16 +48,8 @@ TODO:
 | 
			
		||||
  This means we must double the force in the Test_xxx_force routines, and is the origin of the factor of two.
 | 
			
		||||
  This 2x is applied by hand in the fermion routines and in the Test_rect_force routine.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Policies:
 | 
			
		||||
 | 
			
		||||
* Link smearing/boundary conds; Policy class based implementation ; framework more in place
 | 
			
		||||
 | 
			
		||||
* Support different boundary conditions (finite temp, chem. potential ... )
 | 
			
		||||
 | 
			
		||||
* Support different fermion representations? 
 | 
			
		||||
  - contained entirely within the integrator presently
 | 
			
		||||
 | 
			
		||||
- Sign of force term.
 | 
			
		||||
 | 
			
		||||
- Reversibility test.
 | 
			
		||||
@@ -41,11 +60,6 @@ Policies:
 | 
			
		||||
 | 
			
		||||
- Audit oIndex usage for cb behaviour
 | 
			
		||||
 | 
			
		||||
- Rectangle gauge actions.
 | 
			
		||||
  Iwasaki,
 | 
			
		||||
  Symanzik,
 | 
			
		||||
  ... etc...
 | 
			
		||||
 | 
			
		||||
- Prepare multigrid for HMC. - Alternate setup schemes.
 | 
			
		||||
 | 
			
		||||
- Support for ILDG --- ugly, not done
 | 
			
		||||
@@ -55,9 +69,11 @@ Policies:
 | 
			
		||||
- FFTnD ?
 | 
			
		||||
 | 
			
		||||
- Gparity; hand opt use template specialisation elegance to enable the optimised paths ?
 | 
			
		||||
 | 
			
		||||
- Gparity force term; Gparity (R)HMC.
 | 
			
		||||
- Random number state save restore
 | 
			
		||||
 | 
			
		||||
- Mobius implementation clean up to rmove #if 0 stale code sequences
 | 
			
		||||
 | 
			
		||||
- CG -- profile carefully, kernel fusion, whole CG performance measurements.
 | 
			
		||||
 | 
			
		||||
================================================================
 | 
			
		||||
@@ -90,6 +106,7 @@ Insert/Extract
 | 
			
		||||
Not sure of status of this -- reverify. Things are working nicely now though.
 | 
			
		||||
 | 
			
		||||
* Make the Tensor types and Complex etc... play more nicely.
 | 
			
		||||
 | 
			
		||||
  - TensorRemove is a hack, come up with a long term rationalised approach to Complex vs. Scalar<Scalar<Scalar<Complex > > >
 | 
			
		||||
    QDP forces use of "toDouble" to get back to non tensor scalar. This role is presently taken TensorRemove, but I
 | 
			
		||||
    want to introduce a syntax that does not require this.
 | 
			
		||||
@@ -112,6 +129,8 @@ Not sure of status of this -- reverify. Things are working nicely now though.
 | 
			
		||||
RECENT
 | 
			
		||||
---------------
 | 
			
		||||
 | 
			
		||||
  - Support different fermion representations? -- DONE
 | 
			
		||||
  - contained entirely within the integrator presently
 | 
			
		||||
  - Clean up HMC                                                             -- DONE
 | 
			
		||||
  - LorentzScalar<GaugeField> gets Gauge link type (cleaner).                -- DONE
 | 
			
		||||
  - Simplified the integrators a bit.                                        -- DONE
 | 
			
		||||
@@ -123,6 +142,26 @@ RECENT
 | 
			
		||||
  - Parallel io improvements                                  -- DONE
 | 
			
		||||
  - Plaquette and link trace checks into nersc reader from the Grid_nersc_io.cc test. -- DONE
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
DONE:
 | 
			
		||||
- MultiArray -- MultiRHS done
 | 
			
		||||
- ConjugateGradientMultiShift -- DONE
 | 
			
		||||
- MCR                         -- DONE
 | 
			
		||||
- Remez -- Mike or Boost?     -- DONE
 | 
			
		||||
- Proto (ET)                  -- DONE
 | 
			
		||||
- uBlas                       -- DONE ; Eigen
 | 
			
		||||
- Potentially Useful Boost libraries -- DONE ; Eigen
 | 
			
		||||
- Aligned allocator; memory pool -- DONE
 | 
			
		||||
- Multiprecision              -- DONE
 | 
			
		||||
- Serialization               -- DONE
 | 
			
		||||
- Regex -- Not needed
 | 
			
		||||
- Tokenize -- Why?
 | 
			
		||||
 | 
			
		||||
- Random number state save restore -- DONE
 | 
			
		||||
- Rectangle gauge actions. -- DONE
 | 
			
		||||
  Iwasaki,
 | 
			
		||||
  Symanzik,
 | 
			
		||||
  ... etc...
 | 
			
		||||
Done: Cayley, Partial , ContFrac force terms.
 | 
			
		||||
 | 
			
		||||
DONE
 | 
			
		||||
@@ -207,6 +246,7 @@ Done
 | 
			
		||||
FUNCTIONALITY: it pleases me to keep track of things I have done (keeps me arguably sane)
 | 
			
		||||
======================================================================================================
 | 
			
		||||
 | 
			
		||||
* Link smearing/boundary conds; Policy class based implementation ; framework more in place -- DONE
 | 
			
		||||
* Command line args for geometry, simd, etc. layout. Is it necessary to have -- DONE
 | 
			
		||||
  user pass these? Is this a QCD specific?
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										9
									
								
								VERSION
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								VERSION
									
									
									
									
									
								
							@@ -1,6 +1,5 @@
 | 
			
		||||
Version : 0.6.0
 | 
			
		||||
Version : 0.7.0
 | 
			
		||||
 | 
			
		||||
- AVX512, AVX2, AVX, SSE good
 | 
			
		||||
- Clang 3.5 and above, ICPC v16 and above, GCC 4.9 and above
 | 
			
		||||
- MPI and MPI3
 | 
			
		||||
- HiRep, Smearing, Generic gauge group
 | 
			
		||||
- Clang 3.5 and above, ICPC v16 and above, GCC 6.3 and above recommended
 | 
			
		||||
- MPI and MPI3 comms optimisations for KNL and OPA finished
 | 
			
		||||
- Half precision comms
 | 
			
		||||
 
 | 
			
		||||
@@ -31,6 +31,32 @@ using namespace std;
 | 
			
		||||
using namespace Grid;
 | 
			
		||||
using namespace Grid::QCD;
 | 
			
		||||
 | 
			
		||||
struct time_statistics{
 | 
			
		||||
  double mean;
 | 
			
		||||
  double err;
 | 
			
		||||
  double min;
 | 
			
		||||
  double max;
 | 
			
		||||
 | 
			
		||||
  void statistics(std::vector<double> v){
 | 
			
		||||
      double sum = std::accumulate(v.begin(), v.end(), 0.0);
 | 
			
		||||
      mean = sum / v.size();
 | 
			
		||||
 | 
			
		||||
      std::vector<double> diff(v.size());
 | 
			
		||||
      std::transform(v.begin(), v.end(), diff.begin(), [=](double x) { return x - mean; });
 | 
			
		||||
      double sq_sum = std::inner_product(diff.begin(), diff.end(), diff.begin(), 0.0);
 | 
			
		||||
      err = std::sqrt(sq_sum / (v.size()*(v.size() - 1)));
 | 
			
		||||
 | 
			
		||||
      auto result = std::minmax_element(v.begin(), v.end());
 | 
			
		||||
      min = *result.first;
 | 
			
		||||
      max = *result.second;
 | 
			
		||||
}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void header(){
 | 
			
		||||
  std::cout <<GridLogMessage << " L  "<<"\t"<<" Ls  "<<"\t"
 | 
			
		||||
            <<std::setw(11)<<"bytes"<<"MB/s uni (err/min/max)"<<"\t\t"<<"MB/s bidi (err/min/max)"<<std::endl;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int main (int argc, char ** argv)
 | 
			
		||||
{
 | 
			
		||||
  Grid_init(&argc,&argv);
 | 
			
		||||
@@ -40,17 +66,21 @@ int main (int argc, char ** argv)
 | 
			
		||||
  int threads = GridThread::GetThreads();
 | 
			
		||||
  std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl;
 | 
			
		||||
 | 
			
		||||
  int Nloop=10;
 | 
			
		||||
  int Nloop=100;
 | 
			
		||||
  int nmu=0;
 | 
			
		||||
  int maxlat=24;
 | 
			
		||||
  for(int mu=0;mu<Nd;mu++) if (mpi_layout[mu]>1) nmu++;
 | 
			
		||||
 | 
			
		||||
  std::cout << GridLogMessage << "Number of iterations to average: "<< Nloop << std::endl;
 | 
			
		||||
  std::vector<double> t_time(Nloop);
 | 
			
		||||
  time_statistics timestat;
 | 
			
		||||
 | 
			
		||||
  std::cout<<GridLogMessage << "===================================================================================================="<<std::endl;
 | 
			
		||||
  std::cout<<GridLogMessage << "= Benchmarking concurrent halo exchange in "<<nmu<<" dimensions"<<std::endl;
 | 
			
		||||
  std::cout<<GridLogMessage << "===================================================================================================="<<std::endl;
 | 
			
		||||
  std::cout<<GridLogMessage << "  L  "<<"\t\t"<<" Ls  "<<"\t\t"<<"bytes"<<"\t\t"<<"MB/s uni"<<"\t\t"<<"MB/s bidi"<<std::endl;
 | 
			
		||||
  int maxlat=16;
 | 
			
		||||
  for(int lat=4;lat<=maxlat;lat+=2){
 | 
			
		||||
    for(int Ls=1;Ls<=16;Ls*=2){
 | 
			
		||||
  header();
 | 
			
		||||
  for(int lat=4;lat<=maxlat;lat+=4){
 | 
			
		||||
    for(int Ls=8;Ls<=32;Ls*=2){
 | 
			
		||||
 | 
			
		||||
      std::vector<int> latt_size  ({lat*mpi_layout[0],
 | 
			
		||||
      				    lat*mpi_layout[1],
 | 
			
		||||
@@ -58,6 +88,9 @@ int main (int argc, char ** argv)
 | 
			
		||||
      				    lat*mpi_layout[3]});
 | 
			
		||||
 | 
			
		||||
      GridCartesian     Grid(latt_size,simd_layout,mpi_layout);
 | 
			
		||||
      RealD Nrank = Grid._Nprocessors;
 | 
			
		||||
      RealD Nnode = Grid.NodeCount();
 | 
			
		||||
      RealD ppn = Nrank/Nnode;
 | 
			
		||||
 | 
			
		||||
      std::vector<std::vector<HalfSpinColourVectorD> > xbuf(8,std::vector<HalfSpinColourVectorD>(lat*lat*lat*Ls));
 | 
			
		||||
      std::vector<std::vector<HalfSpinColourVectorD> > rbuf(8,std::vector<HalfSpinColourVectorD>(lat*lat*lat*Ls));
 | 
			
		||||
@@ -65,8 +98,8 @@ int main (int argc, char ** argv)
 | 
			
		||||
      int ncomm;
 | 
			
		||||
      int bytes=lat*lat*lat*Ls*sizeof(HalfSpinColourVectorD);
 | 
			
		||||
 | 
			
		||||
      double start=usecond();
 | 
			
		||||
      for(int i=0;i<Nloop;i++){
 | 
			
		||||
      double start=usecond();
 | 
			
		||||
 | 
			
		||||
	std::vector<CartesianCommunicator::CommsRequest_t> requests;
 | 
			
		||||
 | 
			
		||||
@@ -102,18 +135,24 @@ int main (int argc, char ** argv)
 | 
			
		||||
	}
 | 
			
		||||
	Grid.SendToRecvFromComplete(requests);
 | 
			
		||||
	Grid.Barrier();
 | 
			
		||||
 | 
			
		||||
	double stop=usecond();
 | 
			
		||||
	t_time[i] = stop-start; // microseconds
 | 
			
		||||
      }
 | 
			
		||||
      double stop=usecond();
 | 
			
		||||
 | 
			
		||||
      double dbytes    = bytes;
 | 
			
		||||
      double xbytes    = Nloop*dbytes*2.0*ncomm;
 | 
			
		||||
      timestat.statistics(t_time);
 | 
			
		||||
 | 
			
		||||
      double dbytes    = bytes*ppn;
 | 
			
		||||
      double xbytes    = dbytes*2.0*ncomm;
 | 
			
		||||
      double rbytes    = xbytes;
 | 
			
		||||
      double bidibytes = xbytes+rbytes;
 | 
			
		||||
 | 
			
		||||
      double time = stop-start; // microseconds
 | 
			
		||||
      std::cout<<GridLogMessage << std::setw(4) << lat<<"\t"<<Ls<<"\t"
 | 
			
		||||
               <<std::setw(11) << bytes<< std::fixed << std::setprecision(1) << std::setw(7)
 | 
			
		||||
               <<std::right<< xbytes/timestat.mean<<"  "<< xbytes*timestat.err/(timestat.mean*timestat.mean)<< " "
 | 
			
		||||
               <<xbytes/timestat.max <<" "<< xbytes/timestat.min  
 | 
			
		||||
               << "\t\t"<<std::setw(7)<< bidibytes/timestat.mean<< "  " << bidibytes*timestat.err/(timestat.mean*timestat.mean) << " "
 | 
			
		||||
               << bidibytes/timestat.max << " " << bidibytes/timestat.min << std::endl;
 | 
			
		||||
 | 
			
		||||
      std::cout<<GridLogMessage << lat<<"\t\t"<<Ls<<"\t\t"<<bytes<<"\t\t"<<xbytes/time<<"\t\t"<<bidibytes/time<<std::endl;
 | 
			
		||||
    }
 | 
			
		||||
  }    
 | 
			
		||||
 | 
			
		||||
@@ -121,15 +160,17 @@ int main (int argc, char ** argv)
 | 
			
		||||
  std::cout<<GridLogMessage << "===================================================================================================="<<std::endl;
 | 
			
		||||
  std::cout<<GridLogMessage << "= Benchmarking sequential halo exchange in "<<nmu<<" dimensions"<<std::endl;
 | 
			
		||||
  std::cout<<GridLogMessage << "===================================================================================================="<<std::endl;
 | 
			
		||||
  std::cout<<GridLogMessage << "  L  "<<"\t\t"<<" Ls  "<<"\t\t"<<"bytes"<<"\t\t"<<"MB/s uni"<<"\t\t"<<"MB/s bidi"<<std::endl;
 | 
			
		||||
  header();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  for(int lat=4;lat<=maxlat;lat+=2){
 | 
			
		||||
    for(int Ls=1;Ls<=16;Ls*=2){
 | 
			
		||||
  for(int lat=4;lat<=maxlat;lat+=4){
 | 
			
		||||
    for(int Ls=8;Ls<=32;Ls*=2){
 | 
			
		||||
 | 
			
		||||
      std::vector<int> latt_size  ({lat,lat,lat,lat});
 | 
			
		||||
 | 
			
		||||
      GridCartesian     Grid(latt_size,simd_layout,mpi_layout);
 | 
			
		||||
      RealD Nrank = Grid._Nprocessors;
 | 
			
		||||
      RealD Nnode = Grid.NodeCount();
 | 
			
		||||
      RealD ppn = Nrank/Nnode;
 | 
			
		||||
 | 
			
		||||
      std::vector<std::vector<HalfSpinColourVectorD> > xbuf(8,std::vector<HalfSpinColourVectorD>(lat*lat*lat*Ls));
 | 
			
		||||
      std::vector<std::vector<HalfSpinColourVectorD> > rbuf(8,std::vector<HalfSpinColourVectorD>(lat*lat*lat*Ls));
 | 
			
		||||
@@ -138,8 +179,8 @@ int main (int argc, char ** argv)
 | 
			
		||||
      int ncomm;
 | 
			
		||||
      int bytes=lat*lat*lat*Ls*sizeof(HalfSpinColourVectorD);
 | 
			
		||||
 | 
			
		||||
      double start=usecond();
 | 
			
		||||
      for(int i=0;i<Nloop;i++){
 | 
			
		||||
      double start=usecond();
 | 
			
		||||
    
 | 
			
		||||
	ncomm=0;
 | 
			
		||||
	for(int mu=0;mu<4;mu++){
 | 
			
		||||
@@ -178,30 +219,37 @@ int main (int argc, char ** argv)
 | 
			
		||||
	  }
 | 
			
		||||
	}
 | 
			
		||||
	Grid.Barrier();
 | 
			
		||||
	double stop=usecond();
 | 
			
		||||
	t_time[i] = stop-start; // microseconds
 | 
			
		||||
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      double stop=usecond();
 | 
			
		||||
      timestat.statistics(t_time);
 | 
			
		||||
      
 | 
			
		||||
      double dbytes    = bytes;
 | 
			
		||||
      double xbytes    = Nloop*dbytes*2.0*ncomm;
 | 
			
		||||
      double dbytes    = bytes*ppn;
 | 
			
		||||
      double xbytes    = dbytes*2.0*ncomm;
 | 
			
		||||
      double rbytes    = xbytes;
 | 
			
		||||
      double bidibytes = xbytes+rbytes;
 | 
			
		||||
 | 
			
		||||
      double time = stop-start;
 | 
			
		||||
    std::cout<<GridLogMessage << std::setw(4) << lat<<"\t"<<Ls<<"\t"
 | 
			
		||||
               <<std::setw(11) << bytes<< std::fixed << std::setprecision(1) << std::setw(7)
 | 
			
		||||
               <<std::right<< xbytes/timestat.mean<<"  "<< xbytes*timestat.err/(timestat.mean*timestat.mean)<< " "
 | 
			
		||||
               <<xbytes/timestat.max <<" "<< xbytes/timestat.min  
 | 
			
		||||
               << "\t\t"<<std::setw(7)<< bidibytes/timestat.mean<< "  " << bidibytes*timestat.err/(timestat.mean*timestat.mean) << " "
 | 
			
		||||
               << bidibytes/timestat.max << " " << bidibytes/timestat.min << std::endl;
 | 
			
		||||
 | 
			
		||||
      std::cout<<GridLogMessage << lat<<"\t\t"<<Ls<<"\t\t"<<bytes<<"\t\t"<<xbytes/time<<"\t\t"<<bidibytes/time<<std::endl;
 | 
			
		||||
      
 | 
			
		||||
    }
 | 
			
		||||
  }  
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  Nloop=100;
 | 
			
		||||
  std::cout<<GridLogMessage << "===================================================================================================="<<std::endl;
 | 
			
		||||
  std::cout<<GridLogMessage << "= Benchmarking concurrent STENCIL halo exchange in "<<nmu<<" dimensions"<<std::endl;
 | 
			
		||||
  std::cout<<GridLogMessage << "===================================================================================================="<<std::endl;
 | 
			
		||||
  std::cout<<GridLogMessage << "  L  "<<"\t\t"<<" Ls  "<<"\t\t"<<"bytes"<<"\t\t"<<"MB/s uni"<<"\t\t"<<"MB/s bidi"<<std::endl;
 | 
			
		||||
  header();
 | 
			
		||||
 | 
			
		||||
  for(int lat=4;lat<=maxlat;lat+=2){
 | 
			
		||||
    for(int Ls=1;Ls<=16;Ls*=2){
 | 
			
		||||
  for(int lat=4;lat<=maxlat;lat+=4){
 | 
			
		||||
    for(int Ls=8;Ls<=32;Ls*=2){
 | 
			
		||||
 | 
			
		||||
      std::vector<int> latt_size  ({lat*mpi_layout[0],
 | 
			
		||||
      				    lat*mpi_layout[1],
 | 
			
		||||
@@ -209,6 +257,9 @@ int main (int argc, char ** argv)
 | 
			
		||||
      				    lat*mpi_layout[3]});
 | 
			
		||||
 | 
			
		||||
      GridCartesian     Grid(latt_size,simd_layout,mpi_layout);
 | 
			
		||||
      RealD Nrank = Grid._Nprocessors;
 | 
			
		||||
      RealD Nnode = Grid.NodeCount();
 | 
			
		||||
      RealD ppn = Nrank/Nnode;
 | 
			
		||||
 | 
			
		||||
      std::vector<HalfSpinColourVectorD *> xbuf(8);
 | 
			
		||||
      std::vector<HalfSpinColourVectorD *> rbuf(8);
 | 
			
		||||
@@ -216,73 +267,86 @@ int main (int argc, char ** argv)
 | 
			
		||||
      for(int d=0;d<8;d++){
 | 
			
		||||
	xbuf[d] = (HalfSpinColourVectorD *)Grid.ShmBufferMalloc(lat*lat*lat*Ls*sizeof(HalfSpinColourVectorD));
 | 
			
		||||
	rbuf[d] = (HalfSpinColourVectorD *)Grid.ShmBufferMalloc(lat*lat*lat*Ls*sizeof(HalfSpinColourVectorD));
 | 
			
		||||
	bzero((void *)xbuf[d],lat*lat*lat*Ls*sizeof(HalfSpinColourVectorD));
 | 
			
		||||
	bzero((void *)rbuf[d],lat*lat*lat*Ls*sizeof(HalfSpinColourVectorD));
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      int ncomm;
 | 
			
		||||
      int bytes=lat*lat*lat*Ls*sizeof(HalfSpinColourVectorD);
 | 
			
		||||
 | 
			
		||||
      double start=usecond();
 | 
			
		||||
      double dbytes;
 | 
			
		||||
      for(int i=0;i<Nloop;i++){
 | 
			
		||||
	double start=usecond();
 | 
			
		||||
 | 
			
		||||
	dbytes=0;
 | 
			
		||||
	ncomm=0;
 | 
			
		||||
 | 
			
		||||
	std::vector<CartesianCommunicator::CommsRequest_t> requests;
 | 
			
		||||
 | 
			
		||||
	ncomm=0;
 | 
			
		||||
	for(int mu=0;mu<4;mu++){
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	  if (mpi_layout[mu]>1 ) {
 | 
			
		||||
	  
 | 
			
		||||
	    ncomm++;
 | 
			
		||||
	    int comm_proc=1;
 | 
			
		||||
	    int xmit_to_rank;
 | 
			
		||||
	    int recv_from_rank;
 | 
			
		||||
	    
 | 
			
		||||
	    Grid.ShiftedRanks(mu,comm_proc,xmit_to_rank,recv_from_rank);
 | 
			
		||||
	    Grid.StencilSendToRecvFromBegin(requests,
 | 
			
		||||
					    (void *)&xbuf[mu][0],
 | 
			
		||||
					    xmit_to_rank,
 | 
			
		||||
					    (void *)&rbuf[mu][0],
 | 
			
		||||
					    recv_from_rank,
 | 
			
		||||
					    bytes);
 | 
			
		||||
	    dbytes+=
 | 
			
		||||
	      Grid.StencilSendToRecvFromBegin(requests,
 | 
			
		||||
					      (void *)&xbuf[mu][0],
 | 
			
		||||
					      xmit_to_rank,
 | 
			
		||||
					      (void *)&rbuf[mu][0],
 | 
			
		||||
					      recv_from_rank,
 | 
			
		||||
					      bytes);
 | 
			
		||||
	
 | 
			
		||||
	    comm_proc = mpi_layout[mu]-1;
 | 
			
		||||
	  
 | 
			
		||||
	    Grid.ShiftedRanks(mu,comm_proc,xmit_to_rank,recv_from_rank);
 | 
			
		||||
	    Grid.StencilSendToRecvFromBegin(requests,
 | 
			
		||||
					    (void *)&xbuf[mu+4][0],
 | 
			
		||||
					    xmit_to_rank,
 | 
			
		||||
					    (void *)&rbuf[mu+4][0],
 | 
			
		||||
					    recv_from_rank,
 | 
			
		||||
					    bytes);
 | 
			
		||||
	    dbytes+=
 | 
			
		||||
	      Grid.StencilSendToRecvFromBegin(requests,
 | 
			
		||||
					      (void *)&xbuf[mu+4][0],
 | 
			
		||||
					      xmit_to_rank,
 | 
			
		||||
					      (void *)&rbuf[mu+4][0],
 | 
			
		||||
					      recv_from_rank,
 | 
			
		||||
					      bytes);
 | 
			
		||||
	  
 | 
			
		||||
	  }
 | 
			
		||||
	}
 | 
			
		||||
	Grid.StencilSendToRecvFromComplete(requests);
 | 
			
		||||
	Grid.Barrier();
 | 
			
		||||
 | 
			
		||||
	double stop=usecond();
 | 
			
		||||
	t_time[i] = stop-start; // microseconds
 | 
			
		||||
	
 | 
			
		||||
      }
 | 
			
		||||
      double stop=usecond();
 | 
			
		||||
 | 
			
		||||
      double dbytes    = bytes;
 | 
			
		||||
      double xbytes    = Nloop*dbytes*2.0*ncomm;
 | 
			
		||||
      double rbytes    = xbytes;
 | 
			
		||||
      double bidibytes = xbytes+rbytes;
 | 
			
		||||
      timestat.statistics(t_time);
 | 
			
		||||
 | 
			
		||||
      dbytes=dbytes*ppn;
 | 
			
		||||
      double xbytes    = dbytes*0.5;
 | 
			
		||||
      double rbytes    = dbytes*0.5;
 | 
			
		||||
      double bidibytes = dbytes;
 | 
			
		||||
 | 
			
		||||
      std::cout<<GridLogMessage << std::setw(4) << lat<<"\t"<<Ls<<"\t"
 | 
			
		||||
               <<std::setw(11) << bytes<< std::fixed << std::setprecision(1) << std::setw(7)
 | 
			
		||||
               <<std::right<< xbytes/timestat.mean<<"  "<< xbytes*timestat.err/(timestat.mean*timestat.mean)<< " "
 | 
			
		||||
               <<xbytes/timestat.max <<" "<< xbytes/timestat.min  
 | 
			
		||||
               << "\t\t"<<std::setw(7)<< bidibytes/timestat.mean<< "  " << bidibytes*timestat.err/(timestat.mean*timestat.mean) << " "
 | 
			
		||||
               << bidibytes/timestat.max << " " << bidibytes/timestat.min << std::endl;
 | 
			
		||||
 | 
			
		||||
      double time = stop-start; // microseconds
 | 
			
		||||
 | 
			
		||||
      std::cout<<GridLogMessage << lat<<"\t\t"<<Ls<<"\t\t"<<bytes<<"\t\t"<<xbytes/time<<"\t\t"<<bidibytes/time<<std::endl;
 | 
			
		||||
    }
 | 
			
		||||
  }    
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  Nloop=100;
 | 
			
		||||
  std::cout<<GridLogMessage << "===================================================================================================="<<std::endl;
 | 
			
		||||
  std::cout<<GridLogMessage << "= Benchmarking sequential STENCIL halo exchange in "<<nmu<<" dimensions"<<std::endl;
 | 
			
		||||
  std::cout<<GridLogMessage << "===================================================================================================="<<std::endl;
 | 
			
		||||
  std::cout<<GridLogMessage << "  L  "<<"\t\t"<<" Ls  "<<"\t\t"<<"bytes"<<"\t\t"<<"MB/s uni"<<"\t\t"<<"MB/s bidi"<<std::endl;
 | 
			
		||||
  header();
 | 
			
		||||
 | 
			
		||||
  for(int lat=4;lat<=maxlat;lat+=2){
 | 
			
		||||
    for(int Ls=1;Ls<=16;Ls*=2){
 | 
			
		||||
  for(int lat=4;lat<=maxlat;lat+=4){
 | 
			
		||||
    for(int Ls=8;Ls<=32;Ls*=2){
 | 
			
		||||
 | 
			
		||||
      std::vector<int> latt_size  ({lat*mpi_layout[0],
 | 
			
		||||
      				    lat*mpi_layout[1],
 | 
			
		||||
@@ -290,6 +354,9 @@ int main (int argc, char ** argv)
 | 
			
		||||
      				    lat*mpi_layout[3]});
 | 
			
		||||
 | 
			
		||||
      GridCartesian     Grid(latt_size,simd_layout,mpi_layout);
 | 
			
		||||
      RealD Nrank = Grid._Nprocessors;
 | 
			
		||||
      RealD Nnode = Grid.NodeCount();
 | 
			
		||||
      RealD ppn = Nrank/Nnode;
 | 
			
		||||
 | 
			
		||||
      std::vector<HalfSpinColourVectorD *> xbuf(8);
 | 
			
		||||
      std::vector<HalfSpinColourVectorD *> rbuf(8);
 | 
			
		||||
@@ -297,16 +364,18 @@ int main (int argc, char ** argv)
 | 
			
		||||
      for(int d=0;d<8;d++){
 | 
			
		||||
	xbuf[d] = (HalfSpinColourVectorD *)Grid.ShmBufferMalloc(lat*lat*lat*Ls*sizeof(HalfSpinColourVectorD));
 | 
			
		||||
	rbuf[d] = (HalfSpinColourVectorD *)Grid.ShmBufferMalloc(lat*lat*lat*Ls*sizeof(HalfSpinColourVectorD));
 | 
			
		||||
	bzero((void *)xbuf[d],lat*lat*lat*Ls*sizeof(HalfSpinColourVectorD));
 | 
			
		||||
	bzero((void *)rbuf[d],lat*lat*lat*Ls*sizeof(HalfSpinColourVectorD));
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      int ncomm;
 | 
			
		||||
      int bytes=lat*lat*lat*Ls*sizeof(HalfSpinColourVectorD);
 | 
			
		||||
 | 
			
		||||
      double start=usecond();
 | 
			
		||||
      double dbytes;
 | 
			
		||||
      for(int i=0;i<Nloop;i++){
 | 
			
		||||
	double start=usecond();
 | 
			
		||||
 | 
			
		||||
	std::vector<CartesianCommunicator::CommsRequest_t> requests;
 | 
			
		||||
 | 
			
		||||
	dbytes=0;
 | 
			
		||||
	ncomm=0;
 | 
			
		||||
	for(int mu=0;mu<4;mu++){
 | 
			
		||||
	
 | 
			
		||||
@@ -318,42 +387,52 @@ int main (int argc, char ** argv)
 | 
			
		||||
	    int recv_from_rank;
 | 
			
		||||
	    
 | 
			
		||||
	    Grid.ShiftedRanks(mu,comm_proc,xmit_to_rank,recv_from_rank);
 | 
			
		||||
	    Grid.StencilSendToRecvFromBegin(requests,
 | 
			
		||||
					    (void *)&xbuf[mu][0],
 | 
			
		||||
					    xmit_to_rank,
 | 
			
		||||
					    (void *)&rbuf[mu][0],
 | 
			
		||||
					    recv_from_rank,
 | 
			
		||||
					    bytes);
 | 
			
		||||
	    //	    Grid.StencilSendToRecvFromComplete(requests);
 | 
			
		||||
	    //	    requests.resize(0);
 | 
			
		||||
	    dbytes+=
 | 
			
		||||
	      Grid.StencilSendToRecvFromBegin(requests,
 | 
			
		||||
					      (void *)&xbuf[mu][0],
 | 
			
		||||
					      xmit_to_rank,
 | 
			
		||||
					      (void *)&rbuf[mu][0],
 | 
			
		||||
					      recv_from_rank,
 | 
			
		||||
					      bytes);
 | 
			
		||||
	    Grid.StencilSendToRecvFromComplete(requests);
 | 
			
		||||
	    requests.resize(0);
 | 
			
		||||
 | 
			
		||||
	    comm_proc = mpi_layout[mu]-1;
 | 
			
		||||
	  
 | 
			
		||||
	    Grid.ShiftedRanks(mu,comm_proc,xmit_to_rank,recv_from_rank);
 | 
			
		||||
	    Grid.StencilSendToRecvFromBegin(requests,
 | 
			
		||||
					    (void *)&xbuf[mu+4][0],
 | 
			
		||||
					    xmit_to_rank,
 | 
			
		||||
					    (void *)&rbuf[mu+4][0],
 | 
			
		||||
					    recv_from_rank,
 | 
			
		||||
					    bytes);
 | 
			
		||||
	    dbytes+=
 | 
			
		||||
	      Grid.StencilSendToRecvFromBegin(requests,
 | 
			
		||||
					      (void *)&xbuf[mu+4][0],
 | 
			
		||||
					      xmit_to_rank,
 | 
			
		||||
					      (void *)&rbuf[mu+4][0],
 | 
			
		||||
					      recv_from_rank,
 | 
			
		||||
					      bytes);
 | 
			
		||||
	    Grid.StencilSendToRecvFromComplete(requests);
 | 
			
		||||
	    requests.resize(0);
 | 
			
		||||
	  
 | 
			
		||||
	  }
 | 
			
		||||
	}
 | 
			
		||||
	Grid.Barrier();
 | 
			
		||||
 | 
			
		||||
	double stop=usecond();
 | 
			
		||||
	t_time[i] = stop-start; // microseconds
 | 
			
		||||
	
 | 
			
		||||
      }
 | 
			
		||||
      double stop=usecond();
 | 
			
		||||
 | 
			
		||||
      double dbytes    = bytes;
 | 
			
		||||
      double xbytes    = Nloop*dbytes*2.0*ncomm;
 | 
			
		||||
      double rbytes    = xbytes;
 | 
			
		||||
      double bidibytes = xbytes+rbytes;
 | 
			
		||||
      timestat.statistics(t_time);
 | 
			
		||||
 | 
			
		||||
      double time = stop-start; // microseconds
 | 
			
		||||
      dbytes=dbytes*ppn;
 | 
			
		||||
      double xbytes    = dbytes*0.5;
 | 
			
		||||
      double rbytes    = dbytes*0.5;
 | 
			
		||||
      double bidibytes = dbytes;
 | 
			
		||||
 | 
			
		||||
      std::cout<<GridLogMessage << lat<<"\t\t"<<Ls<<"\t\t"<<bytes<<"\t\t"<<xbytes/time<<"\t\t"<<bidibytes/time<<std::endl;
 | 
			
		||||
 | 
			
		||||
      std::cout<<GridLogMessage << std::setw(4) << lat<<"\t"<<Ls<<"\t"
 | 
			
		||||
               <<std::setw(11) << bytes<< std::fixed << std::setprecision(1) << std::setw(7)
 | 
			
		||||
               <<std::right<< xbytes/timestat.mean<<"  "<< xbytes*timestat.err/(timestat.mean*timestat.mean)<< " "
 | 
			
		||||
               <<xbytes/timestat.max <<" "<< xbytes/timestat.min  
 | 
			
		||||
               << "\t\t"<<std::setw(7)<< bidibytes/timestat.mean<< "  " << bidibytes*timestat.err/(timestat.mean*timestat.mean) << " "
 | 
			
		||||
               << bidibytes/timestat.max << " " << bidibytes/timestat.min << std::endl;
 | 
			
		||||
 
 | 
			
		||||
    }
 | 
			
		||||
  }    
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,28 +1,22 @@
 | 
			
		||||
    /*************************************************************************************
 | 
			
		||||
 | 
			
		||||
 /*************************************************************************************
 | 
			
		||||
    Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
    Source file: ./benchmarks/Benchmark_dwf.cc
 | 
			
		||||
 | 
			
		||||
    Copyright (C) 2015
 | 
			
		||||
 | 
			
		||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
    Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
    Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
 | 
			
		||||
    This program is free software; you can redistribute it and/or modify
 | 
			
		||||
    it under the terms of the GNU General Public License as published by
 | 
			
		||||
    the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
    (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
    This program is distributed in the hope that it will be useful,
 | 
			
		||||
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
    GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
    You should have received a copy of the GNU General Public License along
 | 
			
		||||
    with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
    See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
    *************************************************************************************/
 | 
			
		||||
    /*  END LEGAL */
 | 
			
		||||
@@ -37,27 +31,27 @@ struct scal {
 | 
			
		||||
  d internal;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
  Gamma::GammaMatrix Gmu [] = {
 | 
			
		||||
    Gamma::GammaX,
 | 
			
		||||
    Gamma::GammaY,
 | 
			
		||||
    Gamma::GammaZ,
 | 
			
		||||
    Gamma::GammaT
 | 
			
		||||
  Gamma::Algebra Gmu [] = {
 | 
			
		||||
    Gamma::Algebra::GammaX,
 | 
			
		||||
    Gamma::Algebra::GammaY,
 | 
			
		||||
    Gamma::Algebra::GammaZ,
 | 
			
		||||
    Gamma::Algebra::GammaT
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
typedef WilsonFermion5D<DomainWallVec5dImplR> WilsonFermion5DR;
 | 
			
		||||
typedef WilsonFermion5D<DomainWallVec5dImplF> WilsonFermion5DF;
 | 
			
		||||
typedef WilsonFermion5D<DomainWallVec5dImplD> WilsonFermion5DD;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int main (int argc, char ** argv)
 | 
			
		||||
{
 | 
			
		||||
  Grid_init(&argc,&argv);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  int threads = GridThread::GetThreads();
 | 
			
		||||
  std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl;
 | 
			
		||||
 | 
			
		||||
  std::vector<int> latt4 = GridDefaultLatt();
 | 
			
		||||
  const int Ls=8;
 | 
			
		||||
  const int Ls=16;
 | 
			
		||||
  GridCartesian         * UGrid   = SpaceTimeGrid::makeFourDimGrid(GridDefaultLatt(), GridDefaultSimd(Nd,vComplex::Nsimd()),GridDefaultMpi());
 | 
			
		||||
  GridRedBlackCartesian * UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid);
 | 
			
		||||
  GridCartesian         * FGrid   = SpaceTimeGrid::makeFiveDimGrid(Ls,UGrid);
 | 
			
		||||
@@ -71,35 +65,66 @@ int main (int argc, char ** argv)
 | 
			
		||||
 | 
			
		||||
  std::vector<int> seeds4({1,2,3,4});
 | 
			
		||||
  std::vector<int> seeds5({5,6,7,8});
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
  std::cout << GridLogMessage << "Initialising 4d RNG" << std::endl;
 | 
			
		||||
  GridParallelRNG          RNG4(UGrid);  RNG4.SeedFixedIntegers(seeds4);
 | 
			
		||||
  std::cout << GridLogMessage << "Initialising 5d RNG" << std::endl;
 | 
			
		||||
  GridParallelRNG          RNG5(FGrid);  RNG5.SeedFixedIntegers(seeds5);
 | 
			
		||||
  std::cout << GridLogMessage << "Initialised RNGs" << std::endl;
 | 
			
		||||
 | 
			
		||||
  LatticeFermion src   (FGrid); random(RNG5,src);
 | 
			
		||||
#if 0
 | 
			
		||||
  src = zero;
 | 
			
		||||
  {
 | 
			
		||||
    std::vector<int> origin({0,0,0,latt4[2]-1,0});
 | 
			
		||||
    SpinColourVectorF tmp;
 | 
			
		||||
    tmp=zero;
 | 
			
		||||
    tmp()(0)(0)=Complex(-2.0,0.0);
 | 
			
		||||
    std::cout << " source site 0 " << tmp<<std::endl;
 | 
			
		||||
    pokeSite(tmp,src,origin);
 | 
			
		||||
  }
 | 
			
		||||
#else
 | 
			
		||||
  RealD N2 = 1.0/::sqrt(norm2(src));
 | 
			
		||||
  src = src*N2;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  LatticeFermion result(FGrid); result=zero;
 | 
			
		||||
  LatticeFermion    ref(FGrid);    ref=zero;
 | 
			
		||||
  LatticeFermion    tmp(FGrid);
 | 
			
		||||
  LatticeFermion    err(FGrid);
 | 
			
		||||
 | 
			
		||||
  std::cout << GridLogMessage << "Drawing gauge field" << std::endl;
 | 
			
		||||
  LatticeGaugeField Umu(UGrid); 
 | 
			
		||||
  random(RNG4,Umu);
 | 
			
		||||
 | 
			
		||||
  LatticeGaugeField Umu5d(FGrid); 
 | 
			
		||||
  SU3::HotConfiguration(RNG4,Umu); 
 | 
			
		||||
  std::cout << GridLogMessage << "Random gauge initialised " << std::endl;
 | 
			
		||||
#if 0
 | 
			
		||||
  Umu=1.0;
 | 
			
		||||
  for(int mu=0;mu<Nd;mu++){
 | 
			
		||||
    LatticeColourMatrix ttmp(UGrid);
 | 
			
		||||
    ttmp = PeekIndex<LorentzIndex>(Umu,mu);
 | 
			
		||||
    //    if (mu !=2 ) ttmp = 0;
 | 
			
		||||
    //    ttmp = ttmp* pow(10.0,mu);
 | 
			
		||||
    PokeIndex<LorentzIndex>(Umu,ttmp,mu);
 | 
			
		||||
  }
 | 
			
		||||
  std::cout << GridLogMessage << "Forced to diagonal " << std::endl;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  ////////////////////////////////////
 | 
			
		||||
  // Naive wilson implementation
 | 
			
		||||
  ////////////////////////////////////
 | 
			
		||||
  // replicate across fifth dimension
 | 
			
		||||
  LatticeGaugeField Umu5d(FGrid); 
 | 
			
		||||
  std::vector<LatticeColourMatrix> U(4,FGrid);
 | 
			
		||||
  for(int ss=0;ss<Umu._grid->oSites();ss++){
 | 
			
		||||
    for(int s=0;s<Ls;s++){
 | 
			
		||||
      Umu5d._odata[Ls*ss+s] = Umu._odata[ss];
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ////////////////////////////////////
 | 
			
		||||
  // Naive wilson implementation
 | 
			
		||||
  ////////////////////////////////////
 | 
			
		||||
  std::vector<LatticeColourMatrix> U(4,FGrid);
 | 
			
		||||
  for(int mu=0;mu<Nd;mu++){
 | 
			
		||||
    U[mu] = PeekIndex<LorentzIndex>(Umu5d,mu);
 | 
			
		||||
  }
 | 
			
		||||
  std::cout << GridLogMessage << "Setting up Cshift based reference " << std::endl;
 | 
			
		||||
 | 
			
		||||
  if (1)
 | 
			
		||||
  {
 | 
			
		||||
@@ -120,8 +145,7 @@ int main (int argc, char ** argv)
 | 
			
		||||
  RealD M5  =1.8;
 | 
			
		||||
 | 
			
		||||
  RealD NP = UGrid->_Nprocessors;
 | 
			
		||||
 | 
			
		||||
  DomainWallFermionR Dw(Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5);
 | 
			
		||||
  RealD NN = UGrid->NodeCount();
 | 
			
		||||
 | 
			
		||||
  std::cout << GridLogMessage<< "*****************************************************************" <<std::endl;
 | 
			
		||||
  std::cout << GridLogMessage<< "* Kernel options --dslash-generic, --dslash-unroll, --dslash-asm" <<std::endl;
 | 
			
		||||
@@ -131,15 +155,22 @@ int main (int argc, char ** argv)
 | 
			
		||||
  std::cout << GridLogMessage<< "* Vectorising space-time by "<<vComplex::Nsimd()<<std::endl;
 | 
			
		||||
  if ( sizeof(Real)==4 )   std::cout << GridLogMessage<< "* SINGLE precision "<<std::endl;
 | 
			
		||||
  if ( sizeof(Real)==8 )   std::cout << GridLogMessage<< "* DOUBLE precision "<<std::endl;
 | 
			
		||||
#ifdef GRID_OMP
 | 
			
		||||
  if ( WilsonKernelsStatic::Comms == WilsonKernelsStatic::CommsAndCompute ) std::cout << GridLogMessage<< "* Using Overlapped Comms/Compute" <<std::endl;
 | 
			
		||||
  if ( WilsonKernelsStatic::Comms == WilsonKernelsStatic::CommsThenCompute) std::cout << GridLogMessage<< "* Using sequential comms compute" <<std::endl;
 | 
			
		||||
#endif
 | 
			
		||||
  if ( WilsonKernelsStatic::Opt == WilsonKernelsStatic::OptGeneric   ) std::cout << GridLogMessage<< "* Using GENERIC Nc WilsonKernels" <<std::endl;
 | 
			
		||||
  if ( WilsonKernelsStatic::Opt == WilsonKernelsStatic::OptHandUnroll) std::cout << GridLogMessage<< "* Using Nc=3       WilsonKernels" <<std::endl;
 | 
			
		||||
  if ( WilsonKernelsStatic::Opt == WilsonKernelsStatic::OptInlineAsm ) std::cout << GridLogMessage<< "* Using Asm Nc=3   WilsonKernels" <<std::endl;
 | 
			
		||||
  std::cout << GridLogMessage<< "*****************************************************************" <<std::endl;
 | 
			
		||||
 | 
			
		||||
  int ncall =100;
 | 
			
		||||
  DomainWallFermionR Dw(Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5);
 | 
			
		||||
  int ncall =1000;
 | 
			
		||||
  if (1) {
 | 
			
		||||
    FGrid->Barrier();
 | 
			
		||||
    Dw.ZeroCounters();
 | 
			
		||||
    Dw.Dhop(src,result,0);
 | 
			
		||||
    std::cout<<GridLogMessage<<"Called warmup"<<std::endl;
 | 
			
		||||
    double t0=usecond();
 | 
			
		||||
    for(int i=0;i<ncall;i++){
 | 
			
		||||
      __SSC_START;
 | 
			
		||||
@@ -153,16 +184,55 @@ int main (int argc, char ** argv)
 | 
			
		||||
    double flops=1344*volume*ncall;
 | 
			
		||||
 | 
			
		||||
    std::cout<<GridLogMessage << "Called Dw "<<ncall<<" times in "<<t1-t0<<" us"<<std::endl;
 | 
			
		||||
    std::cout<<GridLogMessage << "norm result "<< norm2(result)<<std::endl;
 | 
			
		||||
    std::cout<<GridLogMessage << "norm ref    "<< norm2(ref)<<std::endl;
 | 
			
		||||
    //    std::cout<<GridLogMessage << "norm result "<< norm2(result)<<std::endl;
 | 
			
		||||
    //    std::cout<<GridLogMessage << "norm ref    "<< norm2(ref)<<std::endl;
 | 
			
		||||
    std::cout<<GridLogMessage << "mflop/s =   "<< flops/(t1-t0)<<std::endl;
 | 
			
		||||
    std::cout<<GridLogMessage << "mflop/s per rank =  "<< flops/(t1-t0)/NP<<std::endl;
 | 
			
		||||
    std::cout<<GridLogMessage << "mflop/s per node =  "<< flops/(t1-t0)/NN<<std::endl;
 | 
			
		||||
    err = ref-result; 
 | 
			
		||||
    std::cout<<GridLogMessage << "norm diff   "<< norm2(err)<<std::endl;
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
    if(( norm2(err)>1.0e-4) ) { 
 | 
			
		||||
      std::cout << "RESULT\n " << result<<std::endl;
 | 
			
		||||
      std::cout << "REF   \n " << ref   <<std::endl;
 | 
			
		||||
      std::cout << "ERR   \n " << err   <<std::endl;
 | 
			
		||||
      FGrid->Barrier();
 | 
			
		||||
      exit(-1);
 | 
			
		||||
    }
 | 
			
		||||
    */
 | 
			
		||||
    assert (norm2(err)< 1.0e-4 );
 | 
			
		||||
    Dw.Report();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  DomainWallFermionRL DwH(Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5);
 | 
			
		||||
  if (1) {
 | 
			
		||||
    FGrid->Barrier();
 | 
			
		||||
    DwH.ZeroCounters();
 | 
			
		||||
    DwH.Dhop(src,result,0);
 | 
			
		||||
    double t0=usecond();
 | 
			
		||||
    for(int i=0;i<ncall;i++){
 | 
			
		||||
      __SSC_START;
 | 
			
		||||
      DwH.Dhop(src,result,0);
 | 
			
		||||
      __SSC_STOP;
 | 
			
		||||
    }
 | 
			
		||||
    double t1=usecond();
 | 
			
		||||
    FGrid->Barrier();
 | 
			
		||||
    
 | 
			
		||||
    double volume=Ls;  for(int mu=0;mu<Nd;mu++) volume=volume*latt4[mu];
 | 
			
		||||
    double flops=1344*volume*ncall;
 | 
			
		||||
 | 
			
		||||
    std::cout<<GridLogMessage << "Called half prec comms Dw "<<ncall<<" times in "<<t1-t0<<" us"<<std::endl;
 | 
			
		||||
    std::cout<<GridLogMessage << "mflop/s =   "<< flops/(t1-t0)<<std::endl;
 | 
			
		||||
    std::cout<<GridLogMessage << "mflop/s per rank =  "<< flops/(t1-t0)/NP<<std::endl;
 | 
			
		||||
    std::cout<<GridLogMessage << "mflop/s per node =  "<< flops/(t1-t0)/NN<<std::endl;
 | 
			
		||||
    err = ref-result; 
 | 
			
		||||
    std::cout<<GridLogMessage << "norm diff   "<< norm2(err)<<std::endl;
 | 
			
		||||
 | 
			
		||||
    assert (norm2(err)< 1.0e-3 );
 | 
			
		||||
    DwH.Report();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (1)
 | 
			
		||||
  {
 | 
			
		||||
 | 
			
		||||
@@ -171,6 +241,10 @@ int main (int argc, char ** argv)
 | 
			
		||||
    std::cout << GridLogMessage<< "* Vectorising fifth dimension by "<<vComplex::Nsimd()<<std::endl;
 | 
			
		||||
    if ( sizeof(Real)==4 )   std::cout << GridLogMessage<< "* SINGLE precision "<<std::endl;
 | 
			
		||||
    if ( sizeof(Real)==8 )   std::cout << GridLogMessage<< "* DOUBLE precision "<<std::endl;
 | 
			
		||||
#ifdef GRID_OMP
 | 
			
		||||
  if ( WilsonKernelsStatic::Comms == WilsonKernelsStatic::CommsAndCompute ) std::cout << GridLogMessage<< "* Using Overlapped Comms/Compute" <<std::endl;
 | 
			
		||||
  if ( WilsonKernelsStatic::Comms == WilsonKernelsStatic::CommsThenCompute) std::cout << GridLogMessage<< "* Using sequential comms compute" <<std::endl;
 | 
			
		||||
#endif
 | 
			
		||||
    if ( WilsonKernelsStatic::Opt == WilsonKernelsStatic::OptGeneric   ) std::cout << GridLogMessage<< "* Using GENERIC Nc WilsonKernels" <<std::endl;
 | 
			
		||||
    if ( WilsonKernelsStatic::Opt == WilsonKernelsStatic::OptHandUnroll) std::cout << GridLogMessage<< "* Using Nc=3       WilsonKernels" <<std::endl;
 | 
			
		||||
    if ( WilsonKernelsStatic::Opt == WilsonKernelsStatic::OptInlineAsm ) std::cout << GridLogMessage<< "* Using Asm Nc=3   WilsonKernels" <<std::endl;
 | 
			
		||||
@@ -182,21 +256,13 @@ int main (int argc, char ** argv)
 | 
			
		||||
    LatticeFermion sresult(sFGrid);
 | 
			
		||||
 | 
			
		||||
    WilsonFermion5DR sDw(Umu,*sFGrid,*sFrbGrid,*sUGrid,*sUrbGrid,M5);
 | 
			
		||||
  
 | 
			
		||||
    for(int x=0;x<latt4[0];x++){
 | 
			
		||||
    for(int y=0;y<latt4[1];y++){
 | 
			
		||||
    for(int z=0;z<latt4[2];z++){
 | 
			
		||||
    for(int t=0;t<latt4[3];t++){
 | 
			
		||||
    for(int s=0;s<Ls;s++){
 | 
			
		||||
      std::vector<int> site({s,x,y,z,t});
 | 
			
		||||
      SpinColourVector tmp;
 | 
			
		||||
      peekSite(tmp,src,site);
 | 
			
		||||
      pokeSite(tmp,ssrc,site);
 | 
			
		||||
    }}}}}
 | 
			
		||||
 | 
			
		||||
    localConvert(src,ssrc);
 | 
			
		||||
    std::cout<<GridLogMessage<< "src norms "<< norm2(src)<<" " <<norm2(ssrc)<<std::endl;
 | 
			
		||||
    FGrid->Barrier();
 | 
			
		||||
    double t0=usecond();
 | 
			
		||||
    sDw.Dhop(ssrc,sresult,0);
 | 
			
		||||
    sDw.ZeroCounters();
 | 
			
		||||
    double t0=usecond();
 | 
			
		||||
    for(int i=0;i<ncall;i++){
 | 
			
		||||
      __SSC_START;
 | 
			
		||||
      sDw.Dhop(ssrc,sresult,0);
 | 
			
		||||
@@ -210,46 +276,52 @@ int main (int argc, char ** argv)
 | 
			
		||||
    std::cout<<GridLogMessage << "Called Dw s_inner "<<ncall<<" times in "<<t1-t0<<" us"<<std::endl;
 | 
			
		||||
    std::cout<<GridLogMessage << "mflop/s =   "<< flops/(t1-t0)<<std::endl;
 | 
			
		||||
    std::cout<<GridLogMessage << "mflop/s per rank =  "<< flops/(t1-t0)/NP<<std::endl;
 | 
			
		||||
    std::cout<<GridLogMessage << "mflop/s per node =  "<< flops/(t1-t0)/NN<<std::endl;
 | 
			
		||||
    //    std::cout<<GridLogMessage<< "res norms "<< norm2(result)<<" " <<norm2(sresult)<<std::endl;
 | 
			
		||||
    sDw.Report();
 | 
			
		||||
  
 | 
			
		||||
    if(0){
 | 
			
		||||
      for(int i=0;i< PerformanceCounter::NumTypes(); i++ ){
 | 
			
		||||
	sDw.Dhop(ssrc,sresult,0);
 | 
			
		||||
	PerformanceCounter Counter(i);
 | 
			
		||||
	Counter.Start();
 | 
			
		||||
	sDw.Dhop(ssrc,sresult,0);
 | 
			
		||||
	Counter.Stop();
 | 
			
		||||
	Counter.Report();
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::cout<<GridLogMessage<< "res norms "<< norm2(result)<<" " <<norm2(sresult)<<std::endl;
 | 
			
		||||
 | 
			
		||||
    RealD sum=0;
 | 
			
		||||
    for(int x=0;x<latt4[0];x++){
 | 
			
		||||
    for(int y=0;y<latt4[1];y++){
 | 
			
		||||
    for(int z=0;z<latt4[2];z++){
 | 
			
		||||
    for(int t=0;t<latt4[3];t++){
 | 
			
		||||
    for(int s=0;s<Ls;s++){
 | 
			
		||||
      std::vector<int> site({s,x,y,z,t});
 | 
			
		||||
      SpinColourVector normal, simd;
 | 
			
		||||
      peekSite(normal,result,site);
 | 
			
		||||
      peekSite(simd,sresult,site);
 | 
			
		||||
      sum=sum+norm2(normal-simd);
 | 
			
		||||
      if (norm2(normal-simd) > 1.0e-6 ) {
 | 
			
		||||
	std::cout << "site "<<x<<","<<y<<","<<z<<","<<t<<","<<s<<" "<<norm2(normal-simd)<<std::endl;
 | 
			
		||||
	std::cout << "site "<<x<<","<<y<<","<<z<<","<<t<<","<<s<<" normal "<<normal<<std::endl;
 | 
			
		||||
	std::cout << "site "<<x<<","<<y<<","<<z<<","<<t<<","<<s<<" simd   "<<simd<<std::endl;
 | 
			
		||||
      }
 | 
			
		||||
    }}}}}
 | 
			
		||||
    std::cout<<GridLogMessage<<" difference between normal and simd is "<<sum<<std::endl;
 | 
			
		||||
    assert (sum< 1.0e-4 );
 | 
			
		||||
 | 
			
		||||
    err=zero;
 | 
			
		||||
    localConvert(sresult,err);
 | 
			
		||||
    err = err - ref;
 | 
			
		||||
    sum = norm2(err);
 | 
			
		||||
    std::cout<<GridLogMessage<<" difference between normal ref and simd is "<<sum<<std::endl;
 | 
			
		||||
    if(sum > 1.0e-4 ){
 | 
			
		||||
      std::cout<< "sD REF\n " <<ref << std::endl;
 | 
			
		||||
      std::cout<< "sD ERR   \n " <<err  <<std::endl;
 | 
			
		||||
    }
 | 
			
		||||
    //    assert(sum < 1.0e-4);
 | 
			
		||||
 | 
			
		||||
    if (1) {
 | 
			
		||||
    err=zero;
 | 
			
		||||
    localConvert(sresult,err);
 | 
			
		||||
    err = err - result;
 | 
			
		||||
    sum = norm2(err);
 | 
			
		||||
    std::cout<<GridLogMessage<<" difference between normal result and simd is "<<sum<<std::endl;
 | 
			
		||||
    if(sum > 1.0e-4 ){
 | 
			
		||||
      std::cout<< "sD REF\n " <<result << std::endl;
 | 
			
		||||
      std::cout<< "sD ERR   \n " << err  <<std::endl;
 | 
			
		||||
    }
 | 
			
		||||
    assert(sum < 1.0e-4);
 | 
			
		||||
    
 | 
			
		||||
    if(1){
 | 
			
		||||
      std::cout << GridLogMessage<< "*********************************************************" <<std::endl;
 | 
			
		||||
      std::cout << GridLogMessage<< "* Benchmarking WilsonFermion5D<DomainWallVec5dImplR>::DhopEO "<<std::endl;
 | 
			
		||||
      std::cout << GridLogMessage<< "* Vectorising fifth dimension by "<<vComplex::Nsimd()<<std::endl;
 | 
			
		||||
      if ( sizeof(Real)==4 )   std::cout << GridLogMessage<< "* SINGLE precision "<<std::endl;
 | 
			
		||||
      if ( sizeof(Real)==8 )   std::cout << GridLogMessage<< "* DOUBLE precision "<<std::endl;
 | 
			
		||||
#ifdef GRID_OMP
 | 
			
		||||
  if ( WilsonKernelsStatic::Comms == WilsonKernelsStatic::CommsAndCompute ) std::cout << GridLogMessage<< "* Using Overlapped Comms/Compute" <<std::endl;
 | 
			
		||||
  if ( WilsonKernelsStatic::Comms == WilsonKernelsStatic::CommsThenCompute) std::cout << GridLogMessage<< "* Using sequential comms compute" <<std::endl;
 | 
			
		||||
#endif
 | 
			
		||||
      if ( WilsonKernelsStatic::Opt == WilsonKernelsStatic::OptGeneric   ) 
 | 
			
		||||
	std::cout << GridLogMessage<< "* Using GENERIC Nc WilsonKernels" <<std::endl;
 | 
			
		||||
      if ( WilsonKernelsStatic::Opt == WilsonKernelsStatic::OptHandUnroll) 
 | 
			
		||||
	std::cout << GridLogMessage<< "* Using Nc=3       WilsonKernels" <<std::endl;
 | 
			
		||||
      if ( WilsonKernelsStatic::Opt == WilsonKernelsStatic::OptInlineAsm ) 
 | 
			
		||||
	std::cout << GridLogMessage<< "* Using Asm Nc=3   WilsonKernels" <<std::endl;
 | 
			
		||||
      std::cout << GridLogMessage<< "*********************************************************" <<std::endl;
 | 
			
		||||
 | 
			
		||||
      LatticeFermion sr_eo(sFGrid);
 | 
			
		||||
 | 
			
		||||
      LatticeFermion ssrc_e (sFrbGrid);
 | 
			
		||||
      LatticeFermion ssrc_o (sFrbGrid);
 | 
			
		||||
      LatticeFermion sr_e   (sFrbGrid);
 | 
			
		||||
@@ -257,39 +329,30 @@ int main (int argc, char ** argv)
 | 
			
		||||
 | 
			
		||||
      pickCheckerboard(Even,ssrc_e,ssrc);
 | 
			
		||||
      pickCheckerboard(Odd,ssrc_o,ssrc);
 | 
			
		||||
 | 
			
		||||
      setCheckerboard(sr_eo,ssrc_o);
 | 
			
		||||
      setCheckerboard(sr_eo,ssrc_e);
 | 
			
		||||
      //      setCheckerboard(sr_eo,ssrc_o);
 | 
			
		||||
      //      setCheckerboard(sr_eo,ssrc_e);
 | 
			
		||||
 | 
			
		||||
      sr_e = zero;
 | 
			
		||||
      sr_o = zero;
 | 
			
		||||
 | 
			
		||||
      std::cout << GridLogMessage<< "*********************************************************" <<std::endl;
 | 
			
		||||
      std::cout << GridLogMessage<< "* Benchmarking WilsonFermion5D<DomainWallVec5dImplR>::DhopEO "<<std::endl;
 | 
			
		||||
      std::cout << GridLogMessage<< "* Vectorising fifth dimension by "<<vComplex::Nsimd()<<std::endl;
 | 
			
		||||
      if ( sizeof(Real)==4 )   std::cout << GridLogMessage<< "* SINGLE precision "<<std::endl;
 | 
			
		||||
      if ( sizeof(Real)==8 )   std::cout << GridLogMessage<< "* DOUBLE precision "<<std::endl;
 | 
			
		||||
      if ( WilsonKernelsStatic::Opt == WilsonKernelsStatic::OptGeneric   ) std::cout << GridLogMessage<< "* Using GENERIC Nc WilsonKernels" <<std::endl;
 | 
			
		||||
      if ( WilsonKernelsStatic::Opt == WilsonKernelsStatic::OptHandUnroll) std::cout << GridLogMessage<< "* Using Nc=3       WilsonKernels" <<std::endl;
 | 
			
		||||
      if ( WilsonKernelsStatic::Opt == WilsonKernelsStatic::OptInlineAsm ) std::cout << GridLogMessage<< "* Using Asm Nc=3   WilsonKernels" <<std::endl;
 | 
			
		||||
      std::cout << GridLogMessage<< "*********************************************************" <<std::endl;
 | 
			
		||||
 | 
			
		||||
      FGrid->Barrier();
 | 
			
		||||
      sDw.DhopEO(ssrc_o, sr_e, DaggerNo);
 | 
			
		||||
      sDw.ZeroCounters();
 | 
			
		||||
      sDw.stat.init("DhopEO");
 | 
			
		||||
      //      sDw.stat.init("DhopEO");
 | 
			
		||||
      double t0=usecond();
 | 
			
		||||
      for (int i = 0; i < ncall; i++) {
 | 
			
		||||
        sDw.DhopEO(ssrc_o, sr_e, DaggerNo);
 | 
			
		||||
      }
 | 
			
		||||
      double t1=usecond();
 | 
			
		||||
      FGrid->Barrier();
 | 
			
		||||
      sDw.stat.print();
 | 
			
		||||
      //      sDw.stat.print();
 | 
			
		||||
 | 
			
		||||
      double volume=Ls;  for(int mu=0;mu<Nd;mu++) volume=volume*latt4[mu];
 | 
			
		||||
      double flops=(1344.0*volume*ncall)/2;
 | 
			
		||||
 | 
			
		||||
      std::cout<<GridLogMessage << "sDeo mflop/s =   "<< flops/(t1-t0)<<std::endl;
 | 
			
		||||
      std::cout<<GridLogMessage << "sDeo mflop/s per rank   "<< flops/(t1-t0)/NP<<std::endl;
 | 
			
		||||
      std::cout<<GridLogMessage << "sDeo mflop/s per node   "<< flops/(t1-t0)/NN<<std::endl;
 | 
			
		||||
      sDw.Report();
 | 
			
		||||
 | 
			
		||||
      sDw.DhopEO(ssrc_o,sr_e,DaggerNo);
 | 
			
		||||
@@ -298,22 +361,26 @@ int main (int argc, char ** argv)
 | 
			
		||||
 | 
			
		||||
      pickCheckerboard(Even,ssrc_e,sresult);
 | 
			
		||||
      pickCheckerboard(Odd ,ssrc_o,sresult);
 | 
			
		||||
 | 
			
		||||
      ssrc_e = ssrc_e - sr_e;
 | 
			
		||||
      RealD error = norm2(ssrc_e);
 | 
			
		||||
 | 
			
		||||
      std::cout<<GridLogMessage << "sE norm diff   "<< norm2(ssrc_e)<< "  vec nrm"<<norm2(sr_e) <<std::endl;
 | 
			
		||||
      ssrc_o = ssrc_o - sr_o;
 | 
			
		||||
 | 
			
		||||
      ssrc_o = ssrc_o - sr_o;
 | 
			
		||||
      error+= norm2(ssrc_o);
 | 
			
		||||
      std::cout<<GridLogMessage << "sO norm diff   "<< norm2(ssrc_o)<< "  vec nrm"<<norm2(sr_o) <<std::endl;
 | 
			
		||||
      if(error>1.0e-4) { 
 | 
			
		||||
 | 
			
		||||
      if(( error>1.0e-4) ) { 
 | 
			
		||||
	setCheckerboard(ssrc,ssrc_o);
 | 
			
		||||
	setCheckerboard(ssrc,ssrc_e);
 | 
			
		||||
	std::cout<< ssrc << std::endl;
 | 
			
		||||
	std::cout<< "DIFF\n " <<ssrc << std::endl;
 | 
			
		||||
	setCheckerboard(ssrc,sr_o);
 | 
			
		||||
	setCheckerboard(ssrc,sr_e);
 | 
			
		||||
	std::cout<< "CBRESULT\n " <<ssrc << std::endl;
 | 
			
		||||
	std::cout<< "RESULT\n " <<sresult<< std::endl;
 | 
			
		||||
      }
 | 
			
		||||
      assert(error<1.0e-4);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (1)
 | 
			
		||||
@@ -321,28 +388,33 @@ int main (int argc, char ** argv)
 | 
			
		||||
    ref = zero;
 | 
			
		||||
    for(int mu=0;mu<Nd;mu++){
 | 
			
		||||
 | 
			
		||||
      //    ref =  src - Gamma(Gamma::GammaX)* src ; // 1+gamma_x
 | 
			
		||||
      //    ref =  src - Gamma(Gamma::Algebra::GammaX)* src ; // 1+gamma_x
 | 
			
		||||
      tmp = U[mu]*Cshift(src,mu+1,1);
 | 
			
		||||
      for(int i=0;i<ref._odata.size();i++){
 | 
			
		||||
  ref._odata[i]+= tmp._odata[i] + Gamma(Gmu[mu])*tmp._odata[i]; ;
 | 
			
		||||
	ref._odata[i]+= tmp._odata[i] + Gamma(Gmu[mu])*tmp._odata[i]; ;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      tmp =adj(U[mu])*src;
 | 
			
		||||
      tmp =Cshift(tmp,mu+1,-1);
 | 
			
		||||
      for(int i=0;i<ref._odata.size();i++){
 | 
			
		||||
  ref._odata[i]+= tmp._odata[i] - Gamma(Gmu[mu])*tmp._odata[i]; ;
 | 
			
		||||
	ref._odata[i]+= tmp._odata[i] - Gamma(Gmu[mu])*tmp._odata[i]; ;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    ref = -0.5*ref;
 | 
			
		||||
  }
 | 
			
		||||
  //  dump=1;
 | 
			
		||||
  Dw.Dhop(src,result,1);
 | 
			
		||||
  std::cout << GridLogMessage << "Compare to naive wilson implementation Dag to verify correctness" << std::endl;
 | 
			
		||||
  std::cout<<GridLogMessage << "Called DwDag"<<std::endl;
 | 
			
		||||
  std::cout<<GridLogMessage << "norm result "<< norm2(result)<<std::endl;
 | 
			
		||||
  std::cout<<GridLogMessage << "norm ref    "<< norm2(ref)<<std::endl;
 | 
			
		||||
  std::cout<<GridLogMessage << "norm dag result "<< norm2(result)<<std::endl;
 | 
			
		||||
  std::cout<<GridLogMessage << "norm dag ref    "<< norm2(ref)<<std::endl;
 | 
			
		||||
  err = ref-result; 
 | 
			
		||||
  std::cout<<GridLogMessage << "norm diff   "<< norm2(err)<<std::endl;
 | 
			
		||||
  assert(norm2(err)<1.0e-4);
 | 
			
		||||
  std::cout<<GridLogMessage << "norm dag diff   "<< norm2(err)<<std::endl;
 | 
			
		||||
  if((norm2(err)>1.0e-4)){
 | 
			
		||||
	std::cout<< "DAG RESULT\n "  <<ref     << std::endl;
 | 
			
		||||
	std::cout<< "DAG sRESULT\n " <<result  << std::endl;
 | 
			
		||||
	std::cout<< "DAG ERR   \n "  << err    <<std::endl;
 | 
			
		||||
  }
 | 
			
		||||
  LatticeFermion src_e (FrbGrid);
 | 
			
		||||
  LatticeFermion src_o (FrbGrid);
 | 
			
		||||
  LatticeFermion r_e   (FrbGrid);
 | 
			
		||||
@@ -350,18 +422,24 @@ int main (int argc, char ** argv)
 | 
			
		||||
  LatticeFermion r_eo  (FGrid);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  std::cout<<GridLogMessage << "Calling Deo and Doe and assert Deo+Doe == Dunprec"<<std::endl;
 | 
			
		||||
  std::cout<<GridLogMessage << "Calling Deo and Doe and //assert Deo+Doe == Dunprec"<<std::endl;
 | 
			
		||||
  pickCheckerboard(Even,src_e,src);
 | 
			
		||||
  pickCheckerboard(Odd,src_o,src);
 | 
			
		||||
 | 
			
		||||
  std::cout<<GridLogMessage << "src_e"<<norm2(src_e)<<std::endl;
 | 
			
		||||
  std::cout<<GridLogMessage << "src_o"<<norm2(src_o)<<std::endl;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  // S-direction is INNERMOST and takes no part in the parity.
 | 
			
		||||
  std::cout << GridLogMessage<< "*********************************************************" <<std::endl;
 | 
			
		||||
  std::cout << GridLogMessage<< "* Benchmarking DomainWallFermionR::DhopEO                "<<std::endl;
 | 
			
		||||
  std::cout << GridLogMessage<< "* Vectorising space-time by "<<vComplex::Nsimd()<<std::endl;
 | 
			
		||||
  if ( sizeof(Real)==4 )   std::cout << GridLogMessage<< "* SINGLE precision "<<std::endl;
 | 
			
		||||
  if ( sizeof(Real)==8 )   std::cout << GridLogMessage<< "* DOUBLE precision "<<std::endl;
 | 
			
		||||
#ifdef GRID_OMP
 | 
			
		||||
  if ( WilsonKernelsStatic::Comms == WilsonKernelsStatic::CommsAndCompute ) std::cout << GridLogMessage<< "* Using Overlapped Comms/Compute" <<std::endl;
 | 
			
		||||
  if ( WilsonKernelsStatic::Comms == WilsonKernelsStatic::CommsThenCompute) std::cout << GridLogMessage<< "* Using sequential comms compute" <<std::endl;
 | 
			
		||||
#endif
 | 
			
		||||
  if ( WilsonKernelsStatic::Opt == WilsonKernelsStatic::OptGeneric   ) std::cout << GridLogMessage<< "* Using GENERIC Nc WilsonKernels" <<std::endl;
 | 
			
		||||
  if ( WilsonKernelsStatic::Opt == WilsonKernelsStatic::OptHandUnroll) std::cout << GridLogMessage<< "* Using Nc=3       WilsonKernels" <<std::endl;
 | 
			
		||||
  if ( WilsonKernelsStatic::Opt == WilsonKernelsStatic::OptInlineAsm ) std::cout << GridLogMessage<< "* Using Asm Nc=3   WilsonKernels" <<std::endl;
 | 
			
		||||
@@ -369,6 +447,7 @@ int main (int argc, char ** argv)
 | 
			
		||||
  {
 | 
			
		||||
    Dw.ZeroCounters();
 | 
			
		||||
    FGrid->Barrier();
 | 
			
		||||
    Dw.DhopEO(src_o,r_e,DaggerNo);
 | 
			
		||||
    double t0=usecond();
 | 
			
		||||
    for(int i=0;i<ncall;i++){
 | 
			
		||||
      Dw.DhopEO(src_o,r_e,DaggerNo);
 | 
			
		||||
@@ -381,6 +460,7 @@ int main (int argc, char ** argv)
 | 
			
		||||
 | 
			
		||||
    std::cout<<GridLogMessage << "Deo mflop/s =   "<< flops/(t1-t0)<<std::endl;
 | 
			
		||||
    std::cout<<GridLogMessage << "Deo mflop/s per rank   "<< flops/(t1-t0)/NP<<std::endl;
 | 
			
		||||
    std::cout<<GridLogMessage << "Deo mflop/s per node   "<< flops/(t1-t0)/NN<<std::endl;
 | 
			
		||||
    Dw.Report();
 | 
			
		||||
  }
 | 
			
		||||
  Dw.DhopEO(src_o,r_e,DaggerNo);
 | 
			
		||||
@@ -396,14 +476,20 @@ int main (int argc, char ** argv)
 | 
			
		||||
 | 
			
		||||
  err = r_eo-result; 
 | 
			
		||||
  std::cout<<GridLogMessage << "norm diff   "<< norm2(err)<<std::endl;
 | 
			
		||||
  assert(norm2(err)<1.0e-4);
 | 
			
		||||
  if((norm2(err)>1.0e-4)){
 | 
			
		||||
	std::cout<< "Deo RESULT\n " <<r_eo << std::endl;
 | 
			
		||||
	std::cout<< "Deo REF\n " <<result  << std::endl;
 | 
			
		||||
	std::cout<< "Deo ERR   \n " << err <<std::endl;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  pickCheckerboard(Even,src_e,err);
 | 
			
		||||
  pickCheckerboard(Odd,src_o,err);
 | 
			
		||||
  std::cout<<GridLogMessage << "norm diff even  "<< norm2(src_e)<<std::endl;
 | 
			
		||||
  std::cout<<GridLogMessage << "norm diff odd   "<< norm2(src_o)<<std::endl;
 | 
			
		||||
  assert(norm2(src_e)<1.0e-4);
 | 
			
		||||
  assert(norm2(src_o)<1.0e-4);
 | 
			
		||||
 | 
			
		||||
  //assert(norm2(src_e)<1.0e-4);
 | 
			
		||||
  //assert(norm2(src_o)<1.0e-4);
 | 
			
		||||
 | 
			
		||||
  Grid_finalize();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -37,11 +37,11 @@ struct scal {
 | 
			
		||||
  d internal;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
  Gamma::GammaMatrix Gmu [] = {
 | 
			
		||||
    Gamma::GammaX,
 | 
			
		||||
    Gamma::GammaY,
 | 
			
		||||
    Gamma::GammaZ,
 | 
			
		||||
    Gamma::GammaT
 | 
			
		||||
  Gamma::Algebra Gmu [] = {
 | 
			
		||||
    Gamma::Algebra::GammaX,
 | 
			
		||||
    Gamma::Algebra::GammaY,
 | 
			
		||||
    Gamma::Algebra::GammaZ,
 | 
			
		||||
    Gamma::Algebra::GammaT
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
void benchDw(std::vector<int> & L, int Ls, int threads, int report =0 );
 | 
			
		||||
 
 | 
			
		||||
@@ -66,7 +66,8 @@ int main (int argc, char ** argv)
 | 
			
		||||
 | 
			
		||||
    Vec tsum; tsum = zero;
 | 
			
		||||
 | 
			
		||||
    GridParallelRNG          pRNG(&Grid);      pRNG.SeedRandomDevice();
 | 
			
		||||
    GridParallelRNG          pRNG(&Grid);      
 | 
			
		||||
    pRNG.SeedFixedIntegers(std::vector<int>({56,17,89,101}));
 | 
			
		||||
 | 
			
		||||
    std::vector<double> stop(threads);
 | 
			
		||||
    Vector<Vec> sum(threads);
 | 
			
		||||
@@ -77,8 +78,7 @@ int main (int argc, char ** argv)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    double start=usecond();
 | 
			
		||||
PARALLEL_FOR_LOOP
 | 
			
		||||
    for(int t=0;t<threads;t++){
 | 
			
		||||
    parallel_for(int t=0;t<threads;t++){
 | 
			
		||||
 | 
			
		||||
      sum[t] = x[t]._odata[0];
 | 
			
		||||
      for(int i=0;i<Nloop;i++){
 | 
			
		||||
 
 | 
			
		||||
@@ -55,8 +55,8 @@ int main (int argc, char ** argv)
 | 
			
		||||
  std::cout<<GridLogMessage << "===================================================================================================="<<std::endl;
 | 
			
		||||
  std::cout<<GridLogMessage << "  L  "<<"\t\t"<<"bytes"<<"\t\t\t"<<"GB/s"<<"\t\t"<<"Gflop/s"<<"\t\t seconds"<<std::endl;
 | 
			
		||||
  std::cout<<GridLogMessage << "----------------------------------------------------------"<<std::endl;
 | 
			
		||||
  uint64_t lmax=44;
 | 
			
		||||
#define NLOOP (1*lmax*lmax*lmax*lmax/vol)
 | 
			
		||||
  uint64_t lmax=64;
 | 
			
		||||
#define NLOOP (100*lmax*lmax*lmax*lmax/vol)
 | 
			
		||||
  for(int lat=4;lat<=lmax;lat+=4){
 | 
			
		||||
 | 
			
		||||
      std::vector<int> latt_size  ({lat*mpi_layout[0],lat*mpi_layout[1],lat*mpi_layout[2],lat*mpi_layout[3]});
 | 
			
		||||
@@ -65,7 +65,7 @@ int main (int argc, char ** argv)
 | 
			
		||||
 | 
			
		||||
      uint64_t Nloop=NLOOP;
 | 
			
		||||
 | 
			
		||||
      //      GridParallelRNG          pRNG(&Grid);      pRNG.SeedRandomDevice();
 | 
			
		||||
      //      GridParallelRNG          pRNG(&Grid);      pRNG.SeedFixedIntegers(std::vector<int>({45,12,81,9});
 | 
			
		||||
 | 
			
		||||
      LatticeVec z(&Grid); //random(pRNG,z);
 | 
			
		||||
      LatticeVec x(&Grid); //random(pRNG,x);
 | 
			
		||||
@@ -100,7 +100,7 @@ int main (int argc, char ** argv)
 | 
			
		||||
      int vol = latt_size[0]*latt_size[1]*latt_size[2]*latt_size[3];
 | 
			
		||||
      GridCartesian     Grid(latt_size,simd_layout,mpi_layout);
 | 
			
		||||
 | 
			
		||||
      //      GridParallelRNG          pRNG(&Grid);      pRNG.SeedRandomDevice();
 | 
			
		||||
      //      GridParallelRNG          pRNG(&Grid);      pRNG.SeedFixedIntegers(std::vector<int>({45,12,81,9});
 | 
			
		||||
 | 
			
		||||
      LatticeVec z(&Grid); //random(pRNG,z);
 | 
			
		||||
      LatticeVec x(&Grid); //random(pRNG,x);
 | 
			
		||||
@@ -138,7 +138,7 @@ int main (int argc, char ** argv)
 | 
			
		||||
 | 
			
		||||
      GridCartesian     Grid(latt_size,simd_layout,mpi_layout);
 | 
			
		||||
 | 
			
		||||
      //      GridParallelRNG          pRNG(&Grid);      pRNG.SeedRandomDevice();
 | 
			
		||||
      //      GridParallelRNG          pRNG(&Grid);      pRNG.SeedFixedIntegers(std::vector<int>({45,12,81,9});
 | 
			
		||||
 | 
			
		||||
      LatticeVec z(&Grid); //random(pRNG,z);
 | 
			
		||||
      LatticeVec x(&Grid); //random(pRNG,x);
 | 
			
		||||
@@ -173,7 +173,7 @@ int main (int argc, char ** argv)
 | 
			
		||||
      uint64_t Nloop=NLOOP;
 | 
			
		||||
      GridCartesian     Grid(latt_size,simd_layout,mpi_layout);
 | 
			
		||||
 | 
			
		||||
      //      GridParallelRNG          pRNG(&Grid);      pRNG.SeedRandomDevice();
 | 
			
		||||
      //      GridParallelRNG          pRNG(&Grid);      pRNG.SeedFixedIntegers(std::vector<int>({45,12,81,9});
 | 
			
		||||
      LatticeVec z(&Grid); //random(pRNG,z);
 | 
			
		||||
      LatticeVec x(&Grid); //random(pRNG,x);
 | 
			
		||||
      LatticeVec y(&Grid); //random(pRNG,y);
 | 
			
		||||
 
 | 
			
		||||
@@ -113,6 +113,36 @@ int main (int argc, char ** argv)
 | 
			
		||||
    std::cout<<GridLogMessage << "Called " #A " "<< (t1-t0)/ncall<<" us"<<std::endl;\
 | 
			
		||||
    std::cout<<GridLogMessage << "******************"<<std::endl;
 | 
			
		||||
 | 
			
		||||
#define BENCH_ZDW(A,in,out)			\
 | 
			
		||||
    zDw.CayleyZeroCounters();			\
 | 
			
		||||
    zDw. A (in,out);				\
 | 
			
		||||
    FGrid->Barrier();				\
 | 
			
		||||
    t0=usecond();				\
 | 
			
		||||
    for(int i=0;i<ncall;i++){			\
 | 
			
		||||
      zDw. A (in,out);				\
 | 
			
		||||
    }						\
 | 
			
		||||
    t1=usecond();				\
 | 
			
		||||
    FGrid->Barrier();				\
 | 
			
		||||
    zDw.CayleyReport();							\
 | 
			
		||||
    std::cout<<GridLogMessage << "Called ZDw " #A " "<< (t1-t0)/ncall<<" us"<<std::endl;\
 | 
			
		||||
    std::cout<<GridLogMessage << "******************"<<std::endl;
 | 
			
		||||
 | 
			
		||||
#define BENCH_DW_SSC(A,in,out)			\
 | 
			
		||||
    Dw.CayleyZeroCounters();			\
 | 
			
		||||
    Dw. A (in,out);				\
 | 
			
		||||
    FGrid->Barrier();				\
 | 
			
		||||
    t0=usecond();				\
 | 
			
		||||
    for(int i=0;i<ncall;i++){			\
 | 
			
		||||
      __SSC_START ;				\
 | 
			
		||||
      Dw. A (in,out);				\
 | 
			
		||||
      __SSC_STOP ;				\
 | 
			
		||||
    }						\
 | 
			
		||||
    t1=usecond();				\
 | 
			
		||||
    FGrid->Barrier();				\
 | 
			
		||||
    Dw.CayleyReport();					\
 | 
			
		||||
    std::cout<<GridLogMessage << "Called " #A " "<< (t1-t0)/ncall<<" us"<<std::endl;\
 | 
			
		||||
    std::cout<<GridLogMessage << "******************"<<std::endl;
 | 
			
		||||
 | 
			
		||||
#define BENCH_DW_MEO(A,in,out)			\
 | 
			
		||||
    Dw.CayleyZeroCounters();			\
 | 
			
		||||
    Dw. A (in,out,0);				\
 | 
			
		||||
@@ -148,9 +178,15 @@ int main (int argc, char ** argv)
 | 
			
		||||
    LatticeFermion sref(sFGrid);
 | 
			
		||||
    LatticeFermion result(sFGrid);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    std::cout<<GridLogMessage << "Constructing Vec5D Dw "<<std::endl;
 | 
			
		||||
    DomainWallFermionVec5dR Dw(Umu,*sFGrid,*sFrbGrid,*sUGrid,*sUrbGrid,mass,M5);
 | 
			
		||||
 | 
			
		||||
    RealD b=1.5;// Scale factor b+c=2, b-c=1
 | 
			
		||||
    RealD c=0.5;
 | 
			
		||||
    std::vector<ComplexD> gamma(Ls,std::complex<double>(1.0,0.0));
 | 
			
		||||
    ZMobiusFermionVec5dR zDw(Umu,*sFGrid,*sFrbGrid,*sUGrid,*sUrbGrid,mass,M5,gamma,b,c);
 | 
			
		||||
 | 
			
		||||
    std::cout<<GridLogMessage << "Calling Dhop "<<std::endl;
 | 
			
		||||
    FGrid->Barrier();
 | 
			
		||||
 | 
			
		||||
@@ -173,10 +209,13 @@ int main (int argc, char ** argv)
 | 
			
		||||
 | 
			
		||||
    BENCH_DW_MEO(Dhop    ,src,result);
 | 
			
		||||
    BENCH_DW_MEO(DhopEO  ,src_o,r_e);
 | 
			
		||||
    BENCH_DW(Meooe   ,src_o,r_e);
 | 
			
		||||
    BENCH_DW_SSC(Meooe   ,src_o,r_e);
 | 
			
		||||
    BENCH_DW(Mooee   ,src_o,r_o);
 | 
			
		||||
    BENCH_DW(MooeeInv,src_o,r_o);
 | 
			
		||||
 | 
			
		||||
    BENCH_ZDW(Mooee   ,src_o,r_o);
 | 
			
		||||
    BENCH_ZDW(MooeeInv,src_o,r_o);
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Grid_finalize();
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										134
									
								
								benchmarks/Benchmark_staggered.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								benchmarks/Benchmark_staggered.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,134 @@
 | 
			
		||||
    /*************************************************************************************
 | 
			
		||||
 | 
			
		||||
    Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
    Source file: ./benchmarks/Benchmark_staggered.cc
 | 
			
		||||
 | 
			
		||||
    Copyright (C) 2015
 | 
			
		||||
 | 
			
		||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
 | 
			
		||||
    This program is free software; you can redistribute it and/or modify
 | 
			
		||||
    it under the terms of the GNU General Public License as published by
 | 
			
		||||
    the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
    (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
    This program is distributed in the hope that it will be useful,
 | 
			
		||||
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
    GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
    You should have received a copy of the GNU General Public License along
 | 
			
		||||
    with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
    See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
    *************************************************************************************/
 | 
			
		||||
    /*  END LEGAL */
 | 
			
		||||
#include <Grid/Grid.h>
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
using namespace Grid;
 | 
			
		||||
using namespace Grid::QCD;
 | 
			
		||||
 | 
			
		||||
int main (int argc, char ** argv)
 | 
			
		||||
{
 | 
			
		||||
  Grid_init(&argc,&argv);
 | 
			
		||||
 | 
			
		||||
  std::vector<int> latt_size   = GridDefaultLatt();
 | 
			
		||||
  std::vector<int> simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
 | 
			
		||||
  std::vector<int> mpi_layout  = GridDefaultMpi();
 | 
			
		||||
  GridCartesian               Grid(latt_size,simd_layout,mpi_layout);
 | 
			
		||||
  GridRedBlackCartesian     RBGrid(latt_size,simd_layout,mpi_layout);
 | 
			
		||||
 | 
			
		||||
  int threads = GridThread::GetThreads();
 | 
			
		||||
  std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl;
 | 
			
		||||
  std::cout<<GridLogMessage << "Grid floating point word size is REALF"<< sizeof(RealF)<<std::endl;
 | 
			
		||||
  std::cout<<GridLogMessage << "Grid floating point word size is REALD"<< sizeof(RealD)<<std::endl;
 | 
			
		||||
  std::cout<<GridLogMessage << "Grid floating point word size is REAL"<< sizeof(Real)<<std::endl;
 | 
			
		||||
 | 
			
		||||
  std::vector<int> seeds({1,2,3,4});
 | 
			
		||||
  GridParallelRNG          pRNG(&Grid);
 | 
			
		||||
  pRNG.SeedFixedIntegers(seeds);
 | 
			
		||||
  //  pRNG.SeedFixedIntegers(std::vector<int>({45,12,81,9});
 | 
			
		||||
 | 
			
		||||
  typedef typename ImprovedStaggeredFermionR::FermionField FermionField; 
 | 
			
		||||
  typename ImprovedStaggeredFermionR::ImplParams params; 
 | 
			
		||||
 | 
			
		||||
  FermionField src   (&Grid); random(pRNG,src);
 | 
			
		||||
  FermionField result(&Grid); result=zero;
 | 
			
		||||
  FermionField    ref(&Grid);    ref=zero;
 | 
			
		||||
  FermionField    tmp(&Grid);    tmp=zero;
 | 
			
		||||
  FermionField    err(&Grid);    tmp=zero;
 | 
			
		||||
  LatticeGaugeField Umu(&Grid); random(pRNG,Umu);
 | 
			
		||||
  std::vector<LatticeColourMatrix> U(4,&Grid);
 | 
			
		||||
 | 
			
		||||
  double volume=1;
 | 
			
		||||
  for(int mu=0;mu<Nd;mu++){
 | 
			
		||||
    volume=volume*latt_size[mu];
 | 
			
		||||
  }  
 | 
			
		||||
 | 
			
		||||
  // Only one non-zero (y)
 | 
			
		||||
#if 0
 | 
			
		||||
  Umu=zero;
 | 
			
		||||
  Complex cone(1.0,0.0);
 | 
			
		||||
  for(int nn=0;nn<Nd;nn++){
 | 
			
		||||
    random(pRNG,U[nn]);
 | 
			
		||||
    if(1) {
 | 
			
		||||
      if (nn!=2) { U[nn]=zero; std::cout<<GridLogMessage << "zeroing gauge field in dir "<<nn<<std::endl; }
 | 
			
		||||
      //      else       { U[nn]= cone;std::cout<<GridLogMessage << "unit gauge field in dir "<<nn<<std::endl; }
 | 
			
		||||
      else       { std::cout<<GridLogMessage << "random gauge field in dir "<<nn<<std::endl; }
 | 
			
		||||
    }
 | 
			
		||||
    PokeIndex<LorentzIndex>(Umu,U[nn],nn);
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  for(int mu=0;mu<Nd;mu++){
 | 
			
		||||
    U[mu] = PeekIndex<LorentzIndex>(Umu,mu);
 | 
			
		||||
  }
 | 
			
		||||
  ref = zero;
 | 
			
		||||
  /*  
 | 
			
		||||
  { // Naive wilson implementation
 | 
			
		||||
    ref = zero;
 | 
			
		||||
    for(int mu=0;mu<Nd;mu++){
 | 
			
		||||
      //    ref =  src + Gamma(Gamma::GammaX)* src ; // 1-gamma_x
 | 
			
		||||
      tmp = U[mu]*Cshift(src,mu,1);
 | 
			
		||||
      for(int i=0;i<ref._odata.size();i++){
 | 
			
		||||
	ref._odata[i]+= tmp._odata[i] - Gamma(Gmu[mu])*tmp._odata[i]; ;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      tmp =adj(U[mu])*src;
 | 
			
		||||
      tmp =Cshift(tmp,mu,-1);
 | 
			
		||||
      for(int i=0;i<ref._odata.size();i++){
 | 
			
		||||
	ref._odata[i]+= tmp._odata[i] + Gamma(Gmu[mu])*tmp._odata[i]; ;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  ref = -0.5*ref;
 | 
			
		||||
  */
 | 
			
		||||
 | 
			
		||||
  RealD mass=0.1;
 | 
			
		||||
  RealD c1=9.0/8.0;
 | 
			
		||||
  RealD c2=-1.0/24.0;
 | 
			
		||||
  RealD u0=1.0;
 | 
			
		||||
  ImprovedStaggeredFermionR Ds(Umu,Umu,Grid,RBGrid,mass,c1,c2,u0,params);
 | 
			
		||||
  
 | 
			
		||||
  std::cout<<GridLogMessage << "Calling Ds"<<std::endl;
 | 
			
		||||
  int ncall=1000;
 | 
			
		||||
  double t0=usecond();
 | 
			
		||||
  for(int i=0;i<ncall;i++){
 | 
			
		||||
    Ds.Dhop(src,result,0);
 | 
			
		||||
  }
 | 
			
		||||
  double t1=usecond();
 | 
			
		||||
  double flops=(16*(3*(6+8+8)) + 15*3*2)*volume*ncall; // == 66*16 +  == 1146
 | 
			
		||||
  
 | 
			
		||||
  std::cout<<GridLogMessage << "Called Ds"<<std::endl;
 | 
			
		||||
  std::cout<<GridLogMessage << "norm result "<< norm2(result)<<std::endl;
 | 
			
		||||
  std::cout<<GridLogMessage << "norm ref    "<< norm2(ref)<<std::endl;
 | 
			
		||||
  std::cout<<GridLogMessage << "mflop/s =   "<< flops/(t1-t0)<<std::endl;
 | 
			
		||||
  err = ref-result; 
 | 
			
		||||
  std::cout<<GridLogMessage << "norm diff   "<< norm2(err)<<std::endl;
 | 
			
		||||
 | 
			
		||||
  Grid_finalize();
 | 
			
		||||
}
 | 
			
		||||
@@ -35,8 +35,9 @@ using namespace Grid::QCD;
 | 
			
		||||
int main (int argc, char ** argv)
 | 
			
		||||
{
 | 
			
		||||
  Grid_init(&argc,&argv);
 | 
			
		||||
#define LMAX (64)
 | 
			
		||||
 | 
			
		||||
  int Nloop=1000;
 | 
			
		||||
  int Nloop=20;
 | 
			
		||||
 | 
			
		||||
  std::vector<int> simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd());
 | 
			
		||||
  std::vector<int> mpi_layout  = GridDefaultMpi();
 | 
			
		||||
@@ -50,12 +51,12 @@ int main (int argc, char ** argv)
 | 
			
		||||
  std::cout<<GridLogMessage << "  L  "<<"\t\t"<<"bytes"<<"\t\t\t"<<"GB/s\t\t GFlop/s"<<std::endl;
 | 
			
		||||
  std::cout<<GridLogMessage << "----------------------------------------------------------"<<std::endl;
 | 
			
		||||
 | 
			
		||||
  for(int lat=2;lat<=32;lat+=2){
 | 
			
		||||
  for(int lat=2;lat<=LMAX;lat+=2){
 | 
			
		||||
 | 
			
		||||
      std::vector<int> latt_size  ({lat*mpi_layout[0],lat*mpi_layout[1],lat*mpi_layout[2],lat*mpi_layout[3]});
 | 
			
		||||
      int vol = latt_size[0]*latt_size[1]*latt_size[2]*latt_size[3];
 | 
			
		||||
      GridCartesian     Grid(latt_size,simd_layout,mpi_layout);
 | 
			
		||||
      //      GridParallelRNG          pRNG(&Grid);      pRNG.SeedRandomDevice();
 | 
			
		||||
      //      GridParallelRNG          pRNG(&Grid);      pRNG.SeedFixedIntegers(std::vector<int>({45,12,81,9});
 | 
			
		||||
 | 
			
		||||
      LatticeColourMatrix z(&Grid);// random(pRNG,z);
 | 
			
		||||
      LatticeColourMatrix x(&Grid);// random(pRNG,x);
 | 
			
		||||
@@ -82,13 +83,13 @@ int main (int argc, char ** argv)
 | 
			
		||||
  std::cout<<GridLogMessage << "  L  "<<"\t\t"<<"bytes"<<"\t\t\t"<<"GB/s\t\t GFlop/s"<<std::endl;
 | 
			
		||||
  std::cout<<GridLogMessage << "----------------------------------------------------------"<<std::endl;
 | 
			
		||||
 | 
			
		||||
  for(int lat=2;lat<=32;lat+=2){
 | 
			
		||||
  for(int lat=2;lat<=LMAX;lat+=2){
 | 
			
		||||
 | 
			
		||||
      std::vector<int> latt_size  ({lat*mpi_layout[0],lat*mpi_layout[1],lat*mpi_layout[2],lat*mpi_layout[3]});
 | 
			
		||||
      int vol = latt_size[0]*latt_size[1]*latt_size[2]*latt_size[3];
 | 
			
		||||
 | 
			
		||||
      GridCartesian     Grid(latt_size,simd_layout,mpi_layout);
 | 
			
		||||
      //      GridParallelRNG          pRNG(&Grid);      pRNG.SeedRandomDevice();
 | 
			
		||||
      //      GridParallelRNG          pRNG(&Grid);      pRNG.SeedFixedIntegers(std::vector<int>({45,12,81,9});
 | 
			
		||||
 | 
			
		||||
      LatticeColourMatrix z(&Grid); //random(pRNG,z);
 | 
			
		||||
      LatticeColourMatrix x(&Grid); //random(pRNG,x);
 | 
			
		||||
@@ -113,13 +114,13 @@ int main (int argc, char ** argv)
 | 
			
		||||
  std::cout<<GridLogMessage << "  L  "<<"\t\t"<<"bytes"<<"\t\t\t"<<"GB/s\t\t GFlop/s"<<std::endl;
 | 
			
		||||
  std::cout<<GridLogMessage << "----------------------------------------------------------"<<std::endl;
 | 
			
		||||
 | 
			
		||||
  for(int lat=2;lat<=32;lat+=2){
 | 
			
		||||
  for(int lat=2;lat<=LMAX;lat+=2){
 | 
			
		||||
 | 
			
		||||
      std::vector<int> latt_size  ({lat*mpi_layout[0],lat*mpi_layout[1],lat*mpi_layout[2],lat*mpi_layout[3]});
 | 
			
		||||
      int vol = latt_size[0]*latt_size[1]*latt_size[2]*latt_size[3];
 | 
			
		||||
 | 
			
		||||
      GridCartesian     Grid(latt_size,simd_layout,mpi_layout);
 | 
			
		||||
      //      GridParallelRNG          pRNG(&Grid);      pRNG.SeedRandomDevice();
 | 
			
		||||
      //      GridParallelRNG          pRNG(&Grid);      pRNG.SeedFixedIntegers(std::vector<int>({45,12,81,9});
 | 
			
		||||
 | 
			
		||||
      LatticeColourMatrix z(&Grid); //random(pRNG,z);
 | 
			
		||||
      LatticeColourMatrix x(&Grid); //random(pRNG,x);
 | 
			
		||||
@@ -144,13 +145,13 @@ int main (int argc, char ** argv)
 | 
			
		||||
  std::cout<<GridLogMessage << "  L  "<<"\t\t"<<"bytes"<<"\t\t\t"<<"GB/s\t\t GFlop/s"<<std::endl;
 | 
			
		||||
  std::cout<<GridLogMessage << "----------------------------------------------------------"<<std::endl;
 | 
			
		||||
 | 
			
		||||
  for(int lat=2;lat<=32;lat+=2){
 | 
			
		||||
  for(int lat=2;lat<=LMAX;lat+=2){
 | 
			
		||||
 | 
			
		||||
      std::vector<int> latt_size  ({lat*mpi_layout[0],lat*mpi_layout[1],lat*mpi_layout[2],lat*mpi_layout[3]});
 | 
			
		||||
      int vol = latt_size[0]*latt_size[1]*latt_size[2]*latt_size[3];
 | 
			
		||||
 | 
			
		||||
      GridCartesian     Grid(latt_size,simd_layout,mpi_layout);
 | 
			
		||||
      //      GridParallelRNG          pRNG(&Grid);      pRNG.SeedRandomDevice();
 | 
			
		||||
      //      GridParallelRNG          pRNG(&Grid);      pRNG.SeedFixedIntegers(std::vector<int>({45,12,81,9});
 | 
			
		||||
 | 
			
		||||
      LatticeColourMatrix z(&Grid); //random(pRNG,z);
 | 
			
		||||
      LatticeColourMatrix x(&Grid); //random(pRNG,x);
 | 
			
		||||
 
 | 
			
		||||
@@ -37,11 +37,11 @@ struct scal {
 | 
			
		||||
  d internal;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
  Gamma::GammaMatrix Gmu [] = {
 | 
			
		||||
    Gamma::GammaX,
 | 
			
		||||
    Gamma::GammaY,
 | 
			
		||||
    Gamma::GammaZ,
 | 
			
		||||
    Gamma::GammaT
 | 
			
		||||
  Gamma::Algebra Gmu [] = {
 | 
			
		||||
    Gamma::Algebra::GammaX,
 | 
			
		||||
    Gamma::Algebra::GammaY,
 | 
			
		||||
    Gamma::Algebra::GammaZ,
 | 
			
		||||
    Gamma::Algebra::GammaT
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
bool overlapComms = false;
 | 
			
		||||
@@ -69,7 +69,7 @@ int main (int argc, char ** argv)
 | 
			
		||||
  std::vector<int> seeds({1,2,3,4});
 | 
			
		||||
  GridParallelRNG          pRNG(&Grid);
 | 
			
		||||
  pRNG.SeedFixedIntegers(seeds);
 | 
			
		||||
  //  pRNG.SeedRandomDevice();
 | 
			
		||||
  //  pRNG.SeedFixedIntegers(std::vector<int>({45,12,81,9});
 | 
			
		||||
 | 
			
		||||
  LatticeFermion src   (&Grid); random(pRNG,src);
 | 
			
		||||
  LatticeFermion result(&Grid); result=zero;
 | 
			
		||||
@@ -106,7 +106,7 @@ int main (int argc, char ** argv)
 | 
			
		||||
  { // Naive wilson implementation
 | 
			
		||||
    ref = zero;
 | 
			
		||||
    for(int mu=0;mu<Nd;mu++){
 | 
			
		||||
      //    ref =  src + Gamma(Gamma::GammaX)* src ; // 1-gamma_x
 | 
			
		||||
      //    ref =  src + Gamma(Gamma::Algebra::GammaX)* src ; // 1-gamma_x
 | 
			
		||||
      tmp = U[mu]*Cshift(src,mu,1);
 | 
			
		||||
      for(int i=0;i<ref._odata.size();i++){
 | 
			
		||||
	ref._odata[i]+= tmp._odata[i] - Gamma(Gmu[mu])*tmp._odata[i]; ;
 | 
			
		||||
@@ -159,7 +159,7 @@ int main (int argc, char ** argv)
 | 
			
		||||
    ref = zero;
 | 
			
		||||
    for(int mu=0;mu<Nd;mu++){
 | 
			
		||||
 | 
			
		||||
      //    ref =  src - Gamma(Gamma::GammaX)* src ; // 1+gamma_x
 | 
			
		||||
      //    ref =  src - Gamma(Gamma::Algebra::GammaX)* src ; // 1+gamma_x
 | 
			
		||||
      tmp = U[mu]*Cshift(src,mu,1);
 | 
			
		||||
      for(int i=0;i<ref._odata.size();i++){
 | 
			
		||||
	ref._odata[i]+= tmp._odata[i] + Gamma(Gmu[mu])*tmp._odata[i]; ;
 | 
			
		||||
 
 | 
			
		||||
@@ -30,11 +30,11 @@ struct scal {
 | 
			
		||||
  d internal;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Gamma::GammaMatrix Gmu [] = {
 | 
			
		||||
  Gamma::GammaX,
 | 
			
		||||
  Gamma::GammaY,
 | 
			
		||||
  Gamma::GammaZ,
 | 
			
		||||
  Gamma::GammaT
 | 
			
		||||
Gamma::Algebra Gmu [] = {
 | 
			
		||||
    Gamma::Algebra::GammaX,
 | 
			
		||||
    Gamma::Algebra::GammaY,
 | 
			
		||||
    Gamma::Algebra::GammaZ,
 | 
			
		||||
    Gamma::Algebra::GammaT
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
bool overlapComms = false;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,7 @@
 | 
			
		||||
include Make.inc
 | 
			
		||||
 | 
			
		||||
simple: simple_su3_test.o simple_su3_expr.o simple_simd_test.o
 | 
			
		||||
 | 
			
		||||
EXTRA_LIBRARIES = libsimple_su3_test.a libsimple_su3_expr.a libsimple_simd_test.a
 | 
			
		||||
 | 
			
		||||
libsimple_su3_test_a_SOURCES = simple_su3_test.cc
 | 
			
		||||
 | 
			
		||||
libsimple_su3_expr_a_SOURCES = simple_su3_expr.cc
 | 
			
		||||
 | 
			
		||||
libsimple_simd_test_a_SOURCES = simple_simd_test.cc
 | 
			
		||||
bench-local: all
 | 
			
		||||
	./Benchmark_su3
 | 
			
		||||
	./Benchmark_memory_bandwidth
 | 
			
		||||
	./Benchmark_wilson
 | 
			
		||||
	./Benchmark_dwf --dslash-unroll
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
#!/usr/bin/env bash
 | 
			
		||||
 | 
			
		||||
EIGEN_URL='http://bitbucket.org/eigen/eigen/get/3.2.9.tar.bz2'
 | 
			
		||||
EIGEN_URL='http://bitbucket.org/eigen/eigen/get/3.3.3.tar.bz2'
 | 
			
		||||
 | 
			
		||||
echo "-- deploying Eigen source..."
 | 
			
		||||
wget ${EIGEN_URL} --no-check-certificate
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										172
									
								
								configure.ac
									
									
									
									
									
								
							
							
						
						
									
										172
									
								
								configure.ac
									
									
									
									
									
								
							@@ -1,16 +1,19 @@
 | 
			
		||||
AC_PREREQ([2.63])
 | 
			
		||||
AC_INIT([Grid], [0.6.0], [https://github.com/paboyle/Grid], [Grid])
 | 
			
		||||
AC_INIT([Grid], [0.7.0], [https://github.com/paboyle/Grid], [Grid])
 | 
			
		||||
AC_CANONICAL_BUILD
 | 
			
		||||
AC_CANONICAL_HOST
 | 
			
		||||
AC_CANONICAL_TARGET
 | 
			
		||||
AM_INIT_AUTOMAKE(subdir-objects)
 | 
			
		||||
AM_INIT_AUTOMAKE([subdir-objects 1.13])
 | 
			
		||||
AM_EXTRA_RECURSIVE_TARGETS([tests bench])
 | 
			
		||||
AC_CONFIG_MACRO_DIR([m4])
 | 
			
		||||
AC_CONFIG_SRCDIR([lib/Grid.h])
 | 
			
		||||
AC_CONFIG_HEADERS([lib/Config.h])
 | 
			
		||||
AC_CONFIG_HEADERS([lib/Config.h],[sed -i 's|PACKAGE_|GRID_|' lib/Config.h])
 | 
			
		||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
 | 
			
		||||
 | 
			
		||||
################ Get git info
 | 
			
		||||
#AC_REVISION([m4_esyscmd_s([./scripts/configure.commit])])
 | 
			
		||||
 | 
			
		||||
############### Checks for programs
 | 
			
		||||
CXXFLAGS="-O3 $CXXFLAGS"
 | 
			
		||||
AC_PROG_CXX
 | 
			
		||||
AC_PROG_RANLIB
 | 
			
		||||
 | 
			
		||||
@@ -24,12 +27,15 @@ AX_GXX_VERSION
 | 
			
		||||
AC_DEFINE_UNQUOTED([GXX_VERSION],["$GXX_VERSION"],
 | 
			
		||||
      [version of g++ that will compile the code])
 | 
			
		||||
 | 
			
		||||
CXXFLAGS="-g $CXXFLAGS"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
############### Checks for typedefs, structures, and compiler characteristics
 | 
			
		||||
AC_TYPE_SIZE_T
 | 
			
		||||
AC_TYPE_UINT32_T
 | 
			
		||||
AC_TYPE_UINT64_T
 | 
			
		||||
 | 
			
		||||
############### OpenMP 
 | 
			
		||||
############### OpenMP
 | 
			
		||||
AC_OPENMP
 | 
			
		||||
ac_openmp=no
 | 
			
		||||
if test "${OPENMP_CXXFLAGS}X" != "X"; then
 | 
			
		||||
@@ -60,16 +66,23 @@ AC_ARG_WITH([mpfr],
 | 
			
		||||
    [AM_CXXFLAGS="-I$with_mpfr/include $AM_CXXFLAGS"]
 | 
			
		||||
    [AM_LDFLAGS="-L$with_mpfr/lib $AM_LDFLAGS"])
 | 
			
		||||
 | 
			
		||||
############### FFTW3 
 | 
			
		||||
AC_ARG_WITH([fftw],    
 | 
			
		||||
############### FFTW3
 | 
			
		||||
AC_ARG_WITH([fftw],
 | 
			
		||||
            [AS_HELP_STRING([--with-fftw=prefix],
 | 
			
		||||
            [try this for a non-standard install prefix of the FFTW3 library])],
 | 
			
		||||
            [AM_CXXFLAGS="-I$with_fftw/include $AM_CXXFLAGS"]
 | 
			
		||||
            [AM_LDFLAGS="-L$with_fftw/lib $AM_LDFLAGS"])
 | 
			
		||||
 | 
			
		||||
############### lapack 
 | 
			
		||||
############### LIME
 | 
			
		||||
AC_ARG_WITH([lime],
 | 
			
		||||
            [AS_HELP_STRING([--with-lime=prefix],
 | 
			
		||||
            [try this for a non-standard install prefix of the LIME library])],
 | 
			
		||||
            [AM_CXXFLAGS="-I$with_lime/include $AM_CXXFLAGS"]
 | 
			
		||||
            [AM_LDFLAGS="-L$with_lime/lib $AM_LDFLAGS"])
 | 
			
		||||
 | 
			
		||||
############### lapack
 | 
			
		||||
AC_ARG_ENABLE([lapack],
 | 
			
		||||
    [AC_HELP_STRING([--enable-lapack=yes|no|prefix], [enable LAPACK])], 
 | 
			
		||||
    [AC_HELP_STRING([--enable-lapack=yes|no|prefix], [enable LAPACK])],
 | 
			
		||||
    [ac_LAPACK=${enable_lapack}], [ac_LAPACK=no])
 | 
			
		||||
 | 
			
		||||
case ${ac_LAPACK} in
 | 
			
		||||
@@ -83,6 +96,18 @@ case ${ac_LAPACK} in
 | 
			
		||||
        AC_DEFINE([USE_LAPACK],[1],[use LAPACK]);;
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
############### FP16 conversions
 | 
			
		||||
AC_ARG_ENABLE([sfw-fp16],
 | 
			
		||||
    [AC_HELP_STRING([--enable-sfw-fp16=yes|no], [enable software fp16 comms])],
 | 
			
		||||
    [ac_SFW_FP16=${enable_sfw_fp16}], [ac_SFW_FP16=yes])
 | 
			
		||||
case ${ac_SFW_FP16} in
 | 
			
		||||
    yes)
 | 
			
		||||
      AC_DEFINE([SFW_FP16],[1],[software conversion to fp16]);;
 | 
			
		||||
    no);;
 | 
			
		||||
    *)
 | 
			
		||||
      AC_MSG_ERROR(["SFW FP16 option not supported ${ac_SFW_FP16}"]);;
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
############### MKL
 | 
			
		||||
AC_ARG_ENABLE([mkl],
 | 
			
		||||
    [AC_HELP_STRING([--enable-mkl=yes|no|prefix], [enable Intel MKL for LAPACK & FFTW])],
 | 
			
		||||
@@ -99,9 +124,16 @@ case ${ac_MKL} in
 | 
			
		||||
        AC_DEFINE([USE_MKL], [1], [Define to 1 if you use the Intel MKL]);;
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
############### HDF5
 | 
			
		||||
AC_ARG_WITH([hdf5],
 | 
			
		||||
    [AS_HELP_STRING([--with-hdf5=prefix],
 | 
			
		||||
    [try this for a non-standard install prefix of the HDF5 library])],
 | 
			
		||||
    [AM_CXXFLAGS="-I$with_hdf5/include $AM_CXXFLAGS"]
 | 
			
		||||
    [AM_LDFLAGS="-L$with_hdf5/lib $AM_LDFLAGS"])
 | 
			
		||||
 | 
			
		||||
############### first-touch
 | 
			
		||||
AC_ARG_ENABLE([numa],
 | 
			
		||||
    [AC_HELP_STRING([--enable-numa=yes|no|prefix], [enable first touch numa opt])], 
 | 
			
		||||
    [AC_HELP_STRING([--enable-numa=yes|no|prefix], [enable first touch numa opt])],
 | 
			
		||||
    [ac_NUMA=${enable_NUMA}],[ac_NUMA=no])
 | 
			
		||||
 | 
			
		||||
case ${ac_NUMA} in
 | 
			
		||||
@@ -127,8 +159,8 @@ if test "${ac_MKL}x" != "nox"; then
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
AC_SEARCH_LIBS([__gmpf_init], [gmp],
 | 
			
		||||
               [AC_SEARCH_LIBS([mpfr_init], [mpfr], 
 | 
			
		||||
                               [AC_DEFINE([HAVE_LIBMPFR], [1], 
 | 
			
		||||
               [AC_SEARCH_LIBS([mpfr_init], [mpfr],
 | 
			
		||||
                               [AC_DEFINE([HAVE_LIBMPFR], [1],
 | 
			
		||||
                                          [Define to 1 if you have the `MPFR' library])]
 | 
			
		||||
                               [have_mpfr=true], [AC_MSG_ERROR([MPFR library not found])])]
 | 
			
		||||
               [AC_DEFINE([HAVE_LIBGMP], [1], [Define to 1 if you have the `GMP' library])]
 | 
			
		||||
@@ -137,7 +169,7 @@ AC_SEARCH_LIBS([__gmpf_init], [gmp],
 | 
			
		||||
if test "${ac_LAPACK}x" != "nox"; then
 | 
			
		||||
    AC_SEARCH_LIBS([LAPACKE_sbdsdc], [lapack], [],
 | 
			
		||||
                   [AC_MSG_ERROR("LAPACK enabled but library not found")])
 | 
			
		||||
fi   
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
AC_SEARCH_LIBS([fftw_execute], [fftw3],
 | 
			
		||||
               [AC_SEARCH_LIBS([fftwf_execute], [fftw3f], [],
 | 
			
		||||
@@ -145,6 +177,24 @@ AC_SEARCH_LIBS([fftw_execute], [fftw3],
 | 
			
		||||
               [AC_DEFINE([HAVE_FFTW], [1], [Define to 1 if you have the `FFTW' library])]
 | 
			
		||||
               [have_fftw=true])
 | 
			
		||||
 | 
			
		||||
AC_SEARCH_LIBS([limeCreateReader], [lime],
 | 
			
		||||
               [AC_DEFINE([HAVE_LIME], [1], [Define to 1 if you have the `LIME' library])]
 | 
			
		||||
               [have_lime=true],
 | 
			
		||||
	       [AC_MSG_WARN(C-LIME library was not found in your system.
 | 
			
		||||
In order to use ILGG file format please install or provide the correct path to your installation
 | 
			
		||||
Info at: http://usqcd.jlab.org/usqcd-docs/c-lime/)])
 | 
			
		||||
 | 
			
		||||
AC_SEARCH_LIBS([crc32], [z],
 | 
			
		||||
               [AC_DEFINE([HAVE_ZLIB], [1], [Define to 1 if you have the `LIBZ' library])]
 | 
			
		||||
               [have_zlib=true],
 | 
			
		||||
	       [AC_MSG_ERROR(zlib library was not found in your system.)])
 | 
			
		||||
 | 
			
		||||
AC_SEARCH_LIBS([H5Fopen], [hdf5_cpp],
 | 
			
		||||
               [AC_DEFINE([HAVE_HDF5], [1], [Define to 1 if you have the `HDF5' library])]
 | 
			
		||||
               [have_hdf5=true]
 | 
			
		||||
               [LIBS="${LIBS} -lhdf5"], [], [-lhdf5])
 | 
			
		||||
AM_CONDITIONAL(BUILD_HDF5, [ test "${have_hdf5}X" == "trueX" ])
 | 
			
		||||
 | 
			
		||||
CXXFLAGS=$CXXFLAGS_CPY
 | 
			
		||||
LDFLAGS=$LDFLAGS_CPY
 | 
			
		||||
 | 
			
		||||
@@ -163,19 +213,26 @@ case ${ax_cv_cxx_compiler_vendor} in
 | 
			
		||||
    case ${ac_SIMD} in
 | 
			
		||||
      SSE4)
 | 
			
		||||
        AC_DEFINE([SSE4],[1],[SSE4 intrinsics])
 | 
			
		||||
        SIMD_FLAGS='-msse4.2';;
 | 
			
		||||
	case ${ac_SFW_FP16} in
 | 
			
		||||
	  yes)
 | 
			
		||||
	  SIMD_FLAGS='-msse4.2';;
 | 
			
		||||
	  no)
 | 
			
		||||
	  SIMD_FLAGS='-msse4.2 -mf16c';;
 | 
			
		||||
	  *)
 | 
			
		||||
          AC_MSG_ERROR(["SFW_FP16 must be either yes or no value ${ac_SFW_FP16} "]);;
 | 
			
		||||
	esac;;
 | 
			
		||||
      AVX)
 | 
			
		||||
        AC_DEFINE([AVX1],[1],[AVX intrinsics])
 | 
			
		||||
        SIMD_FLAGS='-mavx';;
 | 
			
		||||
        SIMD_FLAGS='-mavx -mf16c';;
 | 
			
		||||
      AVXFMA4)
 | 
			
		||||
        AC_DEFINE([AVXFMA4],[1],[AVX intrinsics with FMA4])
 | 
			
		||||
        SIMD_FLAGS='-mavx -mfma4';;
 | 
			
		||||
        SIMD_FLAGS='-mavx -mfma4 -mf16c';;
 | 
			
		||||
      AVXFMA)
 | 
			
		||||
        AC_DEFINE([AVXFMA],[1],[AVX intrinsics with FMA3])
 | 
			
		||||
        SIMD_FLAGS='-mavx -mfma';;
 | 
			
		||||
        SIMD_FLAGS='-mavx -mfma -mf16c';;
 | 
			
		||||
      AVX2)
 | 
			
		||||
        AC_DEFINE([AVX2],[1],[AVX2 intrinsics])
 | 
			
		||||
        SIMD_FLAGS='-mavx2 -mfma';;
 | 
			
		||||
        SIMD_FLAGS='-mavx2 -mfma -mf16c';;
 | 
			
		||||
      AVX512)
 | 
			
		||||
        AC_DEFINE([AVX512],[1],[AVX512 intrinsics])
 | 
			
		||||
        SIMD_FLAGS='-mavx512f -mavx512pf -mavx512er -mavx512cd';;
 | 
			
		||||
@@ -284,7 +341,7 @@ case ${ac_COMMS} in
 | 
			
		||||
        comms_type='shmem'
 | 
			
		||||
     ;;
 | 
			
		||||
     *)
 | 
			
		||||
        AC_MSG_ERROR([${ac_COMMS} unsupported --enable-comms option]); 
 | 
			
		||||
        AC_MSG_ERROR([${ac_COMMS} unsupported --enable-comms option]);
 | 
			
		||||
     ;;
 | 
			
		||||
esac
 | 
			
		||||
case ${ac_COMMS} in
 | 
			
		||||
@@ -306,9 +363,9 @@ AM_CONDITIONAL(BUILD_COMMS_MPI3L, [ test "${comms_type}X" == "mpi3lX" ] )
 | 
			
		||||
AM_CONDITIONAL(BUILD_COMMS_NONE,  [ test "${comms_type}X" == "noneX" ])
 | 
			
		||||
 | 
			
		||||
############### RNG selection
 | 
			
		||||
AC_ARG_ENABLE([rng],[AC_HELP_STRING([--enable-rng=ranlux48|mt19937],\
 | 
			
		||||
AC_ARG_ENABLE([rng],[AC_HELP_STRING([--enable-rng=ranlux48|mt19937|sitmo],\
 | 
			
		||||
	            [Select Random Number Generator to be used])],\
 | 
			
		||||
	            [ac_RNG=${enable_rng}],[ac_RNG=ranlux48])
 | 
			
		||||
	            [ac_RNG=${enable_rng}],[ac_RNG=sitmo])
 | 
			
		||||
 | 
			
		||||
case ${ac_RNG} in
 | 
			
		||||
     ranlux48)
 | 
			
		||||
@@ -317,8 +374,11 @@ case ${ac_RNG} in
 | 
			
		||||
     mt19937)
 | 
			
		||||
      AC_DEFINE([RNG_MT19937],[1],[RNG_MT19937] )
 | 
			
		||||
     ;;
 | 
			
		||||
     sitmo)
 | 
			
		||||
      AC_DEFINE([RNG_SITMO],[1],[RNG_SITMO] )
 | 
			
		||||
     ;;
 | 
			
		||||
     *)
 | 
			
		||||
      AC_MSG_ERROR([${ac_RNG} unsupported --enable-rng option]); 
 | 
			
		||||
      AC_MSG_ERROR([${ac_RNG} unsupported --enable-rng option]);
 | 
			
		||||
     ;;
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
@@ -335,7 +395,7 @@ case ${ac_TIMERS} in
 | 
			
		||||
      AC_DEFINE([TIMERS_OFF],[1],[TIMERS_OFF] )
 | 
			
		||||
     ;;
 | 
			
		||||
     *)
 | 
			
		||||
      AC_MSG_ERROR([${ac_TIMERS} unsupported --enable-timers option]); 
 | 
			
		||||
      AC_MSG_ERROR([${ac_TIMERS} unsupported --enable-timers option]);
 | 
			
		||||
     ;;
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
@@ -347,7 +407,7 @@ case ${ac_CHROMA} in
 | 
			
		||||
     yes|no)
 | 
			
		||||
     ;;
 | 
			
		||||
     *)
 | 
			
		||||
       AC_MSG_ERROR([${ac_CHROMA} unsupported --enable-chroma option]); 
 | 
			
		||||
       AC_MSG_ERROR([${ac_CHROMA} unsupported --enable-chroma option]);
 | 
			
		||||
     ;;
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
@@ -368,29 +428,31 @@ DX_INIT_DOXYGEN([$PACKAGE_NAME], [doxygen.cfg])
 | 
			
		||||
 | 
			
		||||
############### Ouput
 | 
			
		||||
cwd=`pwd -P`; cd ${srcdir}; abs_srcdir=`pwd -P`; cd ${cwd}
 | 
			
		||||
GRID_CXXFLAGS="$AM_CXXFLAGS $CXXFLAGS"
 | 
			
		||||
GRID_LDFLAGS="$AM_LDFLAGS $LDFLAGS"
 | 
			
		||||
GRID_LIBS=$LIBS
 | 
			
		||||
GRID_SHORT_SHA=`git rev-parse --short HEAD`
 | 
			
		||||
GRID_SHA=`git rev-parse HEAD`
 | 
			
		||||
GRID_BRANCH=`git rev-parse --abbrev-ref HEAD`
 | 
			
		||||
AM_CXXFLAGS="-I${abs_srcdir}/include $AM_CXXFLAGS"
 | 
			
		||||
AM_CFLAGS="-I${abs_srcdir}/include $AM_CFLAGS"
 | 
			
		||||
AM_LDFLAGS="-L${cwd}/lib $AM_LDFLAGS"
 | 
			
		||||
AC_SUBST([AM_CFLAGS])
 | 
			
		||||
AC_SUBST([AM_CXXFLAGS])
 | 
			
		||||
AC_SUBST([AM_LDFLAGS])
 | 
			
		||||
AC_CONFIG_FILES(Makefile)
 | 
			
		||||
AC_CONFIG_FILES(lib/Makefile)
 | 
			
		||||
AC_CONFIG_FILES(tests/Makefile)
 | 
			
		||||
AC_CONFIG_FILES(tests/IO/Makefile)
 | 
			
		||||
AC_CONFIG_FILES(tests/core/Makefile)
 | 
			
		||||
AC_CONFIG_FILES(tests/debug/Makefile)
 | 
			
		||||
AC_CONFIG_FILES(tests/forces/Makefile)
 | 
			
		||||
AC_CONFIG_FILES(tests/hmc/Makefile)
 | 
			
		||||
AC_CONFIG_FILES(tests/solver/Makefile)
 | 
			
		||||
AC_CONFIG_FILES(tests/qdpxx/Makefile)
 | 
			
		||||
AC_CONFIG_FILES(benchmarks/Makefile)
 | 
			
		||||
AC_OUTPUT
 | 
			
		||||
AC_SUBST([GRID_CXXFLAGS])
 | 
			
		||||
AC_SUBST([GRID_LDFLAGS])
 | 
			
		||||
AC_SUBST([GRID_LIBS])
 | 
			
		||||
AC_SUBST([GRID_SHA])
 | 
			
		||||
AC_SUBST([GRID_BRANCH])
 | 
			
		||||
 | 
			
		||||
git_commit=`cd $srcdir && ./scripts/configure.commit`
 | 
			
		||||
 | 
			
		||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
Summary of configuration for $PACKAGE v$VERSION
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
----- GIT VERSION -------------------------------------
 | 
			
		||||
$git_commit
 | 
			
		||||
----- PLATFORM ----------------------------------------
 | 
			
		||||
architecture (build)        : $build_cpu
 | 
			
		||||
os (build)                  : $build_os
 | 
			
		||||
@@ -400,13 +462,16 @@ compiler vendor             : ${ax_cv_cxx_compiler_vendor}
 | 
			
		||||
compiler version            : ${ax_cv_gxx_version}
 | 
			
		||||
----- BUILD OPTIONS -----------------------------------
 | 
			
		||||
SIMD                        : ${ac_SIMD}${SIMD_GEN_WIDTH_MSG}
 | 
			
		||||
Threading                   : ${ac_openmp} 
 | 
			
		||||
Threading                   : ${ac_openmp}
 | 
			
		||||
Communications type         : ${comms_type}
 | 
			
		||||
Default precision           : ${ac_PRECISION}
 | 
			
		||||
RNG choice                  : ${ac_RNG} 
 | 
			
		||||
Software FP16 conversion    : ${ac_SFW_FP16}
 | 
			
		||||
RNG choice                  : ${ac_RNG}
 | 
			
		||||
GMP                         : `if test "x$have_gmp" = xtrue; then echo yes; else echo no; fi`
 | 
			
		||||
LAPACK                      : ${ac_LAPACK}
 | 
			
		||||
FFTW                        : `if test "x$have_fftw" = xtrue; then echo yes; else echo no; fi`
 | 
			
		||||
LIME (ILDG support)         : `if test "x$have_lime" = xtrue; then echo yes; else echo no; fi`
 | 
			
		||||
HDF5                        : `if test "x$have_hdf5" = xtrue; then echo yes; else echo no; fi`
 | 
			
		||||
build DOXYGEN documentation : `if test "$DX_FLAG_doc" = '1'; then echo yes; else echo no; fi`
 | 
			
		||||
----- BUILD FLAGS -------------------------------------
 | 
			
		||||
CXXFLAGS:
 | 
			
		||||
@@ -415,7 +480,32 @@ LDFLAGS:
 | 
			
		||||
`echo ${AM_LDFLAGS} ${LDFLAGS} | tr ' ' '\n' | sed 's/^-/    -/g'`
 | 
			
		||||
LIBS:
 | 
			
		||||
`echo ${LIBS} | tr ' ' '\n' | sed 's/^-/    -/g'`
 | 
			
		||||
-------------------------------------------------------" > config.summary
 | 
			
		||||
-------------------------------------------------------" > grid.configure.summary
 | 
			
		||||
 | 
			
		||||
GRID_SUMMARY="`cat grid.configure.summary`"
 | 
			
		||||
AM_SUBST_NOTMAKE([GRID_SUMMARY])
 | 
			
		||||
AC_SUBST([GRID_SUMMARY])
 | 
			
		||||
 | 
			
		||||
AC_CONFIG_FILES([grid-config], [chmod +x grid-config])
 | 
			
		||||
AC_CONFIG_FILES(Makefile)
 | 
			
		||||
AC_CONFIG_FILES(lib/Makefile)
 | 
			
		||||
AC_CONFIG_FILES(tests/Makefile)
 | 
			
		||||
AC_CONFIG_FILES(tests/IO/Makefile)
 | 
			
		||||
AC_CONFIG_FILES(tests/core/Makefile)
 | 
			
		||||
AC_CONFIG_FILES(tests/debug/Makefile)
 | 
			
		||||
AC_CONFIG_FILES(tests/forces/Makefile)
 | 
			
		||||
AC_CONFIG_FILES(tests/hadrons/Makefile)
 | 
			
		||||
AC_CONFIG_FILES(tests/hmc/Makefile)
 | 
			
		||||
AC_CONFIG_FILES(tests/solver/Makefile)
 | 
			
		||||
AC_CONFIG_FILES(tests/smearing/Makefile)
 | 
			
		||||
AC_CONFIG_FILES(tests/qdpxx/Makefile)
 | 
			
		||||
AC_CONFIG_FILES(tests/testu01/Makefile)
 | 
			
		||||
AC_CONFIG_FILES(benchmarks/Makefile)
 | 
			
		||||
AC_CONFIG_FILES(extras/Makefile)
 | 
			
		||||
AC_CONFIG_FILES(extras/Hadrons/Makefile)
 | 
			
		||||
AC_OUTPUT
 | 
			
		||||
 | 
			
		||||
echo ""
 | 
			
		||||
cat config.summary
 | 
			
		||||
cat grid.configure.summary
 | 
			
		||||
echo ""
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										318
									
								
								extras/Hadrons/Application.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										318
									
								
								extras/Hadrons/Application.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,318 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
Source file: extras/Hadrons/Application.cc
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2015
 | 
			
		||||
Copyright (C) 2016
 | 
			
		||||
 | 
			
		||||
Author: Antonin Portelli <antonin.portelli@me.com>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
 | 
			
		||||
#include <Grid/Hadrons/Application.hpp>
 | 
			
		||||
#include <Grid/Hadrons/GeneticScheduler.hpp>
 | 
			
		||||
 | 
			
		||||
using namespace Grid;
 | 
			
		||||
using namespace QCD;
 | 
			
		||||
using namespace Hadrons;
 | 
			
		||||
 | 
			
		||||
#define BIG_SEP "==============="
 | 
			
		||||
#define SEP     "---------------"
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                       Application implementation                           *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
// constructors ////////////////////////////////////////////////////////////////
 | 
			
		||||
Application::Application(void)
 | 
			
		||||
{
 | 
			
		||||
    LOG(Message) << "Modules available:" << std::endl;
 | 
			
		||||
    auto list = ModuleFactory::getInstance().getBuilderList();
 | 
			
		||||
    for (auto &m: list)
 | 
			
		||||
    {
 | 
			
		||||
        LOG(Message) << "  " << m << std::endl;
 | 
			
		||||
    }
 | 
			
		||||
    auto dim = GridDefaultLatt(), mpi = GridDefaultMpi(), loc(dim);
 | 
			
		||||
    locVol_ = 1;
 | 
			
		||||
    for (unsigned int d = 0; d < dim.size(); ++d)
 | 
			
		||||
    {
 | 
			
		||||
        loc[d]  /= mpi[d];
 | 
			
		||||
        locVol_ *= loc[d];
 | 
			
		||||
    }
 | 
			
		||||
    LOG(Message) << "Global lattice: " << dim << std::endl;
 | 
			
		||||
    LOG(Message) << "MPI partition : " << mpi << std::endl;
 | 
			
		||||
    LOG(Message) << "Local lattice : " << loc << std::endl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Application::Application(const Application::GlobalPar &par)
 | 
			
		||||
: Application()
 | 
			
		||||
{
 | 
			
		||||
    setPar(par);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Application::Application(const std::string parameterFileName)
 | 
			
		||||
: Application()
 | 
			
		||||
{
 | 
			
		||||
    parameterFileName_ = parameterFileName;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// environment shortcut ////////////////////////////////////////////////////////
 | 
			
		||||
Environment & Application::env(void) const
 | 
			
		||||
{
 | 
			
		||||
    return Environment::getInstance();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// access //////////////////////////////////////////////////////////////////////
 | 
			
		||||
void Application::setPar(const Application::GlobalPar &par)
 | 
			
		||||
{
 | 
			
		||||
    par_ = par;
 | 
			
		||||
    env().setSeed(strToVec<int>(par_.seed));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const Application::GlobalPar & Application::getPar(void)
 | 
			
		||||
{
 | 
			
		||||
    return par_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// execute /////////////////////////////////////////////////////////////////////
 | 
			
		||||
void Application::run(void)
 | 
			
		||||
{
 | 
			
		||||
    if (!parameterFileName_.empty() and (env().getNModule() == 0))
 | 
			
		||||
    {
 | 
			
		||||
        parseParameterFile(parameterFileName_);
 | 
			
		||||
    }
 | 
			
		||||
    if (!scheduled_)
 | 
			
		||||
    {
 | 
			
		||||
        schedule();
 | 
			
		||||
    }
 | 
			
		||||
    printSchedule();
 | 
			
		||||
    configLoop();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// parse parameter file ////////////////////////////////////////////////////////
 | 
			
		||||
class ObjectId: Serializable
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    GRID_SERIALIZABLE_CLASS_MEMBERS(ObjectId,
 | 
			
		||||
                                    std::string, name,
 | 
			
		||||
                                    std::string, type);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void Application::parseParameterFile(const std::string parameterFileName)
 | 
			
		||||
{
 | 
			
		||||
    XmlReader reader(parameterFileName);
 | 
			
		||||
    GlobalPar par;
 | 
			
		||||
    ObjectId  id;
 | 
			
		||||
    
 | 
			
		||||
    LOG(Message) << "Building application from '" << parameterFileName << "'..." << std::endl;
 | 
			
		||||
    read(reader, "parameters", par);
 | 
			
		||||
    setPar(par);
 | 
			
		||||
    push(reader, "modules");
 | 
			
		||||
    push(reader, "module");
 | 
			
		||||
    do
 | 
			
		||||
    {
 | 
			
		||||
        read(reader, "id", id);
 | 
			
		||||
        env().createModule(id.name, id.type, reader);
 | 
			
		||||
    } while (reader.nextElement("module"));
 | 
			
		||||
    pop(reader);
 | 
			
		||||
    pop(reader);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Application::saveParameterFile(const std::string parameterFileName)
 | 
			
		||||
{
 | 
			
		||||
    XmlWriter          writer(parameterFileName);
 | 
			
		||||
    ObjectId           id;
 | 
			
		||||
    const unsigned int nMod = env().getNModule();
 | 
			
		||||
    
 | 
			
		||||
    LOG(Message) << "Saving application to '" << parameterFileName << "'..." << std::endl;
 | 
			
		||||
    write(writer, "parameters", getPar());
 | 
			
		||||
    push(writer, "modules");
 | 
			
		||||
    for (unsigned int i = 0; i < nMod; ++i)
 | 
			
		||||
    {
 | 
			
		||||
        push(writer, "module");
 | 
			
		||||
        id.name = env().getModuleName(i);
 | 
			
		||||
        id.type = env().getModule(i)->getRegisteredName();
 | 
			
		||||
        write(writer, "id", id);
 | 
			
		||||
        env().getModule(i)->saveParameters(writer, "options");
 | 
			
		||||
        pop(writer);
 | 
			
		||||
    }
 | 
			
		||||
    pop(writer);
 | 
			
		||||
    pop(writer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// schedule computation ////////////////////////////////////////////////////////
 | 
			
		||||
#define MEM_MSG(size)\
 | 
			
		||||
sizeString((size)*locVol_) << " (" << sizeString(size)  << "/site)"
 | 
			
		||||
 | 
			
		||||
#define DEFINE_MEMPEAK \
 | 
			
		||||
GeneticScheduler<unsigned int>::ObjFunc memPeak = \
 | 
			
		||||
[this](const std::vector<unsigned int> &program)\
 | 
			
		||||
{\
 | 
			
		||||
    unsigned int memPeak;\
 | 
			
		||||
    bool         msg;\
 | 
			
		||||
    \
 | 
			
		||||
    msg = HadronsLogMessage.isActive();\
 | 
			
		||||
    HadronsLogMessage.Active(false);\
 | 
			
		||||
    env().dryRun(true);\
 | 
			
		||||
    memPeak = env().executeProgram(program);\
 | 
			
		||||
    env().dryRun(false);\
 | 
			
		||||
    env().freeAll();\
 | 
			
		||||
    HadronsLogMessage.Active(true);\
 | 
			
		||||
    \
 | 
			
		||||
    return memPeak;\
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Application::schedule(void)
 | 
			
		||||
{
 | 
			
		||||
    DEFINE_MEMPEAK;
 | 
			
		||||
    
 | 
			
		||||
    // build module dependency graph
 | 
			
		||||
    LOG(Message) << "Building module graph..." << std::endl;
 | 
			
		||||
    auto graph = env().makeModuleGraph();
 | 
			
		||||
    auto con = graph.getConnectedComponents();
 | 
			
		||||
    
 | 
			
		||||
    // constrained topological sort using a genetic algorithm
 | 
			
		||||
    LOG(Message) << "Scheduling computation..." << std::endl;
 | 
			
		||||
    LOG(Message) << "               #module= " << graph.size() << std::endl;
 | 
			
		||||
    LOG(Message) << "       population size= " << par_.genetic.popSize << std::endl;
 | 
			
		||||
    LOG(Message) << "       max. generation= " << par_.genetic.maxGen << std::endl;
 | 
			
		||||
    LOG(Message) << "  max. cst. generation= " << par_.genetic.maxCstGen << std::endl;
 | 
			
		||||
    LOG(Message) << "         mutation rate= " << par_.genetic.mutationRate << std::endl;
 | 
			
		||||
    
 | 
			
		||||
    unsigned int                               k = 0, gen, prevPeak, nCstPeak = 0;
 | 
			
		||||
    std::random_device                         rd;
 | 
			
		||||
    GeneticScheduler<unsigned int>::Parameters par;
 | 
			
		||||
    
 | 
			
		||||
    par.popSize      = par_.genetic.popSize;
 | 
			
		||||
    par.mutationRate = par_.genetic.mutationRate;
 | 
			
		||||
    par.seed         = rd();
 | 
			
		||||
    memPeak_         = 0;
 | 
			
		||||
    CartesianCommunicator::BroadcastWorld(0, &(par.seed), sizeof(par.seed));
 | 
			
		||||
    for (unsigned int i = 0; i < con.size(); ++i)
 | 
			
		||||
    {
 | 
			
		||||
        GeneticScheduler<unsigned int> scheduler(con[i], memPeak, par);
 | 
			
		||||
        
 | 
			
		||||
        gen = 0;
 | 
			
		||||
        do
 | 
			
		||||
        {
 | 
			
		||||
            LOG(Debug) << "Generation " << gen << ":" << std::endl;
 | 
			
		||||
            scheduler.nextGeneration();
 | 
			
		||||
            if (gen != 0)
 | 
			
		||||
            {
 | 
			
		||||
                if (prevPeak == scheduler.getMinValue())
 | 
			
		||||
                {
 | 
			
		||||
                    nCstPeak++;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    nCstPeak = 0;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            prevPeak = scheduler.getMinValue();
 | 
			
		||||
            if (gen % 10 == 0)
 | 
			
		||||
            {
 | 
			
		||||
                LOG(Iterative) << "Generation " << gen << ": "
 | 
			
		||||
                               << MEM_MSG(scheduler.getMinValue()) << std::endl;
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            gen++;
 | 
			
		||||
        } while ((gen < par_.genetic.maxGen)
 | 
			
		||||
                 and (nCstPeak < par_.genetic.maxCstGen));
 | 
			
		||||
        auto &t = scheduler.getMinSchedule();
 | 
			
		||||
        if (scheduler.getMinValue() > memPeak_)
 | 
			
		||||
        {
 | 
			
		||||
            memPeak_ = scheduler.getMinValue();
 | 
			
		||||
        }
 | 
			
		||||
        for (unsigned int j = 0; j < t.size(); ++j)
 | 
			
		||||
        {
 | 
			
		||||
            program_.push_back(t[j]);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    scheduled_ = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Application::saveSchedule(const std::string filename)
 | 
			
		||||
{
 | 
			
		||||
    TextWriter               writer(filename);
 | 
			
		||||
    std::vector<std::string> program;
 | 
			
		||||
    
 | 
			
		||||
    if (!scheduled_)
 | 
			
		||||
    {
 | 
			
		||||
        HADRON_ERROR("Computation not scheduled");
 | 
			
		||||
    }
 | 
			
		||||
    LOG(Message) << "Saving current schedule to '" << filename << "'..."
 | 
			
		||||
                 << std::endl;
 | 
			
		||||
    for (auto address: program_)
 | 
			
		||||
    {
 | 
			
		||||
        program.push_back(env().getModuleName(address));
 | 
			
		||||
    }
 | 
			
		||||
    write(writer, "schedule", program);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Application::loadSchedule(const std::string filename)
 | 
			
		||||
{
 | 
			
		||||
    DEFINE_MEMPEAK;
 | 
			
		||||
    
 | 
			
		||||
    TextReader               reader(filename);
 | 
			
		||||
    std::vector<std::string> program;
 | 
			
		||||
    
 | 
			
		||||
    LOG(Message) << "Loading schedule from '" << filename << "'..."
 | 
			
		||||
                 << std::endl;
 | 
			
		||||
    read(reader, "schedule", program);
 | 
			
		||||
    program_.clear();
 | 
			
		||||
    for (auto &name: program)
 | 
			
		||||
    {
 | 
			
		||||
        program_.push_back(env().getModuleAddress(name));
 | 
			
		||||
    }
 | 
			
		||||
    scheduled_ = true;
 | 
			
		||||
    memPeak_   = memPeak(program_);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Application::printSchedule(void)
 | 
			
		||||
{
 | 
			
		||||
    if (!scheduled_)
 | 
			
		||||
    {
 | 
			
		||||
        HADRON_ERROR("Computation not scheduled");
 | 
			
		||||
    }
 | 
			
		||||
    LOG(Message) << "Schedule (memory peak: " << MEM_MSG(memPeak_) << "):"
 | 
			
		||||
                 << std::endl;
 | 
			
		||||
    for (unsigned int i = 0; i < program_.size(); ++i)
 | 
			
		||||
    {
 | 
			
		||||
        LOG(Message) << std::setw(4) << i + 1 << ": "
 | 
			
		||||
                     << env().getModuleName(program_[i]) << std::endl;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// loop on configurations //////////////////////////////////////////////////////
 | 
			
		||||
void Application::configLoop(void)
 | 
			
		||||
{
 | 
			
		||||
    auto range = par_.trajCounter;
 | 
			
		||||
    
 | 
			
		||||
    for (unsigned int t = range.start; t < range.end; t += range.step)
 | 
			
		||||
    {
 | 
			
		||||
        LOG(Message) << BIG_SEP << " Starting measurement for trajectory " << t
 | 
			
		||||
                     << " " << BIG_SEP << std::endl;
 | 
			
		||||
        env().setTrajectory(t);
 | 
			
		||||
        env().executeProgram(program_);
 | 
			
		||||
    }
 | 
			
		||||
    LOG(Message) << BIG_SEP << " End of measurement " << BIG_SEP << std::endl;
 | 
			
		||||
    env().freeAll();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										132
									
								
								extras/Hadrons/Application.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								extras/Hadrons/Application.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,132 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
Source file: extras/Hadrons/Application.hpp
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2015
 | 
			
		||||
Copyright (C) 2016
 | 
			
		||||
 | 
			
		||||
Author: Antonin Portelli <antonin.portelli@me.com>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
 | 
			
		||||
#ifndef Hadrons_Application_hpp_
 | 
			
		||||
#define Hadrons_Application_hpp_
 | 
			
		||||
 | 
			
		||||
#include <Grid/Hadrons/Global.hpp>
 | 
			
		||||
#include <Grid/Hadrons/Environment.hpp>
 | 
			
		||||
#include <Grid/Hadrons/ModuleFactory.hpp>
 | 
			
		||||
#include <Grid/Hadrons/Modules.hpp>
 | 
			
		||||
 | 
			
		||||
BEGIN_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                         Main program manager                               *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
class Application
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    class TrajRange: Serializable
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        GRID_SERIALIZABLE_CLASS_MEMBERS(TrajRange,
 | 
			
		||||
                                        unsigned int, start,
 | 
			
		||||
                                        unsigned int, end,
 | 
			
		||||
                                        unsigned int, step);
 | 
			
		||||
    };
 | 
			
		||||
    class GeneticPar: Serializable
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        GeneticPar(void):
 | 
			
		||||
            popSize{20}, maxGen{1000}, maxCstGen{100}, mutationRate{.1} {};
 | 
			
		||||
    public:
 | 
			
		||||
        GRID_SERIALIZABLE_CLASS_MEMBERS(GeneticPar,
 | 
			
		||||
                                        unsigned int, popSize,
 | 
			
		||||
                                        unsigned int, maxGen,
 | 
			
		||||
                                        unsigned int, maxCstGen,
 | 
			
		||||
                                        double      , mutationRate);
 | 
			
		||||
    };
 | 
			
		||||
    class GlobalPar: Serializable
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        GRID_SERIALIZABLE_CLASS_MEMBERS(GlobalPar,
 | 
			
		||||
                                        TrajRange,   trajCounter,
 | 
			
		||||
                                        GeneticPar,  genetic,
 | 
			
		||||
                                        std::string, seed);
 | 
			
		||||
    };
 | 
			
		||||
public:
 | 
			
		||||
    // constructors
 | 
			
		||||
    Application(void);
 | 
			
		||||
    Application(const GlobalPar &par);
 | 
			
		||||
    Application(const std::string parameterFileName);
 | 
			
		||||
    // destructor
 | 
			
		||||
    virtual ~Application(void) = default;
 | 
			
		||||
    // access
 | 
			
		||||
    void              setPar(const GlobalPar &par);
 | 
			
		||||
    const GlobalPar & getPar(void);
 | 
			
		||||
    // module creation
 | 
			
		||||
    template <typename M>
 | 
			
		||||
    void createModule(const std::string name);
 | 
			
		||||
    template <typename M>
 | 
			
		||||
    void createModule(const std::string name, const typename M::Par &par);
 | 
			
		||||
    // execute
 | 
			
		||||
    void run(void);
 | 
			
		||||
    // XML parameter file I/O
 | 
			
		||||
    void parseParameterFile(const std::string parameterFileName);
 | 
			
		||||
    void saveParameterFile(const std::string parameterFileName);
 | 
			
		||||
    // schedule computation
 | 
			
		||||
    void schedule(void);
 | 
			
		||||
    void saveSchedule(const std::string filename);
 | 
			
		||||
    void loadSchedule(const std::string filename);
 | 
			
		||||
    void printSchedule(void);
 | 
			
		||||
    // loop on configurations
 | 
			
		||||
    void configLoop(void);
 | 
			
		||||
private:
 | 
			
		||||
    // environment shortcut
 | 
			
		||||
    Environment & env(void) const;
 | 
			
		||||
private:
 | 
			
		||||
    long unsigned int         locVol_;
 | 
			
		||||
    std::string               parameterFileName_{""};
 | 
			
		||||
    GlobalPar                 par_;
 | 
			
		||||
    std::vector<unsigned int> program_;
 | 
			
		||||
    Environment::Size         memPeak_;
 | 
			
		||||
    bool                      scheduled_{false};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                     Application template implementation                    *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
// module creation /////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename M>
 | 
			
		||||
void Application::createModule(const std::string name)
 | 
			
		||||
{
 | 
			
		||||
    env().createModule<M>(name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename M>
 | 
			
		||||
void Application::createModule(const std::string name,
 | 
			
		||||
                               const typename M::Par &par)
 | 
			
		||||
{
 | 
			
		||||
    env().createModule<M>(name, par);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
END_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
#endif // Hadrons_Application_hpp_
 | 
			
		||||
							
								
								
									
										743
									
								
								extras/Hadrons/Environment.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										743
									
								
								extras/Hadrons/Environment.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,743 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
Source file: extras/Hadrons/Environment.cc
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2015
 | 
			
		||||
Copyright (C) 2016
 | 
			
		||||
 | 
			
		||||
Author: Antonin Portelli <antonin.portelli@me.com>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
 | 
			
		||||
#include <Grid/Hadrons/Environment.hpp>
 | 
			
		||||
#include <Grid/Hadrons/Module.hpp>
 | 
			
		||||
#include <Grid/Hadrons/ModuleFactory.hpp>
 | 
			
		||||
 | 
			
		||||
using namespace Grid;
 | 
			
		||||
using namespace QCD;
 | 
			
		||||
using namespace Hadrons;
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                       Environment implementation                           *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
// constructor /////////////////////////////////////////////////////////////////
 | 
			
		||||
Environment::Environment(void)
 | 
			
		||||
{
 | 
			
		||||
    nd_ = GridDefaultLatt().size();
 | 
			
		||||
    grid4d_.reset(SpaceTimeGrid::makeFourDimGrid(
 | 
			
		||||
        GridDefaultLatt(), GridDefaultSimd(nd_, vComplex::Nsimd()),
 | 
			
		||||
        GridDefaultMpi()));
 | 
			
		||||
    gridRb4d_.reset(SpaceTimeGrid::makeFourDimRedBlackGrid(grid4d_.get()));
 | 
			
		||||
    auto loc = getGrid()->LocalDimensions();
 | 
			
		||||
    locVol_ = 1;
 | 
			
		||||
    for (unsigned int d = 0; d < loc.size(); ++d)
 | 
			
		||||
    {
 | 
			
		||||
        locVol_ *= loc[d];
 | 
			
		||||
    }
 | 
			
		||||
    rng4d_.reset(new GridParallelRNG(grid4d_.get()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// dry run /////////////////////////////////////////////////////////////////////
 | 
			
		||||
void Environment::dryRun(const bool isDry)
 | 
			
		||||
{
 | 
			
		||||
    dryRun_ = isDry;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Environment::isDryRun(void) const
 | 
			
		||||
{
 | 
			
		||||
    return dryRun_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// trajectory number ///////////////////////////////////////////////////////////
 | 
			
		||||
void Environment::setTrajectory(const unsigned int traj)
 | 
			
		||||
{
 | 
			
		||||
    traj_ = traj;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned int Environment::getTrajectory(void) const
 | 
			
		||||
{
 | 
			
		||||
    return traj_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// grids ///////////////////////////////////////////////////////////////////////
 | 
			
		||||
void Environment::createGrid(const unsigned int Ls)
 | 
			
		||||
{
 | 
			
		||||
    if (grid5d_.find(Ls) == grid5d_.end())
 | 
			
		||||
    {
 | 
			
		||||
        auto g = getGrid();
 | 
			
		||||
        
 | 
			
		||||
        grid5d_[Ls].reset(SpaceTimeGrid::makeFiveDimGrid(Ls, g));
 | 
			
		||||
        gridRb5d_[Ls].reset(SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls, g));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GridCartesian * Environment::getGrid(const unsigned int Ls) const
 | 
			
		||||
{
 | 
			
		||||
    try
 | 
			
		||||
    {
 | 
			
		||||
        if (Ls == 1)
 | 
			
		||||
        {
 | 
			
		||||
            return grid4d_.get();
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            return grid5d_.at(Ls).get();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    catch(std::out_of_range &)
 | 
			
		||||
    {
 | 
			
		||||
        HADRON_ERROR("no grid with Ls= " << Ls);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GridRedBlackCartesian * Environment::getRbGrid(const unsigned int Ls) const
 | 
			
		||||
{
 | 
			
		||||
    try
 | 
			
		||||
    {
 | 
			
		||||
        if (Ls == 1)
 | 
			
		||||
        {
 | 
			
		||||
            return gridRb4d_.get();
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            return gridRb5d_.at(Ls).get();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    catch(std::out_of_range &)
 | 
			
		||||
    {
 | 
			
		||||
        HADRON_ERROR("no red-black 5D grid with Ls= " << Ls);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned int Environment::getNd(void) const
 | 
			
		||||
{
 | 
			
		||||
    return nd_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// random number generator /////////////////////////////////////////////////////
 | 
			
		||||
void Environment::setSeed(const std::vector<int> &seed)
 | 
			
		||||
{
 | 
			
		||||
    rng4d_->SeedFixedIntegers(seed);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GridParallelRNG * Environment::get4dRng(void) const
 | 
			
		||||
{
 | 
			
		||||
    return rng4d_.get();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// module management ///////////////////////////////////////////////////////////
 | 
			
		||||
void Environment::pushModule(Environment::ModPt &pt)
 | 
			
		||||
{
 | 
			
		||||
    std::string name = pt->getName();
 | 
			
		||||
    
 | 
			
		||||
    if (!hasModule(name))
 | 
			
		||||
    {
 | 
			
		||||
        std::vector<unsigned int> inputAddress;
 | 
			
		||||
        unsigned int              address;
 | 
			
		||||
        ModuleInfo                m;
 | 
			
		||||
        
 | 
			
		||||
        m.data = std::move(pt);
 | 
			
		||||
        m.type = typeIdPt(*m.data.get());
 | 
			
		||||
        m.name = name;
 | 
			
		||||
        auto input  = m.data->getInput();
 | 
			
		||||
        for (auto &in: input)
 | 
			
		||||
        {
 | 
			
		||||
            if (!hasObject(in))
 | 
			
		||||
            {
 | 
			
		||||
                addObject(in , -1);
 | 
			
		||||
            }
 | 
			
		||||
            m.input.push_back(objectAddress_[in]);
 | 
			
		||||
        }
 | 
			
		||||
        auto output = m.data->getOutput();
 | 
			
		||||
        module_.push_back(std::move(m));
 | 
			
		||||
        address              = static_cast<unsigned int>(module_.size() - 1);
 | 
			
		||||
        moduleAddress_[name] = address;
 | 
			
		||||
        for (auto &out: output)
 | 
			
		||||
        {
 | 
			
		||||
            if (!hasObject(out))
 | 
			
		||||
            {
 | 
			
		||||
                addObject(out, address);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                if (object_[objectAddress_[out]].module < 0)
 | 
			
		||||
                {
 | 
			
		||||
                    object_[objectAddress_[out]].module = address;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    HADRON_ERROR("object '" + out
 | 
			
		||||
                                 + "' is already produced by module '"
 | 
			
		||||
                                 + module_[object_[getObjectAddress(out)].module].name
 | 
			
		||||
                                 + "' (while pushing module '" + name + "')");
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        HADRON_ERROR("module '" + name + "' already exists");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned int Environment::getNModule(void) const
 | 
			
		||||
{
 | 
			
		||||
    return module_.size();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Environment::createModule(const std::string name, const std::string type,
 | 
			
		||||
                               XmlReader &reader)
 | 
			
		||||
{
 | 
			
		||||
    auto &factory = ModuleFactory::getInstance();
 | 
			
		||||
    auto pt       = factory.create(type, name);
 | 
			
		||||
    
 | 
			
		||||
    pt->parseParameters(reader, "options");
 | 
			
		||||
    pushModule(pt);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ModuleBase * Environment::getModule(const unsigned int address) const
 | 
			
		||||
{
 | 
			
		||||
    if (hasModule(address))
 | 
			
		||||
    {
 | 
			
		||||
        return module_[address].data.get();
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        HADRON_ERROR("no module with address " + std::to_string(address));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ModuleBase * Environment::getModule(const std::string name) const
 | 
			
		||||
{
 | 
			
		||||
    return getModule(getModuleAddress(name));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned int Environment::getModuleAddress(const std::string name) const
 | 
			
		||||
{
 | 
			
		||||
    if (hasModule(name))
 | 
			
		||||
    {
 | 
			
		||||
        return moduleAddress_.at(name);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        HADRON_ERROR("no module with name '" + name + "'");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string Environment::getModuleName(const unsigned int address) const
 | 
			
		||||
{
 | 
			
		||||
    if (hasModule(address))
 | 
			
		||||
    {
 | 
			
		||||
        return module_[address].name;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        HADRON_ERROR("no module with address " + std::to_string(address));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string Environment::getModuleType(const unsigned int address) const
 | 
			
		||||
{
 | 
			
		||||
    if (hasModule(address))
 | 
			
		||||
    {
 | 
			
		||||
        return typeName(module_[address].type);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        HADRON_ERROR("no module with address " + std::to_string(address));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string Environment::getModuleType(const std::string name) const
 | 
			
		||||
{
 | 
			
		||||
    return getModuleType(getModuleAddress(name));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Environment::hasModule(const unsigned int address) const
 | 
			
		||||
{
 | 
			
		||||
    return (address < module_.size());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Environment::hasModule(const std::string name) const
 | 
			
		||||
{
 | 
			
		||||
    return (moduleAddress_.find(name) != moduleAddress_.end());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Graph<unsigned int> Environment::makeModuleGraph(void) const
 | 
			
		||||
{
 | 
			
		||||
    Graph<unsigned int> moduleGraph;
 | 
			
		||||
    
 | 
			
		||||
    for (unsigned int i = 0; i < module_.size(); ++i)
 | 
			
		||||
    {
 | 
			
		||||
        moduleGraph.addVertex(i);
 | 
			
		||||
        for (auto &j: module_[i].input)
 | 
			
		||||
        {
 | 
			
		||||
            moduleGraph.addEdge(object_[j].module, i);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    return moduleGraph;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define BIG_SEP "==============="
 | 
			
		||||
#define SEP     "---------------"
 | 
			
		||||
#define MEM_MSG(size)\
 | 
			
		||||
sizeString((size)*locVol_) << " (" << sizeString(size)  << "/site)"
 | 
			
		||||
 | 
			
		||||
Environment::Size
 | 
			
		||||
Environment::executeProgram(const std::vector<unsigned int> &p)
 | 
			
		||||
{
 | 
			
		||||
    Size                                memPeak = 0, sizeBefore, sizeAfter;
 | 
			
		||||
    std::vector<std::set<unsigned int>> freeProg;
 | 
			
		||||
    bool                                continueCollect, nothingFreed;
 | 
			
		||||
    
 | 
			
		||||
    // build garbage collection schedule
 | 
			
		||||
    freeProg.resize(p.size());
 | 
			
		||||
    for (unsigned int i = 0; i < object_.size(); ++i)
 | 
			
		||||
    {
 | 
			
		||||
        auto pred = [i, this](const unsigned int j)
 | 
			
		||||
        {
 | 
			
		||||
            auto &in = module_[j].input;
 | 
			
		||||
            auto it  = std::find(in.begin(), in.end(), i);
 | 
			
		||||
            
 | 
			
		||||
            return (it != in.end()) or (j == object_[i].module);
 | 
			
		||||
        };
 | 
			
		||||
        auto it = std::find_if(p.rbegin(), p.rend(), pred);
 | 
			
		||||
        if (it != p.rend())
 | 
			
		||||
        {
 | 
			
		||||
            freeProg[p.rend() - it - 1].insert(i);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // program execution
 | 
			
		||||
    for (unsigned int i = 0; i < p.size(); ++i)
 | 
			
		||||
    {
 | 
			
		||||
        // execute module
 | 
			
		||||
        if (!isDryRun())
 | 
			
		||||
        {
 | 
			
		||||
            LOG(Message) << SEP << " Measurement step " << i+1 << "/"
 | 
			
		||||
                         << p.size() << " (module '" << module_[p[i]].name
 | 
			
		||||
                         << "') " << SEP << std::endl;
 | 
			
		||||
        }
 | 
			
		||||
        (*module_[p[i]].data)();
 | 
			
		||||
        sizeBefore = getTotalSize();
 | 
			
		||||
        // print used memory after execution
 | 
			
		||||
        if (!isDryRun())
 | 
			
		||||
        {
 | 
			
		||||
            LOG(Message) << "Allocated objects: " << MEM_MSG(sizeBefore)
 | 
			
		||||
                         << std::endl;
 | 
			
		||||
        }
 | 
			
		||||
        if (sizeBefore > memPeak)
 | 
			
		||||
        {
 | 
			
		||||
            memPeak = sizeBefore;
 | 
			
		||||
        }
 | 
			
		||||
        // garbage collection for step i
 | 
			
		||||
        if (!isDryRun())
 | 
			
		||||
        {
 | 
			
		||||
            LOG(Message) << "Garbage collection..." << std::endl;
 | 
			
		||||
        }
 | 
			
		||||
        nothingFreed = true;
 | 
			
		||||
        do
 | 
			
		||||
        {
 | 
			
		||||
            continueCollect = false;
 | 
			
		||||
            auto toFree = freeProg[i];
 | 
			
		||||
            for (auto &j: toFree)
 | 
			
		||||
            {
 | 
			
		||||
                // continue garbage collection while there are still
 | 
			
		||||
                // objects without owners
 | 
			
		||||
                continueCollect = continueCollect or !hasOwners(j);
 | 
			
		||||
                if(freeObject(j))
 | 
			
		||||
                {
 | 
			
		||||
                    // if an object has been freed, remove it from
 | 
			
		||||
                    // the garbage collection schedule
 | 
			
		||||
                    freeProg[i].erase(j);
 | 
			
		||||
                    nothingFreed = false;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        } while (continueCollect);
 | 
			
		||||
        // any remaining objects in step i garbage collection schedule
 | 
			
		||||
        // is scheduled for step i + 1
 | 
			
		||||
        if (i + 1 < p.size())
 | 
			
		||||
        {
 | 
			
		||||
            for (auto &j: freeProg[i])
 | 
			
		||||
            {
 | 
			
		||||
                freeProg[i + 1].insert(j);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        // print used memory after garbage collection if necessary
 | 
			
		||||
        if (!isDryRun())
 | 
			
		||||
        {
 | 
			
		||||
            sizeAfter = getTotalSize();
 | 
			
		||||
            if (sizeBefore != sizeAfter)
 | 
			
		||||
            {
 | 
			
		||||
                LOG(Message) << "Allocated objects: " << MEM_MSG(sizeAfter)
 | 
			
		||||
                             << std::endl;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                LOG(Message) << "Nothing to free" << std::endl;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    return memPeak;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Environment::Size Environment::executeProgram(const std::vector<std::string> &p)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<unsigned int> pAddress;
 | 
			
		||||
    
 | 
			
		||||
    for (auto &n: p)
 | 
			
		||||
    {
 | 
			
		||||
        pAddress.push_back(getModuleAddress(n));
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    return executeProgram(pAddress);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// general memory management ///////////////////////////////////////////////////
 | 
			
		||||
void Environment::addObject(const std::string name, const int moduleAddress)
 | 
			
		||||
{
 | 
			
		||||
    if (!hasObject(name))
 | 
			
		||||
    {
 | 
			
		||||
        ObjInfo info;
 | 
			
		||||
        
 | 
			
		||||
        info.name   = name;
 | 
			
		||||
        info.module = moduleAddress;
 | 
			
		||||
        object_.push_back(std::move(info));
 | 
			
		||||
        objectAddress_[name] = static_cast<unsigned int>(object_.size() - 1);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        HADRON_ERROR("object '" + name + "' already exists");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Environment::registerObject(const unsigned int address,
 | 
			
		||||
                                 const unsigned int size, const unsigned int Ls)
 | 
			
		||||
{
 | 
			
		||||
    if (!hasRegisteredObject(address))
 | 
			
		||||
    {
 | 
			
		||||
        if (hasObject(address))
 | 
			
		||||
        {
 | 
			
		||||
            object_[address].size         = size;
 | 
			
		||||
            object_[address].Ls           = Ls;
 | 
			
		||||
            object_[address].isRegistered = true;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            HADRON_ERROR("no object with address " + std::to_string(address));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        HADRON_ERROR("object with address " + std::to_string(address)
 | 
			
		||||
                     + " already registered");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Environment::registerObject(const std::string name,
 | 
			
		||||
                                 const unsigned int size, const unsigned int Ls)
 | 
			
		||||
{
 | 
			
		||||
    if (!hasObject(name))
 | 
			
		||||
    {
 | 
			
		||||
        addObject(name);
 | 
			
		||||
    }
 | 
			
		||||
    registerObject(getObjectAddress(name), size, Ls);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned int Environment::getObjectAddress(const std::string name) const
 | 
			
		||||
{
 | 
			
		||||
    if (hasObject(name))
 | 
			
		||||
    {
 | 
			
		||||
        return objectAddress_.at(name);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        HADRON_ERROR("no object with name '" + name + "'");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string Environment::getObjectName(const unsigned int address) const
 | 
			
		||||
{
 | 
			
		||||
    if (hasObject(address))
 | 
			
		||||
    {
 | 
			
		||||
        return object_[address].name;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        HADRON_ERROR("no object with address " + std::to_string(address));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string Environment::getObjectType(const unsigned int address) const
 | 
			
		||||
{
 | 
			
		||||
    if (hasRegisteredObject(address))
 | 
			
		||||
    {
 | 
			
		||||
        return typeName(object_[address].type);
 | 
			
		||||
    }
 | 
			
		||||
    else if (hasObject(address))
 | 
			
		||||
    {
 | 
			
		||||
        HADRON_ERROR("object with address " + std::to_string(address)
 | 
			
		||||
                     + " exists but is not registered");
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        HADRON_ERROR("no object with address " + std::to_string(address));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string Environment::getObjectType(const std::string name) const
 | 
			
		||||
{
 | 
			
		||||
    return getObjectType(getObjectAddress(name));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Environment::Size Environment::getObjectSize(const unsigned int address) const
 | 
			
		||||
{
 | 
			
		||||
    if (hasRegisteredObject(address))
 | 
			
		||||
    {
 | 
			
		||||
        return object_[address].size;
 | 
			
		||||
    }
 | 
			
		||||
    else if (hasObject(address))
 | 
			
		||||
    {
 | 
			
		||||
        HADRON_ERROR("object with address " + std::to_string(address)
 | 
			
		||||
                     + " exists but is not registered");
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        HADRON_ERROR("no object with address " + std::to_string(address));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Environment::Size Environment::getObjectSize(const std::string name) const
 | 
			
		||||
{
 | 
			
		||||
    return getObjectSize(getObjectAddress(name));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned int Environment::getObjectLs(const unsigned int address) const
 | 
			
		||||
{
 | 
			
		||||
    if (hasRegisteredObject(address))
 | 
			
		||||
    {
 | 
			
		||||
        return object_[address].Ls;
 | 
			
		||||
    }
 | 
			
		||||
    else if (hasObject(address))
 | 
			
		||||
    {
 | 
			
		||||
        HADRON_ERROR("object with address " + std::to_string(address)
 | 
			
		||||
                     + " exists but is not registered");
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        HADRON_ERROR("no object with address " + std::to_string(address));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned int Environment::getObjectLs(const std::string name) const
 | 
			
		||||
{
 | 
			
		||||
    return getObjectLs(getObjectAddress(name));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Environment::hasObject(const unsigned int address) const
 | 
			
		||||
{
 | 
			
		||||
    return (address < object_.size());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Environment::hasObject(const std::string name) const
 | 
			
		||||
{
 | 
			
		||||
    auto it = objectAddress_.find(name);
 | 
			
		||||
    
 | 
			
		||||
    return ((it != objectAddress_.end()) and hasObject(it->second));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Environment::hasRegisteredObject(const unsigned int address) const
 | 
			
		||||
{
 | 
			
		||||
    if (hasObject(address))
 | 
			
		||||
    {
 | 
			
		||||
        return object_[address].isRegistered;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Environment::hasRegisteredObject(const std::string name) const
 | 
			
		||||
{
 | 
			
		||||
    if (hasObject(name))
 | 
			
		||||
    {
 | 
			
		||||
        return hasRegisteredObject(getObjectAddress(name));
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Environment::hasCreatedObject(const unsigned int address) const
 | 
			
		||||
{
 | 
			
		||||
    if (hasObject(address))
 | 
			
		||||
    {
 | 
			
		||||
        return (object_[address].data != nullptr);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Environment::hasCreatedObject(const std::string name) const
 | 
			
		||||
{
 | 
			
		||||
    if (hasObject(name))
 | 
			
		||||
    {
 | 
			
		||||
        return hasCreatedObject(getObjectAddress(name));
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Environment::isObject5d(const unsigned int address) const
 | 
			
		||||
{
 | 
			
		||||
    return (getObjectLs(address) > 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Environment::isObject5d(const std::string name) const
 | 
			
		||||
{
 | 
			
		||||
    return (getObjectLs(name) > 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Environment::Size Environment::getTotalSize(void) const
 | 
			
		||||
{
 | 
			
		||||
    Environment::Size size = 0;
 | 
			
		||||
    
 | 
			
		||||
    for (auto &o: object_)
 | 
			
		||||
    {
 | 
			
		||||
        if (o.isRegistered)
 | 
			
		||||
        {
 | 
			
		||||
            size += o.size;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    return size;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Environment::addOwnership(const unsigned int owner,
 | 
			
		||||
                               const unsigned int property)
 | 
			
		||||
{
 | 
			
		||||
    if (hasObject(property))
 | 
			
		||||
    {
 | 
			
		||||
        object_[property].owners.insert(owner);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        HADRON_ERROR("no object with address " + std::to_string(property));
 | 
			
		||||
    }
 | 
			
		||||
    if (hasObject(owner))
 | 
			
		||||
    {
 | 
			
		||||
        object_[owner].properties.insert(property);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        HADRON_ERROR("no object with address " + std::to_string(owner));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Environment::addOwnership(const std::string owner,
 | 
			
		||||
                               const std::string property)
 | 
			
		||||
{
 | 
			
		||||
    addOwnership(getObjectAddress(owner), getObjectAddress(property));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Environment::hasOwners(const unsigned int address) const
 | 
			
		||||
{
 | 
			
		||||
    
 | 
			
		||||
    if (hasObject(address))
 | 
			
		||||
    {
 | 
			
		||||
        return (!object_[address].owners.empty());
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        HADRON_ERROR("no object with address " + std::to_string(address));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Environment::hasOwners(const std::string name) const
 | 
			
		||||
{
 | 
			
		||||
    return hasOwners(getObjectAddress(name));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Environment::freeObject(const unsigned int address)
 | 
			
		||||
{
 | 
			
		||||
    if (!hasOwners(address))
 | 
			
		||||
    {
 | 
			
		||||
        if (!isDryRun() and object_[address].isRegistered)
 | 
			
		||||
        {
 | 
			
		||||
            LOG(Message) << "Destroying object '" << object_[address].name
 | 
			
		||||
                         << "'" << std::endl;
 | 
			
		||||
        }
 | 
			
		||||
        for (auto &p: object_[address].properties)
 | 
			
		||||
        {
 | 
			
		||||
            object_[p].owners.erase(address);
 | 
			
		||||
        }
 | 
			
		||||
        object_[address].size         = 0;
 | 
			
		||||
        object_[address].Ls           = 0;
 | 
			
		||||
        object_[address].isRegistered = false;
 | 
			
		||||
        object_[address].type         = nullptr;
 | 
			
		||||
        object_[address].owners.clear();
 | 
			
		||||
        object_[address].properties.clear();
 | 
			
		||||
        object_[address].data.reset(nullptr);
 | 
			
		||||
        
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Environment::freeObject(const std::string name)
 | 
			
		||||
{
 | 
			
		||||
    return freeObject(getObjectAddress(name));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Environment::freeAll(void)
 | 
			
		||||
{
 | 
			
		||||
    for (unsigned int i = 0; i < object_.size(); ++i)
 | 
			
		||||
    {
 | 
			
		||||
        freeObject(i);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Environment::printContent(void)
 | 
			
		||||
{
 | 
			
		||||
    LOG(Message) << "Modules: " << std::endl;
 | 
			
		||||
    for (unsigned int i = 0; i < module_.size(); ++i)
 | 
			
		||||
    {
 | 
			
		||||
        LOG(Message) << std::setw(4) << i << ": "
 | 
			
		||||
                     << getModuleName(i) << std::endl;
 | 
			
		||||
    }
 | 
			
		||||
    LOG(Message) << "Objects: " << std::endl;
 | 
			
		||||
    for (unsigned int i = 0; i < object_.size(); ++i)
 | 
			
		||||
    {
 | 
			
		||||
        LOG(Message) << std::setw(4) << i << ": "
 | 
			
		||||
                     << getObjectName(i) << std::endl;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										385
									
								
								extras/Hadrons/Environment.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										385
									
								
								extras/Hadrons/Environment.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,385 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
Source file: extras/Hadrons/Environment.hpp
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2015
 | 
			
		||||
Copyright (C) 2016
 | 
			
		||||
 | 
			
		||||
Author: Antonin Portelli <antonin.portelli@me.com>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
 | 
			
		||||
#ifndef Hadrons_Environment_hpp_
 | 
			
		||||
#define Hadrons_Environment_hpp_
 | 
			
		||||
 | 
			
		||||
#include <Grid/Hadrons/Global.hpp>
 | 
			
		||||
#include <Grid/Hadrons/Graph.hpp>
 | 
			
		||||
 | 
			
		||||
#ifndef SITE_SIZE_TYPE
 | 
			
		||||
#define SITE_SIZE_TYPE unsigned int
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
BEGIN_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                         Global environment                                 *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
// forward declaration of Module
 | 
			
		||||
class ModuleBase;
 | 
			
		||||
 | 
			
		||||
class Object
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    Object(void) = default;
 | 
			
		||||
    virtual ~Object(void) = default;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
class Holder: public Object
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    Holder(void) = default;
 | 
			
		||||
    Holder(T *pt);
 | 
			
		||||
    virtual ~Holder(void) = default;
 | 
			
		||||
    T &       get(void) const;
 | 
			
		||||
    T *       getPt(void) const;
 | 
			
		||||
    void      reset(T *pt);
 | 
			
		||||
private:
 | 
			
		||||
    std::unique_ptr<T> objPt_{nullptr};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class Environment
 | 
			
		||||
{
 | 
			
		||||
    SINGLETON(Environment);
 | 
			
		||||
public:
 | 
			
		||||
    typedef SITE_SIZE_TYPE                         Size;
 | 
			
		||||
    typedef std::unique_ptr<ModuleBase>            ModPt;
 | 
			
		||||
    typedef std::unique_ptr<GridCartesian>         GridPt;
 | 
			
		||||
    typedef std::unique_ptr<GridRedBlackCartesian> GridRbPt;
 | 
			
		||||
    typedef std::unique_ptr<GridParallelRNG>       RngPt;
 | 
			
		||||
    typedef std::unique_ptr<LatticeBase>           LatticePt;
 | 
			
		||||
private:
 | 
			
		||||
    struct ModuleInfo
 | 
			
		||||
    {
 | 
			
		||||
        const std::type_info      *type{nullptr};
 | 
			
		||||
        std::string               name;
 | 
			
		||||
        ModPt                     data{nullptr};
 | 
			
		||||
        std::vector<unsigned int> input;
 | 
			
		||||
    };
 | 
			
		||||
    struct ObjInfo
 | 
			
		||||
    {
 | 
			
		||||
        Size                    size{0};
 | 
			
		||||
        unsigned int            Ls{0};
 | 
			
		||||
        bool                    isRegistered{false};
 | 
			
		||||
        const std::type_info    *type{nullptr};
 | 
			
		||||
        std::string             name;
 | 
			
		||||
        int                     module{-1};
 | 
			
		||||
        std::set<unsigned int>  owners, properties;
 | 
			
		||||
        std::unique_ptr<Object> data{nullptr};
 | 
			
		||||
    };
 | 
			
		||||
public:
 | 
			
		||||
    // dry run
 | 
			
		||||
    void                    dryRun(const bool isDry);
 | 
			
		||||
    bool                    isDryRun(void) const;
 | 
			
		||||
    // trajectory number
 | 
			
		||||
    void                    setTrajectory(const unsigned int traj);
 | 
			
		||||
    unsigned int            getTrajectory(void) const;
 | 
			
		||||
    // grids
 | 
			
		||||
    void                    createGrid(const unsigned int Ls);
 | 
			
		||||
    GridCartesian *         getGrid(const unsigned int Ls = 1) const;
 | 
			
		||||
    GridRedBlackCartesian * getRbGrid(const unsigned int Ls = 1) const;
 | 
			
		||||
    unsigned int            getNd(void) const;
 | 
			
		||||
    // random number generator
 | 
			
		||||
    void                    setSeed(const std::vector<int> &seed);
 | 
			
		||||
    GridParallelRNG *       get4dRng(void) const;
 | 
			
		||||
    // module management
 | 
			
		||||
    void                    pushModule(ModPt &pt);
 | 
			
		||||
    template <typename M>
 | 
			
		||||
    void                    createModule(const std::string name);
 | 
			
		||||
    template <typename M>
 | 
			
		||||
    void                    createModule(const std::string name,
 | 
			
		||||
                                         const typename M::Par &par);
 | 
			
		||||
    void                    createModule(const std::string name,
 | 
			
		||||
                                         const std::string type,
 | 
			
		||||
                                         XmlReader &reader);
 | 
			
		||||
    unsigned int            getNModule(void) const;
 | 
			
		||||
    ModuleBase *            getModule(const unsigned int address) const;
 | 
			
		||||
    ModuleBase *            getModule(const std::string name) const;
 | 
			
		||||
    template <typename M>
 | 
			
		||||
    M *                     getModule(const unsigned int address) const;
 | 
			
		||||
    template <typename M>
 | 
			
		||||
    M *                     getModule(const std::string name) const;
 | 
			
		||||
    unsigned int            getModuleAddress(const std::string name) const;
 | 
			
		||||
    std::string             getModuleName(const unsigned int address) const;
 | 
			
		||||
    std::string             getModuleType(const unsigned int address) const;
 | 
			
		||||
    std::string             getModuleType(const std::string name) const;
 | 
			
		||||
    bool                    hasModule(const unsigned int address) const;
 | 
			
		||||
    bool                    hasModule(const std::string name) const;
 | 
			
		||||
    Graph<unsigned int>     makeModuleGraph(void) const;
 | 
			
		||||
    Size                    executeProgram(const std::vector<unsigned int> &p);
 | 
			
		||||
    Size                    executeProgram(const std::vector<std::string> &p);
 | 
			
		||||
    // general memory management
 | 
			
		||||
    void                    addObject(const std::string name,
 | 
			
		||||
                                      const int moduleAddress = -1);
 | 
			
		||||
    void                    registerObject(const unsigned int address,
 | 
			
		||||
                                           const unsigned int size,
 | 
			
		||||
                                           const unsigned int Ls = 1);
 | 
			
		||||
    void                    registerObject(const std::string name,
 | 
			
		||||
                                           const unsigned int size,
 | 
			
		||||
                                           const unsigned int Ls = 1);
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    unsigned int            lattice4dSize(void) const;
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    void                    registerLattice(const unsigned int address,
 | 
			
		||||
                                            const unsigned int Ls = 1);
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    void                    registerLattice(const std::string name,
 | 
			
		||||
                                            const unsigned int Ls = 1);
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    void                    setObject(const unsigned int address, T *object);
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    void                    setObject(const std::string name, T *object);
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    T *                     getObject(const unsigned int address) const;
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    T *                     getObject(const std::string name) const;
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    T *                     createLattice(const unsigned int address);
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    T *                     createLattice(const std::string name);
 | 
			
		||||
    unsigned int            getObjectAddress(const std::string name) const;
 | 
			
		||||
    std::string             getObjectName(const unsigned int address) const;
 | 
			
		||||
    std::string             getObjectType(const unsigned int address) const;
 | 
			
		||||
    std::string             getObjectType(const std::string name) const;
 | 
			
		||||
    Size                    getObjectSize(const unsigned int address) const;
 | 
			
		||||
    Size                    getObjectSize(const std::string name) const;
 | 
			
		||||
    unsigned int            getObjectLs(const unsigned int address) const;
 | 
			
		||||
    unsigned int            getObjectLs(const std::string name) const;
 | 
			
		||||
    bool                    hasObject(const unsigned int address) const;
 | 
			
		||||
    bool                    hasObject(const std::string name) const;
 | 
			
		||||
    bool                    hasRegisteredObject(const unsigned int address) const;
 | 
			
		||||
    bool                    hasRegisteredObject(const std::string name) const;
 | 
			
		||||
    bool                    hasCreatedObject(const unsigned int address) const;
 | 
			
		||||
    bool                    hasCreatedObject(const std::string name) const;
 | 
			
		||||
    bool                    isObject5d(const unsigned int address) const;
 | 
			
		||||
    bool                    isObject5d(const std::string name) const;
 | 
			
		||||
    Environment::Size       getTotalSize(void) const;
 | 
			
		||||
    void                    addOwnership(const unsigned int owner,
 | 
			
		||||
                                         const unsigned int property);
 | 
			
		||||
    void                    addOwnership(const std::string owner,
 | 
			
		||||
                                         const std::string property);
 | 
			
		||||
    bool                    hasOwners(const unsigned int address) const;
 | 
			
		||||
    bool                    hasOwners(const std::string name) const;
 | 
			
		||||
    bool                    freeObject(const unsigned int address);
 | 
			
		||||
    bool                    freeObject(const std::string name);
 | 
			
		||||
    void                    freeAll(void);
 | 
			
		||||
    void                    printContent(void);
 | 
			
		||||
private:
 | 
			
		||||
    // general
 | 
			
		||||
    bool                                   dryRun_{false};
 | 
			
		||||
    unsigned int                           traj_, locVol_;
 | 
			
		||||
    // grids
 | 
			
		||||
    GridPt                                 grid4d_;
 | 
			
		||||
    std::map<unsigned int, GridPt>         grid5d_;
 | 
			
		||||
    GridRbPt                               gridRb4d_;
 | 
			
		||||
    std::map<unsigned int, GridRbPt>       gridRb5d_;
 | 
			
		||||
    unsigned int                           nd_;
 | 
			
		||||
    // random number generator
 | 
			
		||||
    RngPt                                  rng4d_;
 | 
			
		||||
    // module and related maps
 | 
			
		||||
    std::vector<ModuleInfo>                module_;
 | 
			
		||||
    std::map<std::string, unsigned int>    moduleAddress_;
 | 
			
		||||
    // lattice store
 | 
			
		||||
    std::map<unsigned int, LatticePt>      lattice_;
 | 
			
		||||
    // object store
 | 
			
		||||
    std::vector<ObjInfo>                   object_;
 | 
			
		||||
    std::map<std::string, unsigned int>    objectAddress_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                       Holder template implementation                       *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
// constructor /////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename T>
 | 
			
		||||
Holder<T>::Holder(T *pt)
 | 
			
		||||
: objPt_(pt)
 | 
			
		||||
{}
 | 
			
		||||
 | 
			
		||||
// access //////////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename T>
 | 
			
		||||
T & Holder<T>::get(void) const
 | 
			
		||||
{
 | 
			
		||||
    return &objPt_.get();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
T * Holder<T>::getPt(void) const
 | 
			
		||||
{
 | 
			
		||||
    return objPt_.get();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
void Holder<T>::reset(T *pt)
 | 
			
		||||
{
 | 
			
		||||
    objPt_.reset(pt);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                     Environment template implementation                    *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
// module management ///////////////////////////////////////////////////////////
 | 
			
		||||
template <typename M>
 | 
			
		||||
void Environment::createModule(const std::string name)
 | 
			
		||||
{
 | 
			
		||||
    ModPt pt(new M(name));
 | 
			
		||||
    
 | 
			
		||||
    pushModule(pt);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename M>
 | 
			
		||||
void Environment::createModule(const std::string name,
 | 
			
		||||
                               const typename M::Par &par)
 | 
			
		||||
{
 | 
			
		||||
    ModPt pt(new M(name));
 | 
			
		||||
    
 | 
			
		||||
    static_cast<M *>(pt.get())->setPar(par);
 | 
			
		||||
    pushModule(pt);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename M>
 | 
			
		||||
M * Environment::getModule(const unsigned int address) const
 | 
			
		||||
{
 | 
			
		||||
    if (auto *pt = dynamic_cast<M *>(getModule(address)))
 | 
			
		||||
    {
 | 
			
		||||
        return pt;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        HADRON_ERROR("module '" + module_[address].name
 | 
			
		||||
                     + "' does not have type " + typeid(M).name()
 | 
			
		||||
                     + "(object type: " + getModuleType(address) + ")");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename M>
 | 
			
		||||
M * Environment::getModule(const std::string name) const
 | 
			
		||||
{
 | 
			
		||||
    return getModule<M>(getModuleAddress(name));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
unsigned int Environment::lattice4dSize(void) const
 | 
			
		||||
{
 | 
			
		||||
    return sizeof(typename T::vector_object)/getGrid()->Nsimd();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
void Environment::registerLattice(const unsigned int address,
 | 
			
		||||
                                  const unsigned int Ls)
 | 
			
		||||
{
 | 
			
		||||
    createGrid(Ls);
 | 
			
		||||
    registerObject(address, Ls*lattice4dSize<T>(), Ls);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
void Environment::registerLattice(const std::string name, const unsigned int Ls)
 | 
			
		||||
{
 | 
			
		||||
    createGrid(Ls);
 | 
			
		||||
    registerObject(name, Ls*lattice4dSize<T>(), Ls);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
void Environment::setObject(const unsigned int address, T *object)
 | 
			
		||||
{
 | 
			
		||||
    if (hasRegisteredObject(address))
 | 
			
		||||
    {
 | 
			
		||||
        object_[address].data.reset(new Holder<T>(object));
 | 
			
		||||
        object_[address].type = &typeid(T);
 | 
			
		||||
    }
 | 
			
		||||
    else if (hasObject(address))
 | 
			
		||||
    {
 | 
			
		||||
        HADRON_ERROR("object with address " + std::to_string(address) +
 | 
			
		||||
                     " exists but is not registered");
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        HADRON_ERROR("no object with address " + std::to_string(address));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
void Environment::setObject(const std::string name, T *object)
 | 
			
		||||
{
 | 
			
		||||
    setObject(getObjectAddress(name), object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
T * Environment::getObject(const unsigned int address) const
 | 
			
		||||
{
 | 
			
		||||
    if (hasRegisteredObject(address))
 | 
			
		||||
    {
 | 
			
		||||
        if (auto h = dynamic_cast<Holder<T> *>(object_[address].data.get()))
 | 
			
		||||
        {
 | 
			
		||||
            return h->getPt();
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            HADRON_ERROR("object with address " + std::to_string(address) +
 | 
			
		||||
                         " does not have type '" + typeid(T).name() +
 | 
			
		||||
                         "' (has type '" + getObjectType(address) + "')");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    else if (hasObject(address))
 | 
			
		||||
    {
 | 
			
		||||
        HADRON_ERROR("object with address " + std::to_string(address) +
 | 
			
		||||
                     " exists but is not registered");
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        HADRON_ERROR("no object with address " + std::to_string(address));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
T * Environment::getObject(const std::string name) const
 | 
			
		||||
{
 | 
			
		||||
    return getObject<T>(getObjectAddress(name));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
T * Environment::createLattice(const unsigned int address)
 | 
			
		||||
{
 | 
			
		||||
    GridCartesian *g = getGrid(getObjectLs(address));
 | 
			
		||||
    
 | 
			
		||||
    setObject(address, new T(g));
 | 
			
		||||
    
 | 
			
		||||
    return getObject<T>(address);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
T * Environment::createLattice(const std::string name)
 | 
			
		||||
{
 | 
			
		||||
    return createLattice<T>(getObjectAddress(name));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
END_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
#endif // Hadrons_Environment_hpp_
 | 
			
		||||
							
								
								
									
										106
									
								
								extras/Hadrons/Factory.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								extras/Hadrons/Factory.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,106 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
Source file: extras/Hadrons/Factory.hpp
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2015
 | 
			
		||||
Copyright (C) 2016
 | 
			
		||||
 | 
			
		||||
Author: Antonin Portelli <antonin.portelli@me.com>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
 | 
			
		||||
#ifndef Hadrons_Factory_hpp_
 | 
			
		||||
#define Hadrons_Factory_hpp_
 | 
			
		||||
 | 
			
		||||
#include <Grid/Hadrons/Global.hpp>
 | 
			
		||||
 | 
			
		||||
BEGIN_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                        abstract factory class                              *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
template <typename T>
 | 
			
		||||
class Factory
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    typedef std::function<std::unique_ptr<T>(const std::string)> Func;
 | 
			
		||||
public:
 | 
			
		||||
    // constructor
 | 
			
		||||
    Factory(void) = default;
 | 
			
		||||
    // destructor
 | 
			
		||||
    virtual ~Factory(void) = default;
 | 
			
		||||
    // registration
 | 
			
		||||
    void registerBuilder(const std::string type, const Func &f);
 | 
			
		||||
    // get builder list
 | 
			
		||||
    std::vector<std::string> getBuilderList(void) const;
 | 
			
		||||
    // factory
 | 
			
		||||
    std::unique_ptr<T> create(const std::string type,
 | 
			
		||||
                              const std::string name) const;
 | 
			
		||||
private:
 | 
			
		||||
    std::map<std::string, Func> builder_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                         template implementation                            *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
// registration ////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename T>
 | 
			
		||||
void Factory<T>::registerBuilder(const std::string type, const Func &f)
 | 
			
		||||
{
 | 
			
		||||
    builder_[type] = f;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// get module list /////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename T>
 | 
			
		||||
std::vector<std::string> Factory<T>::getBuilderList(void) const
 | 
			
		||||
{
 | 
			
		||||
    std::vector<std::string> list;
 | 
			
		||||
    
 | 
			
		||||
    for (auto &b: builder_)
 | 
			
		||||
    {
 | 
			
		||||
        list.push_back(b.first);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    return list;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// factory /////////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename T>
 | 
			
		||||
std::unique_ptr<T> Factory<T>::create(const std::string type,
 | 
			
		||||
                                      const std::string name) const
 | 
			
		||||
{
 | 
			
		||||
    Func func;
 | 
			
		||||
    
 | 
			
		||||
    try
 | 
			
		||||
    {
 | 
			
		||||
        func = builder_.at(type);
 | 
			
		||||
    }
 | 
			
		||||
    catch (std::out_of_range &)
 | 
			
		||||
    {
 | 
			
		||||
        HADRON_ERROR("object of type '" + type + "' unknown");
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    return func(name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
END_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
#endif // Hadrons_Factory_hpp_
 | 
			
		||||
							
								
								
									
										329
									
								
								extras/Hadrons/GeneticScheduler.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										329
									
								
								extras/Hadrons/GeneticScheduler.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,329 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
Source file: extras/Hadrons/GeneticScheduler.hpp
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2015
 | 
			
		||||
Copyright (C) 2016
 | 
			
		||||
 | 
			
		||||
Author: Antonin Portelli <antonin.portelli@me.com>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
 | 
			
		||||
#ifndef Hadrons_GeneticScheduler_hpp_
 | 
			
		||||
#define Hadrons_GeneticScheduler_hpp_
 | 
			
		||||
 | 
			
		||||
#include <Grid/Hadrons/Global.hpp>
 | 
			
		||||
#include <Grid/Hadrons/Graph.hpp>
 | 
			
		||||
 | 
			
		||||
BEGIN_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                   Scheduler based on a genetic algorithm                   *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
template <typename T>
 | 
			
		||||
class GeneticScheduler
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    typedef std::vector<T>                   Gene;
 | 
			
		||||
    typedef std::pair<Gene *, Gene *>        GenePair;
 | 
			
		||||
    typedef std::function<int(const Gene &)> ObjFunc;
 | 
			
		||||
    struct Parameters
 | 
			
		||||
    {
 | 
			
		||||
        double       mutationRate;
 | 
			
		||||
        unsigned int popSize, seed;
 | 
			
		||||
    };
 | 
			
		||||
public:
 | 
			
		||||
    // constructor
 | 
			
		||||
    GeneticScheduler(Graph<T> &graph, const ObjFunc &func,
 | 
			
		||||
                     const Parameters &par);
 | 
			
		||||
    // destructor
 | 
			
		||||
    virtual ~GeneticScheduler(void) = default;
 | 
			
		||||
    // access
 | 
			
		||||
    const Gene & getMinSchedule(void);
 | 
			
		||||
    int          getMinValue(void);
 | 
			
		||||
    // breed a new generation
 | 
			
		||||
    void nextGeneration(void);
 | 
			
		||||
    // heuristic benchmarks
 | 
			
		||||
    void benchmarkCrossover(const unsigned int nIt);
 | 
			
		||||
    // print population
 | 
			
		||||
    friend std::ostream & operator<<(std::ostream &out,
 | 
			
		||||
                                     const GeneticScheduler<T> &s)
 | 
			
		||||
    {
 | 
			
		||||
        out << "[";
 | 
			
		||||
        for (auto &p: s.population_)
 | 
			
		||||
        {
 | 
			
		||||
            out << p.first << ", ";
 | 
			
		||||
        }
 | 
			
		||||
        out << "\b\b]";
 | 
			
		||||
        
 | 
			
		||||
        return out;
 | 
			
		||||
    }
 | 
			
		||||
private:
 | 
			
		||||
    // evolution steps
 | 
			
		||||
    void initPopulation(void);
 | 
			
		||||
    void doCrossover(void);
 | 
			
		||||
    void doMutation(void);
 | 
			
		||||
    // genetic operators
 | 
			
		||||
    GenePair selectPair(void);
 | 
			
		||||
    void     crossover(Gene &c1, Gene &c2, const Gene &p1, const Gene &p2);
 | 
			
		||||
    void     mutation(Gene &m, const Gene &c);
 | 
			
		||||
    
 | 
			
		||||
private:
 | 
			
		||||
    Graph<T>                 &graph_;
 | 
			
		||||
    const ObjFunc            &func_;
 | 
			
		||||
    const Parameters         par_;
 | 
			
		||||
    std::multimap<int, Gene> population_;
 | 
			
		||||
    std::mt19937             gen_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                       template implementation                              *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
// constructor /////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename T>
 | 
			
		||||
GeneticScheduler<T>::GeneticScheduler(Graph<T> &graph, const ObjFunc &func,
 | 
			
		||||
                                      const Parameters &par)
 | 
			
		||||
: graph_(graph)
 | 
			
		||||
, func_(func)
 | 
			
		||||
, par_(par)
 | 
			
		||||
{
 | 
			
		||||
    gen_.seed(par_.seed);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// access //////////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename T>
 | 
			
		||||
const typename GeneticScheduler<T>::Gene &
 | 
			
		||||
GeneticScheduler<T>::getMinSchedule(void)
 | 
			
		||||
{
 | 
			
		||||
    return population_.begin()->second;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
int GeneticScheduler<T>::getMinValue(void)
 | 
			
		||||
{
 | 
			
		||||
    return population_.begin()->first;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// breed a new generation //////////////////////////////////////////////////////
 | 
			
		||||
template <typename T>
 | 
			
		||||
void GeneticScheduler<T>::nextGeneration(void)
 | 
			
		||||
{
 | 
			
		||||
    // random initialization of the population if necessary
 | 
			
		||||
    if (population_.size() != par_.popSize)
 | 
			
		||||
    {
 | 
			
		||||
        initPopulation();
 | 
			
		||||
    }
 | 
			
		||||
    LOG(Debug) << "Starting population:\n" << *this << std::endl;
 | 
			
		||||
    
 | 
			
		||||
    // random mutations
 | 
			
		||||
    //PARALLEL_FOR_LOOP
 | 
			
		||||
    for (unsigned int i = 0; i < par_.popSize; ++i)
 | 
			
		||||
    {
 | 
			
		||||
        doMutation();
 | 
			
		||||
    }
 | 
			
		||||
    LOG(Debug) << "After mutations:\n" << *this << std::endl;
 | 
			
		||||
    
 | 
			
		||||
    // mating
 | 
			
		||||
    //PARALLEL_FOR_LOOP
 | 
			
		||||
    for (unsigned int i = 0; i < par_.popSize/2; ++i)
 | 
			
		||||
    {
 | 
			
		||||
        doCrossover();
 | 
			
		||||
    }
 | 
			
		||||
    LOG(Debug) << "After mating:\n" << *this << std::endl;
 | 
			
		||||
    
 | 
			
		||||
    // grim reaper
 | 
			
		||||
    auto it = population_.begin();
 | 
			
		||||
    
 | 
			
		||||
    std::advance(it, par_.popSize);
 | 
			
		||||
    population_.erase(it, population_.end());
 | 
			
		||||
    LOG(Debug) << "After grim reaper:\n" << *this << std::endl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// evolution steps /////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename T>
 | 
			
		||||
void GeneticScheduler<T>::initPopulation(void)
 | 
			
		||||
{
 | 
			
		||||
    population_.clear();
 | 
			
		||||
    for (unsigned int i = 0; i < par_.popSize; ++i)
 | 
			
		||||
    {
 | 
			
		||||
        auto p = graph_.topoSort(gen_);
 | 
			
		||||
        
 | 
			
		||||
        population_.insert(std::make_pair(func_(p), p));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
void GeneticScheduler<T>::doCrossover(void)
 | 
			
		||||
{
 | 
			
		||||
    auto p = selectPair();
 | 
			
		||||
    Gene &p1 = *(p.first), &p2 = *(p.second);
 | 
			
		||||
    Gene c1, c2;
 | 
			
		||||
    
 | 
			
		||||
    crossover(c1, c2, p1, p2);
 | 
			
		||||
    PARALLEL_CRITICAL
 | 
			
		||||
    {
 | 
			
		||||
        population_.insert(std::make_pair(func_(c1), c1));
 | 
			
		||||
        population_.insert(std::make_pair(func_(c2), c2));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
void GeneticScheduler<T>::doMutation(void)
 | 
			
		||||
{
 | 
			
		||||
    std::uniform_real_distribution<double>      mdis(0., 1.);
 | 
			
		||||
    std::uniform_int_distribution<unsigned int> pdis(0, population_.size() - 1);
 | 
			
		||||
    
 | 
			
		||||
    if (mdis(gen_) < par_.mutationRate)
 | 
			
		||||
    {
 | 
			
		||||
        Gene m;
 | 
			
		||||
        auto it = population_.begin();
 | 
			
		||||
        
 | 
			
		||||
        std::advance(it, pdis(gen_));
 | 
			
		||||
        mutation(m, it->second);
 | 
			
		||||
        PARALLEL_CRITICAL
 | 
			
		||||
        {
 | 
			
		||||
            population_.insert(std::make_pair(func_(m), m));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// genetic operators ///////////////////////////////////////////////////////////
 | 
			
		||||
template <typename T>
 | 
			
		||||
typename GeneticScheduler<T>::GenePair GeneticScheduler<T>::selectPair(void)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<double> prob;
 | 
			
		||||
    unsigned int        ind;
 | 
			
		||||
    Gene                *p1, *p2;
 | 
			
		||||
    
 | 
			
		||||
    for (auto &c: population_)
 | 
			
		||||
    {
 | 
			
		||||
        prob.push_back(1./c.first);
 | 
			
		||||
    }
 | 
			
		||||
    do
 | 
			
		||||
    {
 | 
			
		||||
        double probCpy;
 | 
			
		||||
        
 | 
			
		||||
        std::discrete_distribution<unsigned int> dis1(prob.begin(), prob.end());
 | 
			
		||||
        auto rIt = population_.begin();
 | 
			
		||||
        ind = dis1(gen_);
 | 
			
		||||
        std::advance(rIt, ind);
 | 
			
		||||
        p1 = &(rIt->second);
 | 
			
		||||
        probCpy   = prob[ind];
 | 
			
		||||
        prob[ind] = 0.;
 | 
			
		||||
        std::discrete_distribution<unsigned int> dis2(prob.begin(), prob.end());
 | 
			
		||||
        rIt = population_.begin();
 | 
			
		||||
        std::advance(rIt, dis2(gen_));
 | 
			
		||||
        p2 = &(rIt->second);
 | 
			
		||||
        prob[ind] = probCpy;
 | 
			
		||||
    } while (p1 == p2);
 | 
			
		||||
    
 | 
			
		||||
    return std::make_pair(p1, p2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
void GeneticScheduler<T>::crossover(Gene &c1, Gene &c2, const Gene &p1,
 | 
			
		||||
                                    const Gene &p2)
 | 
			
		||||
{
 | 
			
		||||
    Gene                                        buf;
 | 
			
		||||
    std::uniform_int_distribution<unsigned int> dis(0, p1.size() - 1);
 | 
			
		||||
    unsigned int                                cut = dis(gen_);
 | 
			
		||||
    
 | 
			
		||||
    c1.clear();
 | 
			
		||||
    buf = p2;
 | 
			
		||||
    for (unsigned int i = 0; i < cut; ++i)
 | 
			
		||||
    {
 | 
			
		||||
        c1.push_back(p1[i]);
 | 
			
		||||
        buf.erase(std::find(buf.begin(), buf.end(), p1[i]));
 | 
			
		||||
    }
 | 
			
		||||
    for (unsigned int i = 0; i < buf.size(); ++i)
 | 
			
		||||
    {
 | 
			
		||||
        c1.push_back(buf[i]);
 | 
			
		||||
    }
 | 
			
		||||
    c2.clear();
 | 
			
		||||
    buf = p2;
 | 
			
		||||
    for (unsigned int i = cut; i < p1.size(); ++i)
 | 
			
		||||
    {
 | 
			
		||||
        buf.erase(std::find(buf.begin(), buf.end(), p1[i]));
 | 
			
		||||
    }
 | 
			
		||||
    for (unsigned int i = 0; i < buf.size(); ++i)
 | 
			
		||||
    {
 | 
			
		||||
        c2.push_back(buf[i]);
 | 
			
		||||
    }
 | 
			
		||||
    for (unsigned int i = cut; i < p1.size(); ++i)
 | 
			
		||||
    {
 | 
			
		||||
        c2.push_back(p1[i]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
void GeneticScheduler<T>::mutation(Gene &m, const Gene &c)
 | 
			
		||||
{
 | 
			
		||||
    Gene                                        buf;
 | 
			
		||||
    std::uniform_int_distribution<unsigned int> dis(0, c.size() - 1);
 | 
			
		||||
    unsigned int                                cut = dis(gen_);
 | 
			
		||||
    Graph<T>                                    g1 = graph_, g2 = graph_;
 | 
			
		||||
    
 | 
			
		||||
    for (unsigned int i = 0; i < cut; ++i)
 | 
			
		||||
    {
 | 
			
		||||
        g1.removeVertex(c[i]);
 | 
			
		||||
    }
 | 
			
		||||
    for (unsigned int i = cut; i < c.size(); ++i)
 | 
			
		||||
    {
 | 
			
		||||
        g2.removeVertex(c[i]);
 | 
			
		||||
    }
 | 
			
		||||
    if (g1.size() > 0)
 | 
			
		||||
    {
 | 
			
		||||
        buf = g1.topoSort(gen_);
 | 
			
		||||
    }
 | 
			
		||||
    if (g2.size() > 0)
 | 
			
		||||
    {
 | 
			
		||||
        m = g2.topoSort(gen_);
 | 
			
		||||
    }
 | 
			
		||||
    for (unsigned int i = cut; i < c.size(); ++i)
 | 
			
		||||
    {
 | 
			
		||||
        m.push_back(buf[i - cut]);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
void GeneticScheduler<T>::benchmarkCrossover(const unsigned int nIt)
 | 
			
		||||
{
 | 
			
		||||
    Gene   p1, p2, c1, c2;
 | 
			
		||||
    double neg = 0., eq = 0., pos = 0., total;
 | 
			
		||||
    int    improvement;
 | 
			
		||||
    
 | 
			
		||||
    LOG(Message) << "Benchmarking crossover..." << std::endl;
 | 
			
		||||
    for (unsigned int i = 0; i < nIt; ++i)
 | 
			
		||||
    {
 | 
			
		||||
        p1 = graph_.topoSort(gen_);
 | 
			
		||||
        p2 = graph_.topoSort(gen_);
 | 
			
		||||
        crossover(c1, c2, p1, p2);
 | 
			
		||||
        improvement = (func_(c1) + func_(c2) - func_(p1) - func_(p2))/2;
 | 
			
		||||
        if (improvement < 0) neg++; else if (improvement == 0) eq++; else pos++;
 | 
			
		||||
    }
 | 
			
		||||
    total = neg + eq + pos;
 | 
			
		||||
    LOG(Message) << "  -: " << neg/total << "  =: " << eq/total
 | 
			
		||||
                 << "  +: " << pos/total << std::endl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
END_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
#endif // Hadrons_GeneticScheduler_hpp_
 | 
			
		||||
							
								
								
									
										82
									
								
								extras/Hadrons/Global.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								extras/Hadrons/Global.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,82 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
Source file: extras/Hadrons/Global.cc
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2015
 | 
			
		||||
Copyright (C) 2016
 | 
			
		||||
 | 
			
		||||
Author: Antonin Portelli <antonin.portelli@me.com>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
 | 
			
		||||
#include <Grid/Hadrons/Global.hpp>
 | 
			
		||||
 | 
			
		||||
using namespace Grid;
 | 
			
		||||
using namespace QCD;
 | 
			
		||||
using namespace Hadrons;
 | 
			
		||||
 | 
			
		||||
HadronsLogger Hadrons::HadronsLogError(1,"Error");
 | 
			
		||||
HadronsLogger Hadrons::HadronsLogWarning(1,"Warning");
 | 
			
		||||
HadronsLogger Hadrons::HadronsLogMessage(1,"Message");
 | 
			
		||||
HadronsLogger Hadrons::HadronsLogIterative(1,"Iterative");
 | 
			
		||||
HadronsLogger Hadrons::HadronsLogDebug(1,"Debug");
 | 
			
		||||
 | 
			
		||||
// pretty size formatting //////////////////////////////////////////////////////
 | 
			
		||||
std::string Hadrons::sizeString(long unsigned int bytes)
 | 
			
		||||
 | 
			
		||||
{
 | 
			
		||||
    constexpr unsigned int bufSize = 256;
 | 
			
		||||
    const char             *suffixes[7] = {"", "K", "M", "G", "T", "P", "E"};
 | 
			
		||||
    char                   buf[256];
 | 
			
		||||
    long unsigned int      s     = 0;
 | 
			
		||||
    double                 count = bytes;
 | 
			
		||||
    
 | 
			
		||||
    while (count >= 1024 && s < 7)
 | 
			
		||||
    {
 | 
			
		||||
        s++;
 | 
			
		||||
        count /= 1024;
 | 
			
		||||
    }
 | 
			
		||||
    if (count - floor(count) == 0.0)
 | 
			
		||||
    {
 | 
			
		||||
        snprintf(buf, bufSize, "%d %sB", (int)count, suffixes[s]);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        snprintf(buf, bufSize, "%.1f %sB", count, suffixes[s]);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    return std::string(buf);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// type utilities //////////////////////////////////////////////////////////////
 | 
			
		||||
constexpr unsigned int maxNameSize = 1024u;
 | 
			
		||||
 | 
			
		||||
std::string Hadrons::typeName(const std::type_info *info)
 | 
			
		||||
{
 | 
			
		||||
    char        *buf;
 | 
			
		||||
    std::string name;
 | 
			
		||||
    
 | 
			
		||||
    buf  = abi::__cxa_demangle(info->name(), nullptr, nullptr, nullptr);
 | 
			
		||||
    name = buf;
 | 
			
		||||
    free(buf);
 | 
			
		||||
    
 | 
			
		||||
    return name;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										159
									
								
								extras/Hadrons/Global.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										159
									
								
								extras/Hadrons/Global.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,159 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
Source file: extras/Hadrons/Global.hpp
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2015
 | 
			
		||||
Copyright (C) 2016
 | 
			
		||||
 | 
			
		||||
Author: Antonin Portelli <antonin.portelli@me.com>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
 | 
			
		||||
#ifndef Hadrons_Global_hpp_
 | 
			
		||||
#define Hadrons_Global_hpp_
 | 
			
		||||
 | 
			
		||||
#include <set>
 | 
			
		||||
#include <stack>
 | 
			
		||||
#include <Grid/Grid.h>
 | 
			
		||||
#include <cxxabi.h>
 | 
			
		||||
 | 
			
		||||
#define BEGIN_HADRONS_NAMESPACE \
 | 
			
		||||
namespace Grid {\
 | 
			
		||||
using namespace QCD;\
 | 
			
		||||
namespace Hadrons {\
 | 
			
		||||
using Grid::operator<<;
 | 
			
		||||
#define END_HADRONS_NAMESPACE }}
 | 
			
		||||
 | 
			
		||||
#define BEGIN_MODULE_NAMESPACE(name)\
 | 
			
		||||
namespace name {\
 | 
			
		||||
using Grid::operator<<;
 | 
			
		||||
#define END_MODULE_NAMESPACE }
 | 
			
		||||
 | 
			
		||||
/* the 'using Grid::operator<<;' statement prevents a very nasty compilation
 | 
			
		||||
 * error with GCC 5 (clang & GCC 6 compile fine without it).
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
// FIXME: find a way to do that in a more general fashion
 | 
			
		||||
#ifndef FIMPL
 | 
			
		||||
#define FIMPL WilsonImplR
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
BEGIN_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
// type aliases
 | 
			
		||||
#define TYPE_ALIASES(FImpl, suffix)\
 | 
			
		||||
typedef FermionOperator<FImpl>                       FMat##suffix;             \
 | 
			
		||||
typedef typename FImpl::FermionField                 FermionField##suffix;     \
 | 
			
		||||
typedef typename FImpl::PropagatorField              PropagatorField##suffix;  \
 | 
			
		||||
typedef typename FImpl::SitePropagator               SitePropagator##suffix;   \
 | 
			
		||||
typedef typename FImpl::DoubledGaugeField            DoubledGaugeField##suffix;\
 | 
			
		||||
typedef std::function<void(FermionField##suffix &,                             \
 | 
			
		||||
                      const FermionField##suffix &)> SolverFn##suffix;
 | 
			
		||||
 | 
			
		||||
// logger
 | 
			
		||||
class HadronsLogger: public Logger
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    HadronsLogger(int on, std::string nm): Logger("Hadrons", on, nm,
 | 
			
		||||
                                                  GridLogColours, "BLACK"){};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define LOG(channel) std::cout << HadronsLog##channel
 | 
			
		||||
#define HADRON_ERROR(msg)\
 | 
			
		||||
LOG(Error) << msg << " (" << __FUNCTION__ << " at " << __FILE__ << ":"\
 | 
			
		||||
           << __LINE__ << ")" << std::endl;\
 | 
			
		||||
abort();
 | 
			
		||||
 | 
			
		||||
#define DEBUG_VAR(var) LOG(Debug) << #var << "= " << (var) << std::endl;
 | 
			
		||||
 | 
			
		||||
extern HadronsLogger HadronsLogError;
 | 
			
		||||
extern HadronsLogger HadronsLogWarning;
 | 
			
		||||
extern HadronsLogger HadronsLogMessage;
 | 
			
		||||
extern HadronsLogger HadronsLogIterative;
 | 
			
		||||
extern HadronsLogger HadronsLogDebug;
 | 
			
		||||
 | 
			
		||||
// singleton pattern
 | 
			
		||||
#define SINGLETON(name)\
 | 
			
		||||
public:\
 | 
			
		||||
    name(const name &e) = delete;\
 | 
			
		||||
    void operator=(const name &e) = delete;\
 | 
			
		||||
    static name & getInstance(void)\
 | 
			
		||||
    {\
 | 
			
		||||
        static name e;\
 | 
			
		||||
        return e;\
 | 
			
		||||
    }\
 | 
			
		||||
private:\
 | 
			
		||||
    name(void);
 | 
			
		||||
 | 
			
		||||
#define SINGLETON_DEFCTOR(name)\
 | 
			
		||||
public:\
 | 
			
		||||
    name(const name &e) = delete;\
 | 
			
		||||
    void operator=(const name &e) = delete;\
 | 
			
		||||
    static name & getInstance(void)\
 | 
			
		||||
    {\
 | 
			
		||||
        static name e;\
 | 
			
		||||
        return e;\
 | 
			
		||||
    }\
 | 
			
		||||
private:\
 | 
			
		||||
    name(void) = default;
 | 
			
		||||
 | 
			
		||||
// pretty size formating
 | 
			
		||||
std::string sizeString(long unsigned int bytes);
 | 
			
		||||
 | 
			
		||||
// type utilities
 | 
			
		||||
template <typename T>
 | 
			
		||||
const std::type_info * typeIdPt(const T &x)
 | 
			
		||||
{
 | 
			
		||||
    return &typeid(x);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string typeName(const std::type_info *info);
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
const std::type_info * typeIdPt(void)
 | 
			
		||||
{
 | 
			
		||||
    return &typeid(T);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
std::string typeName(const T &x)
 | 
			
		||||
{
 | 
			
		||||
    return typeName(typeIdPt(x));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
std::string typeName(void)
 | 
			
		||||
{
 | 
			
		||||
    return typeName(typeIdPt<T>());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// default writers/readers
 | 
			
		||||
#ifdef HAVE_HDF5
 | 
			
		||||
typedef Hdf5Reader CorrReader;
 | 
			
		||||
typedef Hdf5Writer CorrWriter;
 | 
			
		||||
#else
 | 
			
		||||
typedef XmlReader CorrReader;
 | 
			
		||||
typedef XmlWriter CorrWriter;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
END_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
#endif // Hadrons_Global_hpp_
 | 
			
		||||
							
								
								
									
										760
									
								
								extras/Hadrons/Graph.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										760
									
								
								extras/Hadrons/Graph.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,760 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
Source file: extras/Hadrons/Graph.hpp
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2015
 | 
			
		||||
Copyright (C) 2016
 | 
			
		||||
 | 
			
		||||
Author: Antonin Portelli <antonin.portelli@me.com>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
 | 
			
		||||
#ifndef Hadrons_Graph_hpp_
 | 
			
		||||
#define Hadrons_Graph_hpp_
 | 
			
		||||
 | 
			
		||||
#include <Grid/Hadrons/Global.hpp>
 | 
			
		||||
 | 
			
		||||
BEGIN_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                          Oriented graph class                              *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
// I/O for edges
 | 
			
		||||
template <typename T>
 | 
			
		||||
std::ostream & operator<<(std::ostream &out, const std::pair<T, T> &e)
 | 
			
		||||
{
 | 
			
		||||
    out << "\""  << e.first << "\" -> \"" << e.second << "\"";
 | 
			
		||||
    
 | 
			
		||||
    return out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// main class
 | 
			
		||||
template <typename T>
 | 
			
		||||
class Graph
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    typedef std::pair<T, T> Edge;
 | 
			
		||||
public:
 | 
			
		||||
    // constructor
 | 
			
		||||
    Graph(void);
 | 
			
		||||
    // destructor
 | 
			
		||||
    virtual ~Graph(void) = default;
 | 
			
		||||
    // access
 | 
			
		||||
    void           addVertex(const T &value);
 | 
			
		||||
    void           addEdge(const Edge &e);
 | 
			
		||||
    void           addEdge(const T &start, const T &end);
 | 
			
		||||
    std::vector<T> getVertices(void) const;
 | 
			
		||||
    void           removeVertex(const T &value);
 | 
			
		||||
    void           removeEdge(const Edge &e);
 | 
			
		||||
    void           removeEdge(const T &start, const T &end);
 | 
			
		||||
    unsigned int   size(void) const;
 | 
			
		||||
    // tests
 | 
			
		||||
    bool gotValue(const T &value) const;
 | 
			
		||||
    // graph topological manipulations
 | 
			
		||||
    std::vector<T>              getAdjacentVertices(const T &value) const;
 | 
			
		||||
    std::vector<T>              getChildren(const T &value) const;
 | 
			
		||||
    std::vector<T>              getParents(const T &value) const;
 | 
			
		||||
    std::vector<T>              getRoots(void) const;
 | 
			
		||||
    std::vector<Graph<T>>       getConnectedComponents(void) const;
 | 
			
		||||
    std::vector<T>              topoSort(void);
 | 
			
		||||
    template <typename Gen>
 | 
			
		||||
    std::vector<T>              topoSort(Gen &gen);
 | 
			
		||||
    std::vector<std::vector<T>> allTopoSort(void);
 | 
			
		||||
    // I/O
 | 
			
		||||
    friend std::ostream & operator<<(std::ostream &out, const Graph<T> &g)
 | 
			
		||||
    {
 | 
			
		||||
        out << "{";
 | 
			
		||||
        for (auto &e: g.edgeSet_)
 | 
			
		||||
        {
 | 
			
		||||
            out << e << ", ";
 | 
			
		||||
        }
 | 
			
		||||
        if (g.edgeSet_.size() != 0)
 | 
			
		||||
        {
 | 
			
		||||
            out << "\b\b";
 | 
			
		||||
        }
 | 
			
		||||
        out << "}";
 | 
			
		||||
        
 | 
			
		||||
        return out;
 | 
			
		||||
    }
 | 
			
		||||
private:
 | 
			
		||||
    // vertex marking
 | 
			
		||||
    void      mark(const T &value, const bool doMark = true);
 | 
			
		||||
    void      markAll(const bool doMark = true);
 | 
			
		||||
    void      unmark(const T &value);
 | 
			
		||||
    void      unmarkAll(void);
 | 
			
		||||
    bool      isMarked(const T &value) const;
 | 
			
		||||
    const T * getFirstMarked(const bool isMarked = true) const;
 | 
			
		||||
    template <typename Gen>
 | 
			
		||||
    const T * getRandomMarked(const bool isMarked, Gen &gen);
 | 
			
		||||
    const T * getFirstUnmarked(void) const;
 | 
			
		||||
    template <typename Gen>
 | 
			
		||||
    const T * getRandomUnmarked(Gen &gen);
 | 
			
		||||
    // prune marked/unmarked vertices
 | 
			
		||||
    void removeMarked(const bool isMarked = true);
 | 
			
		||||
    void removeUnmarked(void);
 | 
			
		||||
    // depth-first search marking
 | 
			
		||||
    void depthFirstSearch(void);
 | 
			
		||||
    void depthFirstSearch(const T &root);
 | 
			
		||||
private:
 | 
			
		||||
    std::map<T, bool>  isMarked_;
 | 
			
		||||
    std::set<Edge>     edgeSet_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// build depedency matrix from topological sorts
 | 
			
		||||
template <typename T>
 | 
			
		||||
std::map<T, std::map<T, bool>>
 | 
			
		||||
makeDependencyMatrix(const std::vector<std::vector<T>> &topSort);
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                       template implementation                              *
 | 
			
		||||
 ******************************************************************************
 | 
			
		||||
 * in all the following V is the number of vertex and E is the number of edge
 | 
			
		||||
 * in the worst case E = V^2
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
// constructor /////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename T>
 | 
			
		||||
Graph<T>::Graph(void)
 | 
			
		||||
{}
 | 
			
		||||
 | 
			
		||||
// access //////////////////////////////////////////////////////////////////////
 | 
			
		||||
// complexity: log(V)
 | 
			
		||||
template <typename T>
 | 
			
		||||
void Graph<T>::addVertex(const T &value)
 | 
			
		||||
{
 | 
			
		||||
    isMarked_[value] = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// complexity: O(log(V))
 | 
			
		||||
template <typename T>
 | 
			
		||||
void Graph<T>::addEdge(const Edge &e)
 | 
			
		||||
{
 | 
			
		||||
    addVertex(e.first);
 | 
			
		||||
    addVertex(e.second);
 | 
			
		||||
    edgeSet_.insert(e);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// complexity: O(log(V))
 | 
			
		||||
template <typename T>
 | 
			
		||||
void Graph<T>::addEdge(const T &start, const T &end)
 | 
			
		||||
{
 | 
			
		||||
    addEdge(Edge(start, end));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
std::vector<T> Graph<T>::getVertices(void) const
 | 
			
		||||
{
 | 
			
		||||
    std::vector<T> vertex;
 | 
			
		||||
    
 | 
			
		||||
    for (auto &v: isMarked_)
 | 
			
		||||
    {
 | 
			
		||||
        vertex.push_back(v.first);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    return vertex;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// complexity: O(V*log(V))
 | 
			
		||||
template <typename T>
 | 
			
		||||
void Graph<T>::removeVertex(const T &value)
 | 
			
		||||
{
 | 
			
		||||
    // remove vertex from the mark table
 | 
			
		||||
    auto vIt = isMarked_.find(value);
 | 
			
		||||
    
 | 
			
		||||
    if (vIt != isMarked_.end())
 | 
			
		||||
    {
 | 
			
		||||
        isMarked_.erase(vIt);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        HADRON_ERROR("vertex " << value << " does not exists");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // remove all edges containing the vertex
 | 
			
		||||
    auto pred = [&value](const Edge &e)
 | 
			
		||||
    {
 | 
			
		||||
        return ((e.first == value) or (e.second == value));
 | 
			
		||||
    };
 | 
			
		||||
    auto eIt = find_if(edgeSet_.begin(), edgeSet_.end(), pred);
 | 
			
		||||
    
 | 
			
		||||
    while (eIt != edgeSet_.end())
 | 
			
		||||
    {
 | 
			
		||||
        edgeSet_.erase(eIt);
 | 
			
		||||
        eIt = find_if(edgeSet_.begin(), edgeSet_.end(), pred);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// complexity: O(log(V))
 | 
			
		||||
template <typename T>
 | 
			
		||||
void Graph<T>::removeEdge(const Edge &e)
 | 
			
		||||
{
 | 
			
		||||
    auto eIt = edgeSet_.find(e);
 | 
			
		||||
    
 | 
			
		||||
    if (eIt != edgeSet_.end())
 | 
			
		||||
    {
 | 
			
		||||
        edgeSet_.erase(eIt);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        HADRON_ERROR("edge "  << e << " does not exists");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// complexity: O(log(V))
 | 
			
		||||
template <typename T>
 | 
			
		||||
void Graph<T>::removeEdge(const T &start, const T &end)
 | 
			
		||||
{
 | 
			
		||||
    removeEdge(Edge(start, end));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// complexity: O(1)
 | 
			
		||||
template <typename T>
 | 
			
		||||
unsigned int Graph<T>::size(void) const
 | 
			
		||||
{
 | 
			
		||||
    return isMarked_.size();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// tests ///////////////////////////////////////////////////////////////////////
 | 
			
		||||
// complexity: O(log(V))
 | 
			
		||||
template <typename T>
 | 
			
		||||
bool Graph<T>::gotValue(const T &value) const
 | 
			
		||||
{
 | 
			
		||||
    auto it = isMarked_.find(value);
 | 
			
		||||
    
 | 
			
		||||
    if (it == isMarked_.end())
 | 
			
		||||
    {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// vertex marking //////////////////////////////////////////////////////////////
 | 
			
		||||
// complexity: O(log(V))
 | 
			
		||||
template <typename T>
 | 
			
		||||
void Graph<T>::mark(const T &value, const bool doMark)
 | 
			
		||||
{
 | 
			
		||||
    if (gotValue(value))
 | 
			
		||||
    {
 | 
			
		||||
        isMarked_[value] = doMark;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        HADRON_ERROR("vertex " << value << " does not exists");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// complexity: O(V*log(V))
 | 
			
		||||
template <typename T>
 | 
			
		||||
void Graph<T>::markAll(const bool doMark)
 | 
			
		||||
{
 | 
			
		||||
    for (auto &v: isMarked_)
 | 
			
		||||
    {
 | 
			
		||||
        mark(v.first, doMark);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// complexity: O(log(V))
 | 
			
		||||
template <typename T>
 | 
			
		||||
void Graph<T>::unmark(const T &value)
 | 
			
		||||
{
 | 
			
		||||
    mark(value, false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// complexity: O(V*log(V))
 | 
			
		||||
template <typename T>
 | 
			
		||||
void Graph<T>::unmarkAll(void)
 | 
			
		||||
{
 | 
			
		||||
    markAll(false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// complexity: O(log(V))
 | 
			
		||||
template <typename T>
 | 
			
		||||
bool Graph<T>::isMarked(const T &value) const
 | 
			
		||||
{
 | 
			
		||||
    if (gotValue(value))
 | 
			
		||||
    {
 | 
			
		||||
        return isMarked_.at(value);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        HADRON_ERROR("vertex " << value << " does not exists");
 | 
			
		||||
        
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// complexity: O(log(V))
 | 
			
		||||
template <typename T>
 | 
			
		||||
const T * Graph<T>::getFirstMarked(const bool isMarked) const
 | 
			
		||||
{
 | 
			
		||||
    auto pred = [&isMarked](const std::pair<T, bool> &v)
 | 
			
		||||
    {
 | 
			
		||||
        return (v.second == isMarked);
 | 
			
		||||
    };
 | 
			
		||||
    auto vIt = std::find_if(isMarked_.begin(), isMarked_.end(), pred);
 | 
			
		||||
    
 | 
			
		||||
    if (vIt != isMarked_.end())
 | 
			
		||||
    {
 | 
			
		||||
        return &(vIt->first);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// complexity: O(log(V))
 | 
			
		||||
template <typename T>
 | 
			
		||||
template <typename Gen>
 | 
			
		||||
const T * Graph<T>::getRandomMarked(const bool isMarked, Gen &gen)
 | 
			
		||||
{
 | 
			
		||||
    auto pred = [&isMarked](const std::pair<T, bool> &v)
 | 
			
		||||
    {
 | 
			
		||||
        return (v.second == isMarked);
 | 
			
		||||
    };
 | 
			
		||||
    std::uniform_int_distribution<unsigned int> dis(0, size() - 1);
 | 
			
		||||
    auto                                        rIt = isMarked_.begin();
 | 
			
		||||
    
 | 
			
		||||
    std::advance(rIt, dis(gen));
 | 
			
		||||
    auto vIt = std::find_if(rIt, isMarked_.end(), pred);
 | 
			
		||||
    if (vIt != isMarked_.end())
 | 
			
		||||
    {
 | 
			
		||||
        return &(vIt->first);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        vIt = std::find_if(isMarked_.begin(), rIt, pred);
 | 
			
		||||
        if (vIt != rIt)
 | 
			
		||||
        {
 | 
			
		||||
            return &(vIt->first);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            return nullptr;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// complexity: O(log(V))
 | 
			
		||||
template <typename T>
 | 
			
		||||
const T * Graph<T>::getFirstUnmarked(void) const
 | 
			
		||||
{
 | 
			
		||||
    return getFirstMarked(false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// complexity: O(log(V))
 | 
			
		||||
template <typename T>
 | 
			
		||||
template <typename Gen>
 | 
			
		||||
const T * Graph<T>::getRandomUnmarked(Gen &gen)
 | 
			
		||||
{
 | 
			
		||||
    return getRandomMarked(false, gen);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// prune marked/unmarked vertices //////////////////////////////////////////////
 | 
			
		||||
// complexity: O(V^2*log(V))
 | 
			
		||||
template <typename T>
 | 
			
		||||
void Graph<T>::removeMarked(const bool isMarked)
 | 
			
		||||
{
 | 
			
		||||
    auto isMarkedCopy = isMarked_;
 | 
			
		||||
    
 | 
			
		||||
    for (auto &v: isMarkedCopy)
 | 
			
		||||
    {
 | 
			
		||||
        if (v.second == isMarked)
 | 
			
		||||
        {
 | 
			
		||||
            removeVertex(v.first);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// complexity: O(V^2*log(V))
 | 
			
		||||
template <typename T>
 | 
			
		||||
void Graph<T>::removeUnmarked(void)
 | 
			
		||||
{
 | 
			
		||||
    removeMarked(false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// depth-first search marking //////////////////////////////////////////////////
 | 
			
		||||
// complexity: O(V*log(V))
 | 
			
		||||
template <typename T>
 | 
			
		||||
void Graph<T>::depthFirstSearch(void)
 | 
			
		||||
{
 | 
			
		||||
    depthFirstSearch(isMarked_.begin()->first);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// complexity: O(V*log(V))
 | 
			
		||||
template <typename T>
 | 
			
		||||
void Graph<T>::depthFirstSearch(const T &root)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<T> adjacentVertex;
 | 
			
		||||
    
 | 
			
		||||
    mark(root);
 | 
			
		||||
    adjacentVertex = getAdjacentVertices(root);
 | 
			
		||||
    for (auto &v: adjacentVertex)
 | 
			
		||||
    {
 | 
			
		||||
        if (!isMarked(v))
 | 
			
		||||
        {
 | 
			
		||||
            depthFirstSearch(v);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// graph topological manipulations /////////////////////////////////////////////
 | 
			
		||||
// complexity: O(V*log(V))
 | 
			
		||||
template <typename T>
 | 
			
		||||
std::vector<T> Graph<T>::getAdjacentVertices(const T &value) const
 | 
			
		||||
{
 | 
			
		||||
    std::vector<T> adjacentVertex;
 | 
			
		||||
    
 | 
			
		||||
    auto pred = [&value](const Edge &e)
 | 
			
		||||
    {
 | 
			
		||||
        return ((e.first == value) or (e.second == value));
 | 
			
		||||
    };
 | 
			
		||||
    auto eIt = find_if(edgeSet_.begin(), edgeSet_.end(), pred);
 | 
			
		||||
    
 | 
			
		||||
    while (eIt != edgeSet_.end())
 | 
			
		||||
    {
 | 
			
		||||
        if (eIt->first == value)
 | 
			
		||||
        {
 | 
			
		||||
            adjacentVertex.push_back((*eIt).second);
 | 
			
		||||
        }
 | 
			
		||||
        else if (eIt->second == value)
 | 
			
		||||
        {
 | 
			
		||||
            adjacentVertex.push_back((*eIt).first);
 | 
			
		||||
        }
 | 
			
		||||
        eIt = find_if(++eIt, edgeSet_.end(), pred);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    return adjacentVertex;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// complexity: O(V*log(V))
 | 
			
		||||
template <typename T>
 | 
			
		||||
std::vector<T> Graph<T>::getChildren(const T &value) const
 | 
			
		||||
{
 | 
			
		||||
    std::vector<T> child;
 | 
			
		||||
    
 | 
			
		||||
    auto pred = [&value](const Edge &e)
 | 
			
		||||
    {
 | 
			
		||||
        return (e.first == value);
 | 
			
		||||
    };
 | 
			
		||||
    auto eIt = find_if(edgeSet_.begin(), edgeSet_.end(), pred);
 | 
			
		||||
    
 | 
			
		||||
    while (eIt != edgeSet_.end())
 | 
			
		||||
    {
 | 
			
		||||
        child.push_back((*eIt).second);
 | 
			
		||||
        eIt = find_if(++eIt, edgeSet_.end(), pred);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    return child;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// complexity: O(V*log(V))
 | 
			
		||||
template <typename T>
 | 
			
		||||
std::vector<T> Graph<T>::getParents(const T &value) const
 | 
			
		||||
{
 | 
			
		||||
    std::vector<T> parent;
 | 
			
		||||
    
 | 
			
		||||
    auto pred = [&value](const Edge &e)
 | 
			
		||||
    {
 | 
			
		||||
        return (e.second == value);
 | 
			
		||||
    };
 | 
			
		||||
    auto eIt = find_if(edgeSet_.begin(), edgeSet_.end(), pred);
 | 
			
		||||
    
 | 
			
		||||
    while (eIt != edgeSet_.end())
 | 
			
		||||
    {
 | 
			
		||||
        parent.push_back((*eIt).first);
 | 
			
		||||
        eIt = find_if(++eIt, edgeSet_.end(), pred);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    return parent;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// complexity: O(V^2*log(V))
 | 
			
		||||
template <typename T>
 | 
			
		||||
std::vector<T> Graph<T>::getRoots(void) const
 | 
			
		||||
{
 | 
			
		||||
    std::vector<T> root;
 | 
			
		||||
    
 | 
			
		||||
    for (auto &v: isMarked_)
 | 
			
		||||
    {
 | 
			
		||||
        auto parent = getParents(v.first);
 | 
			
		||||
        
 | 
			
		||||
        if (parent.size() == 0)
 | 
			
		||||
        {
 | 
			
		||||
            root.push_back(v.first);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    return root;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// complexity: O(V^2*log(V))
 | 
			
		||||
template <typename T>
 | 
			
		||||
std::vector<Graph<T>> Graph<T>::getConnectedComponents(void) const
 | 
			
		||||
{
 | 
			
		||||
    std::vector<Graph<T>> res;
 | 
			
		||||
    Graph<T>              copy(*this);
 | 
			
		||||
    
 | 
			
		||||
    while (copy.size() > 0)
 | 
			
		||||
    {
 | 
			
		||||
        copy.depthFirstSearch();
 | 
			
		||||
        res.push_back(copy);
 | 
			
		||||
        res.back().removeUnmarked();
 | 
			
		||||
        res.back().unmarkAll();
 | 
			
		||||
        copy.removeMarked();
 | 
			
		||||
        copy.unmarkAll();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// topological sort using a directed DFS algorithm
 | 
			
		||||
// complexity: O(V*log(V))
 | 
			
		||||
template <typename T>
 | 
			
		||||
std::vector<T> Graph<T>::topoSort(void)
 | 
			
		||||
{
 | 
			
		||||
    std::stack<T>     buf;
 | 
			
		||||
    std::vector<T>    res;
 | 
			
		||||
    const T           *vPt;
 | 
			
		||||
    std::map<T, bool> tmpMarked(isMarked_);
 | 
			
		||||
 | 
			
		||||
    // visit function
 | 
			
		||||
    std::function<void(const T &)> visit = [&](const T &v)
 | 
			
		||||
    {
 | 
			
		||||
        if (tmpMarked.at(v))
 | 
			
		||||
        {
 | 
			
		||||
            HADRON_ERROR("cannot topologically sort a cyclic graph");
 | 
			
		||||
        }
 | 
			
		||||
        if (!isMarked(v))
 | 
			
		||||
        {
 | 
			
		||||
            std::vector<T> child = getChildren(v);
 | 
			
		||||
 | 
			
		||||
            tmpMarked[v] = true;
 | 
			
		||||
            for (auto &c: child)
 | 
			
		||||
            {
 | 
			
		||||
                visit(c);
 | 
			
		||||
            }
 | 
			
		||||
            mark(v);
 | 
			
		||||
            tmpMarked[v] = false;
 | 
			
		||||
            buf.push(v);
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
    // reset temporary marks
 | 
			
		||||
    for (auto &v: tmpMarked)
 | 
			
		||||
    {
 | 
			
		||||
        tmpMarked.at(v.first) = false;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // loop on unmarked vertices
 | 
			
		||||
    unmarkAll();
 | 
			
		||||
    vPt = getFirstUnmarked();
 | 
			
		||||
    while (vPt)
 | 
			
		||||
    {
 | 
			
		||||
        visit(*vPt);
 | 
			
		||||
        vPt = getFirstUnmarked();
 | 
			
		||||
    }
 | 
			
		||||
    unmarkAll();
 | 
			
		||||
    
 | 
			
		||||
    // create result vector
 | 
			
		||||
    while (!buf.empty())
 | 
			
		||||
    {
 | 
			
		||||
        res.push_back(buf.top());
 | 
			
		||||
        buf.pop();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// random version of the topological sort
 | 
			
		||||
// complexity: O(V*log(V))
 | 
			
		||||
template <typename T>
 | 
			
		||||
template <typename Gen>
 | 
			
		||||
std::vector<T> Graph<T>::topoSort(Gen &gen)
 | 
			
		||||
{
 | 
			
		||||
    std::stack<T>     buf;
 | 
			
		||||
    std::vector<T>    res;
 | 
			
		||||
    const T           *vPt;
 | 
			
		||||
    std::map<T, bool> tmpMarked(isMarked_);
 | 
			
		||||
    
 | 
			
		||||
    // visit function
 | 
			
		||||
    std::function<void(const T &)> visit = [&](const T &v)
 | 
			
		||||
    {
 | 
			
		||||
        if (tmpMarked.at(v))
 | 
			
		||||
        {
 | 
			
		||||
            HADRON_ERROR("cannot topologically sort a cyclic graph");
 | 
			
		||||
        }
 | 
			
		||||
        if (!isMarked(v))
 | 
			
		||||
        {
 | 
			
		||||
            std::vector<T> child = getChildren(v);
 | 
			
		||||
            
 | 
			
		||||
            tmpMarked[v] = true;
 | 
			
		||||
            std::shuffle(child.begin(), child.end(), gen);
 | 
			
		||||
            for (auto &c: child)
 | 
			
		||||
            {
 | 
			
		||||
                visit(c);
 | 
			
		||||
            }
 | 
			
		||||
            mark(v);
 | 
			
		||||
            tmpMarked[v] = false;
 | 
			
		||||
            buf.push(v);
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
    // reset temporary marks
 | 
			
		||||
    for (auto &v: tmpMarked)
 | 
			
		||||
    {
 | 
			
		||||
        tmpMarked.at(v.first) = false;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // loop on unmarked vertices
 | 
			
		||||
    unmarkAll();
 | 
			
		||||
    vPt = getRandomUnmarked(gen);
 | 
			
		||||
    while (vPt)
 | 
			
		||||
    {
 | 
			
		||||
        visit(*vPt);
 | 
			
		||||
        vPt = getRandomUnmarked(gen);
 | 
			
		||||
    }
 | 
			
		||||
    unmarkAll();
 | 
			
		||||
    
 | 
			
		||||
    // create result vector
 | 
			
		||||
    while (!buf.empty())
 | 
			
		||||
    {
 | 
			
		||||
        res.push_back(buf.top());
 | 
			
		||||
        buf.pop();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// generate all possible topological sorts
 | 
			
		||||
// Y. L. Varol & D. Rotem, Comput. J. 24(1), pp. 83–84, 1981
 | 
			
		||||
// http://comjnl.oupjournals.org/cgi/doi/10.1093/comjnl/24.1.83
 | 
			
		||||
// complexity: O(V*log(V)) (from the paper, but really ?)
 | 
			
		||||
template <typename T>
 | 
			
		||||
std::vector<std::vector<T>> Graph<T>::allTopoSort(void)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<std::vector<T>>    res;
 | 
			
		||||
    std::map<T, std::map<T, bool>> iMat;
 | 
			
		||||
    
 | 
			
		||||
    // create incidence matrix
 | 
			
		||||
    for (auto &v1: isMarked_)
 | 
			
		||||
    for (auto &v2: isMarked_)
 | 
			
		||||
    {
 | 
			
		||||
        iMat[v1.first][v2.first] = false;
 | 
			
		||||
    }
 | 
			
		||||
    for (auto &v: isMarked_)
 | 
			
		||||
    {
 | 
			
		||||
        auto cVec = getChildren(v.first);
 | 
			
		||||
        
 | 
			
		||||
        for (auto &c: cVec)
 | 
			
		||||
        {
 | 
			
		||||
            iMat[v.first][c] = true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // generate initial topological sort
 | 
			
		||||
    res.push_back(topoSort());
 | 
			
		||||
    
 | 
			
		||||
    // generate all other topological sorts by permutation
 | 
			
		||||
    std::vector<T>            p = res[0];
 | 
			
		||||
    const unsigned int        n = size();
 | 
			
		||||
    std::vector<unsigned int> loc(n);
 | 
			
		||||
    unsigned int              i, k, k1;
 | 
			
		||||
    T                         obj_k, obj_k1;
 | 
			
		||||
    bool                      isFinal;
 | 
			
		||||
    
 | 
			
		||||
    for (unsigned int j = 0; j < n; ++j)
 | 
			
		||||
    {
 | 
			
		||||
        loc[j] = j;
 | 
			
		||||
    }
 | 
			
		||||
    i = 0;
 | 
			
		||||
    while (i < n-1)
 | 
			
		||||
    {
 | 
			
		||||
        k      = loc[i];
 | 
			
		||||
        k1     = k + 1;
 | 
			
		||||
        obj_k  = p[k];
 | 
			
		||||
        if (k1 >= n)
 | 
			
		||||
        {
 | 
			
		||||
            isFinal = true;
 | 
			
		||||
            obj_k1  = obj_k;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            isFinal = false;
 | 
			
		||||
            obj_k1  = p[k1];
 | 
			
		||||
        }
 | 
			
		||||
        if (iMat[res[0][i]][obj_k1] or isFinal)
 | 
			
		||||
        {
 | 
			
		||||
            for (unsigned int l = k; l >= i + 1; --l)
 | 
			
		||||
            {
 | 
			
		||||
                p[l]   = p[l-1];
 | 
			
		||||
            }
 | 
			
		||||
            p[i]   = obj_k;
 | 
			
		||||
            loc[i] = i;
 | 
			
		||||
            i++;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            p[k]   = obj_k1;
 | 
			
		||||
            p[k1]  = obj_k;
 | 
			
		||||
            loc[i] = k1;
 | 
			
		||||
            i      = 0;
 | 
			
		||||
            res.push_back(p);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// build depedency matrix from topological sorts ///////////////////////////////
 | 
			
		||||
// complexity: something like O(V^2*log(V!))
 | 
			
		||||
template <typename T>
 | 
			
		||||
std::map<T, std::map<T, bool>>
 | 
			
		||||
makeDependencyMatrix(const std::vector<std::vector<T>> &topSort)
 | 
			
		||||
{
 | 
			
		||||
    std::map<T, std::map<T, bool>> m;
 | 
			
		||||
    const std::vector<T>           &vList = topSort[0];
 | 
			
		||||
    
 | 
			
		||||
    for (auto &v1: vList)
 | 
			
		||||
    for (auto &v2: vList)
 | 
			
		||||
    {
 | 
			
		||||
        bool dep = true;
 | 
			
		||||
        
 | 
			
		||||
        for (auto &t: topSort)
 | 
			
		||||
        {
 | 
			
		||||
            auto i1 = std::find(t.begin(), t.end(), v1);
 | 
			
		||||
            auto i2 = std::find(t.begin(), t.end(), v2);
 | 
			
		||||
            
 | 
			
		||||
            dep = dep and (i1 - i2 > 0);
 | 
			
		||||
            if (!dep) break;
 | 
			
		||||
        }
 | 
			
		||||
        m[v1][v2] = dep;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    return m;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
END_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
#endif // Hadrons_Graph_hpp_
 | 
			
		||||
							
								
								
									
										80
									
								
								extras/Hadrons/HadronsXmlRun.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								extras/Hadrons/HadronsXmlRun.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,80 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
Source file: extras/Hadrons/HadronsXmlRun.cc
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2015
 | 
			
		||||
Copyright (C) 2016
 | 
			
		||||
 | 
			
		||||
Author: Antonin Portelli <antonin.portelli@me.com>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
 | 
			
		||||
#include <Grid/Hadrons/Application.hpp>
 | 
			
		||||
 | 
			
		||||
using namespace Grid;
 | 
			
		||||
using namespace QCD;
 | 
			
		||||
using namespace Hadrons;
 | 
			
		||||
 | 
			
		||||
int main(int argc, char *argv[])
 | 
			
		||||
{
 | 
			
		||||
    // parse command line
 | 
			
		||||
    std::string parameterFileName, scheduleFileName = "";
 | 
			
		||||
    
 | 
			
		||||
    if (argc < 2)
 | 
			
		||||
    {
 | 
			
		||||
        std::cerr << "usage: " << argv[0] << " <parameter file> [<precomputed schedule>] [Grid options]";
 | 
			
		||||
        std::cerr << std::endl;
 | 
			
		||||
        std::exit(EXIT_FAILURE);
 | 
			
		||||
    }
 | 
			
		||||
    parameterFileName = argv[1];
 | 
			
		||||
    if (argc > 2)
 | 
			
		||||
    {
 | 
			
		||||
        if (argv[2][0] != '-')
 | 
			
		||||
        {
 | 
			
		||||
            scheduleFileName = argv[2];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // initialization
 | 
			
		||||
    Grid_init(&argc, &argv);
 | 
			
		||||
    HadronsLogError.Active(GridLogError.isActive());
 | 
			
		||||
    HadronsLogWarning.Active(GridLogWarning.isActive());
 | 
			
		||||
    HadronsLogMessage.Active(GridLogMessage.isActive());
 | 
			
		||||
    HadronsLogIterative.Active(GridLogIterative.isActive());
 | 
			
		||||
    HadronsLogDebug.Active(GridLogDebug.isActive());
 | 
			
		||||
    LOG(Message) << "Grid initialized" << std::endl;
 | 
			
		||||
    
 | 
			
		||||
    // execution
 | 
			
		||||
    Application application(parameterFileName);
 | 
			
		||||
    
 | 
			
		||||
    application.parseParameterFile(parameterFileName);
 | 
			
		||||
    if (!scheduleFileName.empty())
 | 
			
		||||
    {
 | 
			
		||||
        application.loadSchedule(scheduleFileName);
 | 
			
		||||
    }
 | 
			
		||||
    application.run();
 | 
			
		||||
    
 | 
			
		||||
    // epilogue
 | 
			
		||||
    LOG(Message) << "Grid is finalizing now" << std::endl;
 | 
			
		||||
    Grid_finalize();
 | 
			
		||||
    
 | 
			
		||||
    return EXIT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										72
									
								
								extras/Hadrons/HadronsXmlSchedule.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								extras/Hadrons/HadronsXmlSchedule.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,72 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
Source file: extras/Hadrons/HadronsXmlSchedule.cc
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2015
 | 
			
		||||
Copyright (C) 2016
 | 
			
		||||
 | 
			
		||||
Author: Antonin Portelli <antonin.portelli@me.com>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
 | 
			
		||||
#include <Grid/Hadrons/Application.hpp>
 | 
			
		||||
 | 
			
		||||
using namespace Grid;
 | 
			
		||||
using namespace QCD;
 | 
			
		||||
using namespace Hadrons;
 | 
			
		||||
 | 
			
		||||
int main(int argc, char *argv[])
 | 
			
		||||
{
 | 
			
		||||
    // parse command line
 | 
			
		||||
    std::string parameterFileName, scheduleFileName;
 | 
			
		||||
    
 | 
			
		||||
    if (argc < 3)
 | 
			
		||||
    {
 | 
			
		||||
        std::cerr << "usage: " << argv[0] << " <parameter file> <schedule output> [Grid options]";
 | 
			
		||||
        std::cerr << std::endl;
 | 
			
		||||
        std::exit(EXIT_FAILURE);
 | 
			
		||||
    }
 | 
			
		||||
    parameterFileName = argv[1];
 | 
			
		||||
    scheduleFileName  = argv[2];
 | 
			
		||||
    
 | 
			
		||||
    // initialization
 | 
			
		||||
    Grid_init(&argc, &argv);
 | 
			
		||||
    HadronsLogError.Active(GridLogError.isActive());
 | 
			
		||||
    HadronsLogWarning.Active(GridLogWarning.isActive());
 | 
			
		||||
    HadronsLogMessage.Active(GridLogMessage.isActive());
 | 
			
		||||
    HadronsLogIterative.Active(GridLogIterative.isActive());
 | 
			
		||||
    HadronsLogDebug.Active(GridLogDebug.isActive());
 | 
			
		||||
    LOG(Message) << "Grid initialized" << std::endl;
 | 
			
		||||
    
 | 
			
		||||
    // execution
 | 
			
		||||
    Application application;
 | 
			
		||||
    
 | 
			
		||||
    application.parseParameterFile(parameterFileName);
 | 
			
		||||
    application.schedule();
 | 
			
		||||
    application.printSchedule();
 | 
			
		||||
    application.saveSchedule(scheduleFileName);
 | 
			
		||||
    
 | 
			
		||||
    // epilogue
 | 
			
		||||
    LOG(Message) << "Grid is finalizing now" << std::endl;
 | 
			
		||||
    Grid_finalize();
 | 
			
		||||
    
 | 
			
		||||
    return EXIT_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										29
									
								
								extras/Hadrons/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								extras/Hadrons/Makefile.am
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
			
		||||
lib_LIBRARIES = libHadrons.a
 | 
			
		||||
bin_PROGRAMS  = HadronsXmlRun HadronsXmlSchedule
 | 
			
		||||
 | 
			
		||||
include modules.inc
 | 
			
		||||
 | 
			
		||||
libHadrons_a_SOURCES = \
 | 
			
		||||
    $(modules_cc)      \
 | 
			
		||||
    Application.cc     \
 | 
			
		||||
    Environment.cc     \
 | 
			
		||||
    Global.cc          \
 | 
			
		||||
    Module.cc
 | 
			
		||||
libHadrons_adir = $(pkgincludedir)/Hadrons
 | 
			
		||||
nobase_libHadrons_a_HEADERS = \
 | 
			
		||||
	$(modules_hpp)            \
 | 
			
		||||
	Application.hpp           \
 | 
			
		||||
	Environment.hpp           \
 | 
			
		||||
	Factory.hpp               \
 | 
			
		||||
	GeneticScheduler.hpp      \
 | 
			
		||||
	Global.hpp                \
 | 
			
		||||
	Graph.hpp                 \
 | 
			
		||||
	Module.hpp                \
 | 
			
		||||
	Modules.hpp               \
 | 
			
		||||
	ModuleFactory.hpp
 | 
			
		||||
 | 
			
		||||
HadronsXmlRun_SOURCES = HadronsXmlRun.cc
 | 
			
		||||
HadronsXmlRun_LDADD   = libHadrons.a -lGrid
 | 
			
		||||
 | 
			
		||||
HadronsXmlSchedule_SOURCES = HadronsXmlSchedule.cc
 | 
			
		||||
HadronsXmlSchedule_LDADD   = libHadrons.a -lGrid
 | 
			
		||||
							
								
								
									
										71
									
								
								extras/Hadrons/Module.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								extras/Hadrons/Module.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,71 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
Source file: extras/Hadrons/Module.cc
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2015
 | 
			
		||||
Copyright (C) 2016
 | 
			
		||||
 | 
			
		||||
Author: Antonin Portelli <antonin.portelli@me.com>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
 | 
			
		||||
#include <Grid/Hadrons/Module.hpp>
 | 
			
		||||
 | 
			
		||||
using namespace Grid;
 | 
			
		||||
using namespace QCD;
 | 
			
		||||
using namespace Hadrons;
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                       ModuleBase implementation                            *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
// constructor /////////////////////////////////////////////////////////////////
 | 
			
		||||
ModuleBase::ModuleBase(const std::string name)
 | 
			
		||||
: name_(name)
 | 
			
		||||
, env_(Environment::getInstance())
 | 
			
		||||
{}
 | 
			
		||||
 | 
			
		||||
// access //////////////////////////////////////////////////////////////////////
 | 
			
		||||
std::string ModuleBase::getName(void) const
 | 
			
		||||
{
 | 
			
		||||
    return name_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Environment & ModuleBase::env(void) const
 | 
			
		||||
{
 | 
			
		||||
    return env_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// get factory registration name if available
 | 
			
		||||
std::string ModuleBase::getRegisteredName(void)
 | 
			
		||||
{
 | 
			
		||||
    HADRON_ERROR("module '" + getName() + "' has a type not registered"
 | 
			
		||||
                 + " in the factory");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// execution ///////////////////////////////////////////////////////////////////
 | 
			
		||||
void ModuleBase::operator()(void)
 | 
			
		||||
{
 | 
			
		||||
    setup();
 | 
			
		||||
    if (!env().isDryRun())
 | 
			
		||||
    {
 | 
			
		||||
        execute();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										198
									
								
								extras/Hadrons/Module.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										198
									
								
								extras/Hadrons/Module.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,198 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
Source file: extras/Hadrons/Module.hpp
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2015
 | 
			
		||||
Copyright (C) 2016
 | 
			
		||||
 | 
			
		||||
Author: Antonin Portelli <antonin.portelli@me.com>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
 | 
			
		||||
#ifndef Hadrons_Module_hpp_
 | 
			
		||||
#define Hadrons_Module_hpp_
 | 
			
		||||
 | 
			
		||||
#include <Grid/Hadrons/Global.hpp>
 | 
			
		||||
#include <Grid/Hadrons/Environment.hpp>
 | 
			
		||||
 | 
			
		||||
BEGIN_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
// module registration macros
 | 
			
		||||
#define MODULE_REGISTER(mod, base)\
 | 
			
		||||
class mod: public base\
 | 
			
		||||
{\
 | 
			
		||||
public:\
 | 
			
		||||
    typedef base Base;\
 | 
			
		||||
    using Base::Base;\
 | 
			
		||||
    virtual std::string getRegisteredName(void)\
 | 
			
		||||
    {\
 | 
			
		||||
        return std::string(#mod);\
 | 
			
		||||
    }\
 | 
			
		||||
};\
 | 
			
		||||
class mod##ModuleRegistrar\
 | 
			
		||||
{\
 | 
			
		||||
public:\
 | 
			
		||||
    mod##ModuleRegistrar(void)\
 | 
			
		||||
    {\
 | 
			
		||||
        ModuleFactory &modFac = ModuleFactory::getInstance();\
 | 
			
		||||
        modFac.registerBuilder(#mod, [&](const std::string name)\
 | 
			
		||||
                              {\
 | 
			
		||||
                                  return std::unique_ptr<mod>(new mod(name));\
 | 
			
		||||
                              });\
 | 
			
		||||
    }\
 | 
			
		||||
};\
 | 
			
		||||
static mod##ModuleRegistrar mod##ModuleRegistrarInstance;
 | 
			
		||||
 | 
			
		||||
#define MODULE_REGISTER_NS(mod, base, ns)\
 | 
			
		||||
class mod: public base\
 | 
			
		||||
{\
 | 
			
		||||
public:\
 | 
			
		||||
    typedef base Base;\
 | 
			
		||||
    using Base::Base;\
 | 
			
		||||
    virtual std::string getRegisteredName(void)\
 | 
			
		||||
    {\
 | 
			
		||||
        return std::string(#ns "::" #mod);\
 | 
			
		||||
    }\
 | 
			
		||||
};\
 | 
			
		||||
class ns##mod##ModuleRegistrar\
 | 
			
		||||
{\
 | 
			
		||||
public:\
 | 
			
		||||
    ns##mod##ModuleRegistrar(void)\
 | 
			
		||||
    {\
 | 
			
		||||
        ModuleFactory &modFac = ModuleFactory::getInstance();\
 | 
			
		||||
        modFac.registerBuilder(#ns "::" #mod, [&](const std::string name)\
 | 
			
		||||
                              {\
 | 
			
		||||
                                  return std::unique_ptr<ns::mod>(new ns::mod(name));\
 | 
			
		||||
                              });\
 | 
			
		||||
    }\
 | 
			
		||||
};\
 | 
			
		||||
static ns##mod##ModuleRegistrar ns##mod##ModuleRegistrarInstance;
 | 
			
		||||
 | 
			
		||||
#define ARG(...) __VA_ARGS__
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                            Module class                                    *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
// base class
 | 
			
		||||
class ModuleBase
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    // constructor
 | 
			
		||||
    ModuleBase(const std::string name);
 | 
			
		||||
    // destructor
 | 
			
		||||
    virtual ~ModuleBase(void) = default;
 | 
			
		||||
    // access
 | 
			
		||||
    std::string getName(void) const;
 | 
			
		||||
    Environment &env(void) const;
 | 
			
		||||
    // get factory registration name if available
 | 
			
		||||
    virtual std::string getRegisteredName(void);
 | 
			
		||||
    // dependencies/products
 | 
			
		||||
    virtual std::vector<std::string> getInput(void) = 0;
 | 
			
		||||
    virtual std::vector<std::string> getOutput(void) = 0;
 | 
			
		||||
    // parse parameters
 | 
			
		||||
    virtual void parseParameters(XmlReader &reader, const std::string name) = 0;
 | 
			
		||||
    virtual void saveParameters(XmlWriter &writer, const std::string name) = 0;
 | 
			
		||||
    // setup
 | 
			
		||||
    virtual void setup(void) {};
 | 
			
		||||
    // execution
 | 
			
		||||
    void operator()(void);
 | 
			
		||||
    virtual void execute(void) = 0;
 | 
			
		||||
private:
 | 
			
		||||
    std::string name_;
 | 
			
		||||
    Environment &env_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// derived class, templating the parameter class
 | 
			
		||||
template <typename P>
 | 
			
		||||
class Module: public ModuleBase
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    typedef P Par;
 | 
			
		||||
public:
 | 
			
		||||
    // constructor
 | 
			
		||||
    Module(const std::string name);
 | 
			
		||||
    // destructor
 | 
			
		||||
    virtual ~Module(void) = default;
 | 
			
		||||
    // parse parameters
 | 
			
		||||
    virtual void parseParameters(XmlReader &reader, const std::string name);
 | 
			
		||||
    virtual void saveParameters(XmlWriter &writer, const std::string name);
 | 
			
		||||
    // parameter access
 | 
			
		||||
    const P & par(void) const;
 | 
			
		||||
    void      setPar(const P &par);
 | 
			
		||||
private:
 | 
			
		||||
    P par_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// no parameter type
 | 
			
		||||
class NoPar {};
 | 
			
		||||
 | 
			
		||||
template <>
 | 
			
		||||
class Module<NoPar>: public ModuleBase
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    // constructor
 | 
			
		||||
    Module(const std::string name): ModuleBase(name) {};
 | 
			
		||||
    // destructor
 | 
			
		||||
    virtual ~Module(void) = default;
 | 
			
		||||
    // parse parameters (do nothing)
 | 
			
		||||
    virtual void parseParameters(XmlReader &reader, const std::string name) {};
 | 
			
		||||
    virtual void saveParameters(XmlWriter &writer, const std::string name)
 | 
			
		||||
    {
 | 
			
		||||
        push(writer, "options");
 | 
			
		||||
        pop(writer);
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                           Template implementation                          *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
template <typename P>
 | 
			
		||||
Module<P>::Module(const std::string name)
 | 
			
		||||
: ModuleBase(name)
 | 
			
		||||
{}
 | 
			
		||||
 | 
			
		||||
template <typename P>
 | 
			
		||||
void Module<P>::parseParameters(XmlReader &reader, const std::string name)
 | 
			
		||||
{
 | 
			
		||||
    read(reader, name, par_);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename P>
 | 
			
		||||
void Module<P>::saveParameters(XmlWriter &writer, const std::string name)
 | 
			
		||||
{
 | 
			
		||||
    write(writer, name, par_);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename P>
 | 
			
		||||
const P & Module<P>::par(void) const
 | 
			
		||||
{
 | 
			
		||||
    return par_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename P>
 | 
			
		||||
void Module<P>::setPar(const P &par)
 | 
			
		||||
{
 | 
			
		||||
    par_ = par;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
END_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
#endif // Hadrons_Module_hpp_
 | 
			
		||||
							
								
								
									
										49
									
								
								extras/Hadrons/ModuleFactory.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								extras/Hadrons/ModuleFactory.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,49 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
Source file: extras/Hadrons/ModuleFactory.hpp
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2015
 | 
			
		||||
Copyright (C) 2016
 | 
			
		||||
 | 
			
		||||
Author: Antonin Portelli <antonin.portelli@me.com>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
 | 
			
		||||
#ifndef Hadrons_ModuleFactory_hpp_
 | 
			
		||||
#define Hadrons_ModuleFactory_hpp_
 | 
			
		||||
 | 
			
		||||
#include <Grid/Hadrons/Global.hpp>
 | 
			
		||||
#include <Grid/Hadrons/Factory.hpp>
 | 
			
		||||
#include <Grid/Hadrons/Module.hpp>
 | 
			
		||||
 | 
			
		||||
BEGIN_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                            ModuleFactory                                   *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
class ModuleFactory: public Factory<ModuleBase>
 | 
			
		||||
{
 | 
			
		||||
    SINGLETON_DEFCTOR(ModuleFactory)
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
END_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
#endif // Hadrons_ModuleFactory_hpp_
 | 
			
		||||
							
								
								
									
										48
									
								
								extras/Hadrons/Modules.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								extras/Hadrons/Modules.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,48 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
Source file: extras/Hadrons/Modules.hpp
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2015
 | 
			
		||||
Copyright (C) 2016
 | 
			
		||||
 | 
			
		||||
Author: Antonin Portelli <antonin.portelli@me.com>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
#include <Grid/Hadrons/Modules/MAction/DWF.hpp>
 | 
			
		||||
#include <Grid/Hadrons/Modules/MAction/Wilson.hpp>
 | 
			
		||||
#include <Grid/Hadrons/Modules/MContraction/Baryon.hpp>
 | 
			
		||||
#include <Grid/Hadrons/Modules/MContraction/DiscLoop.hpp>
 | 
			
		||||
#include <Grid/Hadrons/Modules/MContraction/Gamma3pt.hpp>
 | 
			
		||||
#include <Grid/Hadrons/Modules/MContraction/Meson.hpp>
 | 
			
		||||
#include <Grid/Hadrons/Modules/MContraction/WeakHamiltonian.hpp>
 | 
			
		||||
#include <Grid/Hadrons/Modules/MContraction/WeakHamiltonianEye.hpp>
 | 
			
		||||
#include <Grid/Hadrons/Modules/MContraction/WeakHamiltonianNonEye.hpp>
 | 
			
		||||
#include <Grid/Hadrons/Modules/MContraction/WeakNeutral4ptDisc.hpp>
 | 
			
		||||
#include <Grid/Hadrons/Modules/MGauge/Load.hpp>
 | 
			
		||||
#include <Grid/Hadrons/Modules/MGauge/Random.hpp>
 | 
			
		||||
#include <Grid/Hadrons/Modules/MGauge/Unit.hpp>
 | 
			
		||||
#include <Grid/Hadrons/Modules/MLoop/NoiseLoop.hpp>
 | 
			
		||||
#include <Grid/Hadrons/Modules/MSolver/RBPrecCG.hpp>
 | 
			
		||||
#include <Grid/Hadrons/Modules/MSource/Point.hpp>
 | 
			
		||||
#include <Grid/Hadrons/Modules/MSource/SeqGamma.hpp>
 | 
			
		||||
#include <Grid/Hadrons/Modules/MSource/Wall.hpp>
 | 
			
		||||
#include <Grid/Hadrons/Modules/MSource/Z2.hpp>
 | 
			
		||||
#include <Grid/Hadrons/Modules/Quark.hpp>
 | 
			
		||||
							
								
								
									
										140
									
								
								extras/Hadrons/Modules/MAction/DWF.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								extras/Hadrons/Modules/MAction/DWF.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,140 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
Source file: extras/Hadrons/Modules/MAction/DWF.hpp
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2015
 | 
			
		||||
Copyright (C) 2016
 | 
			
		||||
 | 
			
		||||
Author: Antonin Portelli <antonin.portelli@me.com>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
 | 
			
		||||
#ifndef Hadrons_DWF_hpp_
 | 
			
		||||
#define Hadrons_DWF_hpp_
 | 
			
		||||
 | 
			
		||||
#include <Grid/Hadrons/Global.hpp>
 | 
			
		||||
#include <Grid/Hadrons/Module.hpp>
 | 
			
		||||
#include <Grid/Hadrons/ModuleFactory.hpp>
 | 
			
		||||
 | 
			
		||||
BEGIN_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                     Domain wall quark action                               *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
BEGIN_MODULE_NAMESPACE(MAction)
 | 
			
		||||
 | 
			
		||||
class DWFPar: Serializable
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    GRID_SERIALIZABLE_CLASS_MEMBERS(DWFPar,
 | 
			
		||||
                                    std::string, gauge,
 | 
			
		||||
                                    unsigned int, Ls,
 | 
			
		||||
                                    double      , mass,
 | 
			
		||||
                                    double      , M5,
 | 
			
		||||
                                    std::string , boundary);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
class TDWF: public Module<DWFPar>
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    TYPE_ALIASES(FImpl,);
 | 
			
		||||
public:
 | 
			
		||||
    // constructor
 | 
			
		||||
    TDWF(const std::string name);
 | 
			
		||||
    // destructor
 | 
			
		||||
    virtual ~TDWF(void) = default;
 | 
			
		||||
    // dependency relation
 | 
			
		||||
    virtual std::vector<std::string> getInput(void);
 | 
			
		||||
    virtual std::vector<std::string> getOutput(void);
 | 
			
		||||
    // setup
 | 
			
		||||
    virtual void setup(void);
 | 
			
		||||
    // execution
 | 
			
		||||
    virtual void execute(void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
MODULE_REGISTER_NS(DWF, TDWF<FIMPL>, MAction);
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                        DWF template implementation                         *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
// constructor /////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
TDWF<FImpl>::TDWF(const std::string name)
 | 
			
		||||
: Module<DWFPar>(name)
 | 
			
		||||
{}
 | 
			
		||||
 | 
			
		||||
// dependencies/products ///////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
std::vector<std::string> TDWF<FImpl>::getInput(void)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<std::string> in = {par().gauge};
 | 
			
		||||
    
 | 
			
		||||
    return in;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
std::vector<std::string> TDWF<FImpl>::getOutput(void)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<std::string> out = {getName()};
 | 
			
		||||
    
 | 
			
		||||
    return out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// setup ///////////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
void TDWF<FImpl>::setup(void)
 | 
			
		||||
{
 | 
			
		||||
    unsigned int size;
 | 
			
		||||
    
 | 
			
		||||
    size = 2*env().template lattice4dSize<typename FImpl::DoubledGaugeField>();
 | 
			
		||||
    env().registerObject(getName(), size, par().Ls);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// execution ///////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
void TDWF<FImpl>::execute(void)
 | 
			
		||||
{
 | 
			
		||||
    LOG(Message) << "Setting up domain wall fermion matrix with m= "
 | 
			
		||||
                 << par().mass << ", M5= " << par().M5 << " and Ls= "
 | 
			
		||||
                 << par().Ls << " using gauge field '" << par().gauge << "'"
 | 
			
		||||
                 << std::endl;
 | 
			
		||||
    LOG(Message) << "Fermion boundary conditions: " << par().boundary 
 | 
			
		||||
                 << std::endl;
 | 
			
		||||
    env().createGrid(par().Ls);
 | 
			
		||||
    auto &U      = *env().template getObject<LatticeGaugeField>(par().gauge);
 | 
			
		||||
    auto &g4     = *env().getGrid();
 | 
			
		||||
    auto &grb4   = *env().getRbGrid();
 | 
			
		||||
    auto &g5     = *env().getGrid(par().Ls);
 | 
			
		||||
    auto &grb5   = *env().getRbGrid(par().Ls);
 | 
			
		||||
    std::vector<Complex> boundary = strToVec<Complex>(par().boundary);
 | 
			
		||||
    typename DomainWallFermion<FImpl>::ImplParams implParams(boundary);
 | 
			
		||||
    FMat *fMatPt = new DomainWallFermion<FImpl>(U, g5, grb5, g4, grb4,
 | 
			
		||||
                                                par().mass, par().M5,
 | 
			
		||||
                                                implParams);
 | 
			
		||||
    env().setObject(getName(), fMatPt);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
END_MODULE_NAMESPACE
 | 
			
		||||
 | 
			
		||||
END_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
#endif // Hadrons_DWF_hpp_
 | 
			
		||||
							
								
								
									
										132
									
								
								extras/Hadrons/Modules/MAction/Wilson.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								extras/Hadrons/Modules/MAction/Wilson.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,132 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
Source file: extras/Hadrons/Modules/MAction/Wilson.hpp
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2015
 | 
			
		||||
Copyright (C) 2016
 | 
			
		||||
 | 
			
		||||
Author: Antonin Portelli <antonin.portelli@me.com>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
 | 
			
		||||
#ifndef Hadrons_Wilson_hpp_
 | 
			
		||||
#define Hadrons_Wilson_hpp_
 | 
			
		||||
 | 
			
		||||
#include <Grid/Hadrons/Global.hpp>
 | 
			
		||||
#include <Grid/Hadrons/Module.hpp>
 | 
			
		||||
#include <Grid/Hadrons/ModuleFactory.hpp>
 | 
			
		||||
 | 
			
		||||
BEGIN_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                            TWilson quark action                            *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
BEGIN_MODULE_NAMESPACE(MAction)
 | 
			
		||||
 | 
			
		||||
class WilsonPar: Serializable
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    GRID_SERIALIZABLE_CLASS_MEMBERS(WilsonPar,
 | 
			
		||||
                                    std::string, gauge,
 | 
			
		||||
                                    double     , mass,
 | 
			
		||||
                                    std::string, boundary);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
class TWilson: public Module<WilsonPar>
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    TYPE_ALIASES(FImpl,);
 | 
			
		||||
public:
 | 
			
		||||
    // constructor
 | 
			
		||||
    TWilson(const std::string name);
 | 
			
		||||
    // destructor
 | 
			
		||||
    virtual ~TWilson(void) = default;
 | 
			
		||||
    // dependencies/products
 | 
			
		||||
    virtual std::vector<std::string> getInput(void);
 | 
			
		||||
    virtual std::vector<std::string> getOutput(void);
 | 
			
		||||
    // setup
 | 
			
		||||
    virtual void setup(void);
 | 
			
		||||
    // execution
 | 
			
		||||
    virtual void execute(void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
MODULE_REGISTER_NS(Wilson, TWilson<FIMPL>, MAction);
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                     TWilson template implementation                        *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
// constructor /////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
TWilson<FImpl>::TWilson(const std::string name)
 | 
			
		||||
: Module<WilsonPar>(name)
 | 
			
		||||
{}
 | 
			
		||||
 | 
			
		||||
// dependencies/products ///////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
std::vector<std::string> TWilson<FImpl>::getInput(void)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<std::string> in = {par().gauge};
 | 
			
		||||
    
 | 
			
		||||
    return in;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
std::vector<std::string> TWilson<FImpl>::getOutput(void)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<std::string> out = {getName()};
 | 
			
		||||
    
 | 
			
		||||
    return out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// setup ///////////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
void TWilson<FImpl>::setup(void)
 | 
			
		||||
{
 | 
			
		||||
    unsigned int size;
 | 
			
		||||
    
 | 
			
		||||
    size = 2*env().template lattice4dSize<typename FImpl::DoubledGaugeField>();
 | 
			
		||||
    env().registerObject(getName(), size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// execution ///////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
void TWilson<FImpl>::execute()
 | 
			
		||||
{
 | 
			
		||||
    LOG(Message) << "Setting up TWilson fermion matrix with m= " << par().mass
 | 
			
		||||
                 << " using gauge field '" << par().gauge << "'" << std::endl;
 | 
			
		||||
    LOG(Message) << "Fermion boundary conditions: " << par().boundary 
 | 
			
		||||
                 << std::endl;
 | 
			
		||||
    auto &U      = *env().template getObject<LatticeGaugeField>(par().gauge);
 | 
			
		||||
    auto &grid   = *env().getGrid();
 | 
			
		||||
    auto &gridRb = *env().getRbGrid();
 | 
			
		||||
    std::vector<Complex> boundary = strToVec<Complex>(par().boundary);
 | 
			
		||||
    typename WilsonFermion<FImpl>::ImplParams implParams(boundary);
 | 
			
		||||
    FMat *fMatPt = new WilsonFermion<FImpl>(U, grid, gridRb, par().mass,
 | 
			
		||||
                                            implParams);
 | 
			
		||||
    env().setObject(getName(), fMatPt);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
END_MODULE_NAMESPACE
 | 
			
		||||
 | 
			
		||||
END_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
#endif // Hadrons_Wilson_hpp_
 | 
			
		||||
							
								
								
									
										131
									
								
								extras/Hadrons/Modules/MContraction/Baryon.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										131
									
								
								extras/Hadrons/Modules/MContraction/Baryon.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,131 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
Source file: extras/Hadrons/Modules/MContraction/Baryon.hpp
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2015
 | 
			
		||||
Copyright (C) 2016
 | 
			
		||||
 | 
			
		||||
Author: Antonin Portelli <antonin.portelli@me.com>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
 | 
			
		||||
#ifndef Hadrons_Baryon_hpp_
 | 
			
		||||
#define Hadrons_Baryon_hpp_
 | 
			
		||||
 | 
			
		||||
#include <Grid/Hadrons/Global.hpp>
 | 
			
		||||
#include <Grid/Hadrons/Module.hpp>
 | 
			
		||||
#include <Grid/Hadrons/ModuleFactory.hpp>
 | 
			
		||||
 | 
			
		||||
BEGIN_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                               Baryon                                       *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
BEGIN_MODULE_NAMESPACE(MContraction)
 | 
			
		||||
 | 
			
		||||
class BaryonPar: Serializable
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    GRID_SERIALIZABLE_CLASS_MEMBERS(BaryonPar,
 | 
			
		||||
                                    std::string, q1,
 | 
			
		||||
                                    std::string, q2,
 | 
			
		||||
                                    std::string, q3,
 | 
			
		||||
                                    std::string, output);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename FImpl1, typename FImpl2, typename FImpl3>
 | 
			
		||||
class TBaryon: public Module<BaryonPar>
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    TYPE_ALIASES(FImpl1, 1);
 | 
			
		||||
    TYPE_ALIASES(FImpl2, 2);
 | 
			
		||||
    TYPE_ALIASES(FImpl3, 3);
 | 
			
		||||
    class Result: Serializable
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        GRID_SERIALIZABLE_CLASS_MEMBERS(Result,
 | 
			
		||||
                                        std::vector<std::vector<std::vector<Complex>>>, corr);
 | 
			
		||||
    };
 | 
			
		||||
public:
 | 
			
		||||
    // constructor
 | 
			
		||||
    TBaryon(const std::string name);
 | 
			
		||||
    // destructor
 | 
			
		||||
    virtual ~TBaryon(void) = default;
 | 
			
		||||
    // dependency relation
 | 
			
		||||
    virtual std::vector<std::string> getInput(void);
 | 
			
		||||
    virtual std::vector<std::string> getOutput(void);
 | 
			
		||||
    // execution
 | 
			
		||||
    virtual void execute(void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
MODULE_REGISTER_NS(Baryon, ARG(TBaryon<FIMPL, FIMPL, FIMPL>), MContraction);
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                         TBaryon implementation                             *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
// constructor /////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl1, typename FImpl2, typename FImpl3>
 | 
			
		||||
TBaryon<FImpl1, FImpl2, FImpl3>::TBaryon(const std::string name)
 | 
			
		||||
: Module<BaryonPar>(name)
 | 
			
		||||
{}
 | 
			
		||||
 | 
			
		||||
// dependencies/products ///////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl1, typename FImpl2, typename FImpl3>
 | 
			
		||||
std::vector<std::string> TBaryon<FImpl1, FImpl2, FImpl3>::getInput(void)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<std::string> input = {par().q1, par().q2, par().q3};
 | 
			
		||||
    
 | 
			
		||||
    return input;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename FImpl1, typename FImpl2, typename FImpl3>
 | 
			
		||||
std::vector<std::string> TBaryon<FImpl1, FImpl2, FImpl3>::getOutput(void)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<std::string> out = {getName()};
 | 
			
		||||
    
 | 
			
		||||
    return out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// execution ///////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl1, typename FImpl2, typename FImpl3>
 | 
			
		||||
void TBaryon<FImpl1, FImpl2, FImpl3>::execute(void)
 | 
			
		||||
{
 | 
			
		||||
    LOG(Message) << "Computing baryon contractions '" << getName() << "' using"
 | 
			
		||||
                 << " quarks '" << par().q1 << "', '" << par().q2 << "', and '"
 | 
			
		||||
                 << par().q3 << "'" << std::endl;
 | 
			
		||||
    
 | 
			
		||||
    CorrWriter             writer(par().output);
 | 
			
		||||
    PropagatorField1      &q1 = *env().template getObject<PropagatorField1>(par().q1);
 | 
			
		||||
    PropagatorField2      &q2 = *env().template getObject<PropagatorField2>(par().q2);
 | 
			
		||||
    PropagatorField3      &q3 = *env().template getObject<PropagatorField3>(par().q2);
 | 
			
		||||
    LatticeComplex        c(env().getGrid());
 | 
			
		||||
    Result                result;
 | 
			
		||||
    
 | 
			
		||||
    // FIXME: do contractions
 | 
			
		||||
    
 | 
			
		||||
    write(writer, "meson", result);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
END_MODULE_NAMESPACE
 | 
			
		||||
 | 
			
		||||
END_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
#endif // Hadrons_Baryon_hpp_
 | 
			
		||||
							
								
								
									
										144
									
								
								extras/Hadrons/Modules/MContraction/DiscLoop.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										144
									
								
								extras/Hadrons/Modules/MContraction/DiscLoop.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,144 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
Source file: extras/Hadrons/Modules/MContraction/DiscLoop.hpp
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2017
 | 
			
		||||
 | 
			
		||||
Author: Andrew Lawson    <andrew.lawson1991@gmail.com>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
 | 
			
		||||
#ifndef Hadrons_DiscLoop_hpp_
 | 
			
		||||
#define Hadrons_DiscLoop_hpp_
 | 
			
		||||
 | 
			
		||||
#include <Grid/Hadrons/Global.hpp>
 | 
			
		||||
#include <Grid/Hadrons/Module.hpp>
 | 
			
		||||
#include <Grid/Hadrons/ModuleFactory.hpp>
 | 
			
		||||
 | 
			
		||||
BEGIN_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                                DiscLoop                                    *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
BEGIN_MODULE_NAMESPACE(MContraction)
 | 
			
		||||
 | 
			
		||||
class DiscLoopPar: Serializable
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    GRID_SERIALIZABLE_CLASS_MEMBERS(DiscLoopPar,
 | 
			
		||||
                                    std::string,    q_loop,
 | 
			
		||||
                                    Gamma::Algebra, gamma,
 | 
			
		||||
                                    std::string,    output);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
class TDiscLoop: public Module<DiscLoopPar>
 | 
			
		||||
{
 | 
			
		||||
    TYPE_ALIASES(FImpl,);
 | 
			
		||||
    class Result: Serializable
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        GRID_SERIALIZABLE_CLASS_MEMBERS(Result,
 | 
			
		||||
                                        Gamma::Algebra, gamma,
 | 
			
		||||
                                        std::vector<Complex>, corr);
 | 
			
		||||
    };
 | 
			
		||||
public:
 | 
			
		||||
    // constructor
 | 
			
		||||
    TDiscLoop(const std::string name);
 | 
			
		||||
    // destructor
 | 
			
		||||
    virtual ~TDiscLoop(void) = default;
 | 
			
		||||
    // dependency relation
 | 
			
		||||
    virtual std::vector<std::string> getInput(void);
 | 
			
		||||
    virtual std::vector<std::string> getOutput(void);
 | 
			
		||||
    // setup
 | 
			
		||||
    virtual void setup(void);
 | 
			
		||||
    // execution
 | 
			
		||||
    virtual void execute(void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
MODULE_REGISTER_NS(DiscLoop, TDiscLoop<FIMPL>, MContraction);
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                       TDiscLoop implementation                             *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
// constructor /////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
TDiscLoop<FImpl>::TDiscLoop(const std::string name)
 | 
			
		||||
: Module<DiscLoopPar>(name)
 | 
			
		||||
{}
 | 
			
		||||
 | 
			
		||||
// dependencies/products ///////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
std::vector<std::string> TDiscLoop<FImpl>::getInput(void)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<std::string> in = {par().q_loop};
 | 
			
		||||
    
 | 
			
		||||
    return in;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
std::vector<std::string> TDiscLoop<FImpl>::getOutput(void)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<std::string> out = {getName()};
 | 
			
		||||
    
 | 
			
		||||
    return out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// setup ///////////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
void TDiscLoop<FImpl>::setup(void)
 | 
			
		||||
{
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// execution ///////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
void TDiscLoop<FImpl>::execute(void)
 | 
			
		||||
{
 | 
			
		||||
    LOG(Message) << "Computing disconnected loop contraction '" << getName() 
 | 
			
		||||
                 << "' using '" << par().q_loop << "' with " << par().gamma 
 | 
			
		||||
                 << " insertion." << std::endl;
 | 
			
		||||
 | 
			
		||||
    CorrWriter            writer(par().output);
 | 
			
		||||
    PropagatorField       &q_loop = *env().template getObject<PropagatorField>(par().q_loop);
 | 
			
		||||
    LatticeComplex        c(env().getGrid());
 | 
			
		||||
    Gamma                 gamma(par().gamma);
 | 
			
		||||
    std::vector<TComplex> buf;
 | 
			
		||||
    Result                result;
 | 
			
		||||
 | 
			
		||||
    c = trace(gamma*q_loop);
 | 
			
		||||
    sliceSum(c, buf, Tp);
 | 
			
		||||
 | 
			
		||||
    result.gamma = par().gamma;
 | 
			
		||||
    result.corr.resize(buf.size());
 | 
			
		||||
    for (unsigned int t = 0; t < buf.size(); ++t)
 | 
			
		||||
    {
 | 
			
		||||
        result.corr[t] = TensorRemove(buf[t]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    write(writer, "disc", result);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
END_MODULE_NAMESPACE
 | 
			
		||||
 | 
			
		||||
END_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
#endif // Hadrons_DiscLoop_hpp_
 | 
			
		||||
							
								
								
									
										170
									
								
								extras/Hadrons/Modules/MContraction/Gamma3pt.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										170
									
								
								extras/Hadrons/Modules/MContraction/Gamma3pt.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,170 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
Source file: extras/Hadrons/Modules/MContraction/Gamma3pt.hpp
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2017
 | 
			
		||||
 | 
			
		||||
Author: Andrew Lawson    <andrew.lawson1991@gmail.com>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
 | 
			
		||||
#ifndef Hadrons_Gamma3pt_hpp_
 | 
			
		||||
#define Hadrons_Gamma3pt_hpp_
 | 
			
		||||
 | 
			
		||||
#include <Grid/Hadrons/Global.hpp>
 | 
			
		||||
#include <Grid/Hadrons/Module.hpp>
 | 
			
		||||
#include <Grid/Hadrons/ModuleFactory.hpp>
 | 
			
		||||
 | 
			
		||||
BEGIN_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * 3pt contraction with gamma matrix insertion.
 | 
			
		||||
 *
 | 
			
		||||
 * Schematic:
 | 
			
		||||
 *
 | 
			
		||||
 *             q2           q3
 | 
			
		||||
 *        /----<------*------<----¬
 | 
			
		||||
 *       /          gamma          \
 | 
			
		||||
 *      /                           \
 | 
			
		||||
 *   i *                            * f
 | 
			
		||||
 *      \                          /
 | 
			
		||||
 *       \                        /
 | 
			
		||||
 *        \----------->----------/
 | 
			
		||||
 *                   q1
 | 
			
		||||
 *
 | 
			
		||||
 *      trace(g5*q1*adj(q2)*g5*gamma*q3)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                               Gamma3pt                                     *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
BEGIN_MODULE_NAMESPACE(MContraction)
 | 
			
		||||
 | 
			
		||||
class Gamma3ptPar: Serializable
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    GRID_SERIALIZABLE_CLASS_MEMBERS(Gamma3ptPar,
 | 
			
		||||
                                    std::string,    q1,
 | 
			
		||||
                                    std::string,    q2,
 | 
			
		||||
                                    std::string,    q3,
 | 
			
		||||
                                    Gamma::Algebra, gamma,
 | 
			
		||||
                                    std::string,    output);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename FImpl1, typename FImpl2, typename FImpl3>
 | 
			
		||||
class TGamma3pt: public Module<Gamma3ptPar>
 | 
			
		||||
{
 | 
			
		||||
    TYPE_ALIASES(FImpl1, 1);
 | 
			
		||||
    TYPE_ALIASES(FImpl2, 2);
 | 
			
		||||
    TYPE_ALIASES(FImpl3, 3);
 | 
			
		||||
    class Result: Serializable
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        GRID_SERIALIZABLE_CLASS_MEMBERS(Result,
 | 
			
		||||
                                        Gamma::Algebra, gamma,
 | 
			
		||||
                                        std::vector<Complex>, corr);
 | 
			
		||||
    };
 | 
			
		||||
public:
 | 
			
		||||
    // constructor
 | 
			
		||||
    TGamma3pt(const std::string name);
 | 
			
		||||
    // destructor
 | 
			
		||||
    virtual ~TGamma3pt(void) = default;
 | 
			
		||||
    // dependency relation
 | 
			
		||||
    virtual std::vector<std::string> getInput(void);
 | 
			
		||||
    virtual std::vector<std::string> getOutput(void);
 | 
			
		||||
    // setup
 | 
			
		||||
    virtual void setup(void);
 | 
			
		||||
    // execution
 | 
			
		||||
    virtual void execute(void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
MODULE_REGISTER_NS(Gamma3pt, ARG(TGamma3pt<FIMPL, FIMPL, FIMPL>), MContraction);
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                       TGamma3pt implementation                             *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
// constructor /////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl1, typename FImpl2, typename FImpl3>
 | 
			
		||||
TGamma3pt<FImpl1, FImpl2, FImpl3>::TGamma3pt(const std::string name)
 | 
			
		||||
: Module<Gamma3ptPar>(name)
 | 
			
		||||
{}
 | 
			
		||||
 | 
			
		||||
// dependencies/products ///////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl1, typename FImpl2, typename FImpl3>
 | 
			
		||||
std::vector<std::string> TGamma3pt<FImpl1, FImpl2, FImpl3>::getInput(void)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<std::string> in = {par().q1, par().q2, par().q3};
 | 
			
		||||
    
 | 
			
		||||
    return in;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename FImpl1, typename FImpl2, typename FImpl3>
 | 
			
		||||
std::vector<std::string> TGamma3pt<FImpl1, FImpl2, FImpl3>::getOutput(void)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<std::string> out = {getName()};
 | 
			
		||||
    
 | 
			
		||||
    return out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// setup ///////////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl1, typename FImpl2, typename FImpl3>
 | 
			
		||||
void TGamma3pt<FImpl1, FImpl2, FImpl3>::setup(void)
 | 
			
		||||
{
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// execution ///////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl1, typename FImpl2, typename FImpl3>
 | 
			
		||||
void TGamma3pt<FImpl1, FImpl2, FImpl3>::execute(void)
 | 
			
		||||
{
 | 
			
		||||
    LOG(Message) << "Computing 3pt contractions '" << getName() << "' using"
 | 
			
		||||
                 << " quarks '" << par().q1 << "', '" << par().q2 << "' and '"
 | 
			
		||||
                 << par().q3 << "', with " << par().gamma << " insertion." 
 | 
			
		||||
                 << std::endl;
 | 
			
		||||
 | 
			
		||||
    CorrWriter            writer(par().output);
 | 
			
		||||
    PropagatorField1      &q1 = *env().template getObject<PropagatorField1>(par().q1);
 | 
			
		||||
    PropagatorField2      &q2 = *env().template getObject<PropagatorField2>(par().q2);
 | 
			
		||||
    PropagatorField3      &q3 = *env().template getObject<PropagatorField3>(par().q3);
 | 
			
		||||
    LatticeComplex        c(env().getGrid());
 | 
			
		||||
    Gamma                 g5(Gamma::Algebra::Gamma5);
 | 
			
		||||
    Gamma                 gamma(par().gamma);
 | 
			
		||||
    std::vector<TComplex> buf;
 | 
			
		||||
    Result                result;
 | 
			
		||||
 | 
			
		||||
    c = trace(g5*q1*adj(q2)*(g5*gamma)*q3);
 | 
			
		||||
    sliceSum(c, buf, Tp);
 | 
			
		||||
 | 
			
		||||
    result.gamma = par().gamma;
 | 
			
		||||
    result.corr.resize(buf.size());
 | 
			
		||||
    for (unsigned int t = 0; t < buf.size(); ++t)
 | 
			
		||||
    {
 | 
			
		||||
        result.corr[t] = TensorRemove(buf[t]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    write(writer, "gamma3pt", result);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
END_MODULE_NAMESPACE
 | 
			
		||||
 | 
			
		||||
END_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
#endif // Hadrons_Gamma3pt_hpp_
 | 
			
		||||
							
								
								
									
										210
									
								
								extras/Hadrons/Modules/MContraction/Meson.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										210
									
								
								extras/Hadrons/Modules/MContraction/Meson.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,210 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
Source file: extras/Hadrons/Modules/MContraction/Meson.hpp
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2015
 | 
			
		||||
Copyright (C) 2016
 | 
			
		||||
Copyright (C) 2017
 | 
			
		||||
 | 
			
		||||
Author: Antonin Portelli <antonin.portelli@me.com>
 | 
			
		||||
        Andrew Lawson    <andrew.lawson1991@gmail.com>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
 | 
			
		||||
#ifndef Hadrons_Meson_hpp_
 | 
			
		||||
#define Hadrons_Meson_hpp_
 | 
			
		||||
 | 
			
		||||
#include <Grid/Hadrons/Global.hpp>
 | 
			
		||||
#include <Grid/Hadrons/Module.hpp>
 | 
			
		||||
#include <Grid/Hadrons/ModuleFactory.hpp>
 | 
			
		||||
 | 
			
		||||
BEGIN_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 
 | 
			
		||||
 Meson contractions
 | 
			
		||||
 -----------------------------
 | 
			
		||||
 
 | 
			
		||||
 * options:
 | 
			
		||||
 - q1: input propagator 1 (string)
 | 
			
		||||
 - q2: input propagator 2 (string)
 | 
			
		||||
 - gammas: gamma products to insert at sink & source, pairs of gamma matrices 
 | 
			
		||||
           (space-separated strings) in angled brackets (i.e. <g_sink g_src>),
 | 
			
		||||
           in a sequence (e.g. "<Gamma5 Gamma5><Gamma5 GammaT>").
 | 
			
		||||
 | 
			
		||||
           Special values: "all" - perform all possible contractions.
 | 
			
		||||
 - mom: momentum insertion, space-separated float sequence (e.g ".1 .2 1. 0."),
 | 
			
		||||
        given as multiples of (2*pi) / L.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                                TMeson                                       *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
BEGIN_MODULE_NAMESPACE(MContraction)
 | 
			
		||||
 | 
			
		||||
typedef std::pair<Gamma::Algebra, Gamma::Algebra> GammaPair;
 | 
			
		||||
 | 
			
		||||
class MesonPar: Serializable
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    GRID_SERIALIZABLE_CLASS_MEMBERS(MesonPar,
 | 
			
		||||
                                    std::string, q1,
 | 
			
		||||
                                    std::string, q2,
 | 
			
		||||
                                    std::string, gammas,
 | 
			
		||||
                                    std::string, mom,
 | 
			
		||||
                                    std::string, output);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename FImpl1, typename FImpl2>
 | 
			
		||||
class TMeson: public Module<MesonPar>
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    TYPE_ALIASES(FImpl1, 1);
 | 
			
		||||
    TYPE_ALIASES(FImpl2, 2);
 | 
			
		||||
    class Result: Serializable
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        GRID_SERIALIZABLE_CLASS_MEMBERS(Result,
 | 
			
		||||
                                        Gamma::Algebra, gamma_snk,
 | 
			
		||||
                                        Gamma::Algebra, gamma_src,
 | 
			
		||||
                                        std::vector<Complex>, corr);
 | 
			
		||||
    };
 | 
			
		||||
public:
 | 
			
		||||
    // constructor
 | 
			
		||||
    TMeson(const std::string name);
 | 
			
		||||
    // destructor
 | 
			
		||||
    virtual ~TMeson(void) = default;
 | 
			
		||||
    // dependencies/products
 | 
			
		||||
    virtual std::vector<std::string> getInput(void);
 | 
			
		||||
    virtual std::vector<std::string> getOutput(void);
 | 
			
		||||
    virtual void parseGammaString(std::vector<GammaPair> &gammaList);
 | 
			
		||||
    // execution
 | 
			
		||||
    virtual void execute(void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
MODULE_REGISTER_NS(Meson, ARG(TMeson<FIMPL, FIMPL>), MContraction);
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                           TMeson implementation                            *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
// constructor /////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl1, typename FImpl2>
 | 
			
		||||
TMeson<FImpl1, FImpl2>::TMeson(const std::string name)
 | 
			
		||||
: Module<MesonPar>(name)
 | 
			
		||||
{}
 | 
			
		||||
 | 
			
		||||
// dependencies/products ///////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl1, typename FImpl2>
 | 
			
		||||
std::vector<std::string> TMeson<FImpl1, FImpl2>::getInput(void)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<std::string> input = {par().q1, par().q2};
 | 
			
		||||
    
 | 
			
		||||
    return input;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename FImpl1, typename FImpl2>
 | 
			
		||||
std::vector<std::string> TMeson<FImpl1, FImpl2>::getOutput(void)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<std::string> output = {getName()};
 | 
			
		||||
    
 | 
			
		||||
    return output;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename FImpl1, typename FImpl2>
 | 
			
		||||
void TMeson<FImpl1, FImpl2>::parseGammaString(std::vector<GammaPair> &gammaList)
 | 
			
		||||
{
 | 
			
		||||
    gammaList.clear();
 | 
			
		||||
    // Determine gamma matrices to insert at source/sink.
 | 
			
		||||
    if (par().gammas.compare("all") == 0)
 | 
			
		||||
    {
 | 
			
		||||
        // Do all contractions.
 | 
			
		||||
        for (unsigned int i = 1; i < Gamma::nGamma; i += 2)
 | 
			
		||||
        {
 | 
			
		||||
            for (unsigned int j = 1; j < Gamma::nGamma; j += 2)
 | 
			
		||||
            {
 | 
			
		||||
                gammaList.push_back(std::make_pair((Gamma::Algebra)i, 
 | 
			
		||||
                                                   (Gamma::Algebra)j));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        // Parse individual contractions from input string.
 | 
			
		||||
        gammaList = strToVec<GammaPair>(par().gammas);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// execution ///////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl1, typename FImpl2>
 | 
			
		||||
void TMeson<FImpl1, FImpl2>::execute(void)
 | 
			
		||||
{
 | 
			
		||||
    LOG(Message) << "Computing meson contractions '" << getName() << "' using"
 | 
			
		||||
                 << " quarks '" << par().q1 << "' and '" << par().q2 << "'"
 | 
			
		||||
                 << std::endl;
 | 
			
		||||
    
 | 
			
		||||
    CorrWriter              writer(par().output);
 | 
			
		||||
    PropagatorField1       &q1 = *env().template getObject<PropagatorField1>(par().q1);
 | 
			
		||||
    PropagatorField2       &q2 = *env().template getObject<PropagatorField2>(par().q2);
 | 
			
		||||
    LatticeComplex         c(env().getGrid());
 | 
			
		||||
    Gamma                  g5(Gamma::Algebra::Gamma5);
 | 
			
		||||
    std::vector<GammaPair> gammaList;
 | 
			
		||||
    std::vector<TComplex>  buf;
 | 
			
		||||
    std::vector<Result>    result;
 | 
			
		||||
    std::vector<Real>      p;
 | 
			
		||||
 | 
			
		||||
    p  = strToVec<Real>(par().mom);
 | 
			
		||||
    LatticeComplex         ph(env().getGrid()), coor(env().getGrid());
 | 
			
		||||
    Complex                i(0.0,1.0);
 | 
			
		||||
    ph = zero;
 | 
			
		||||
    for(unsigned int mu = 0; mu < env().getNd(); mu++)
 | 
			
		||||
    {
 | 
			
		||||
        LatticeCoordinate(coor, mu);
 | 
			
		||||
        ph = ph + p[mu]*coor*((1./(env().getGrid()->_fdimensions[mu])));
 | 
			
		||||
    }
 | 
			
		||||
    ph = exp((Real)(2*M_PI)*i*ph);
 | 
			
		||||
    
 | 
			
		||||
    parseGammaString(gammaList);
 | 
			
		||||
 | 
			
		||||
    result.resize(gammaList.size());
 | 
			
		||||
    for (unsigned int i = 0; i < result.size(); ++i)
 | 
			
		||||
    {
 | 
			
		||||
        Gamma gSnk(gammaList[i].first);
 | 
			
		||||
        Gamma gSrc(gammaList[i].second);
 | 
			
		||||
        c = trace((g5*gSnk)*q1*(adj(gSrc)*g5)*adj(q2))*ph;
 | 
			
		||||
        sliceSum(c, buf, Tp);
 | 
			
		||||
 | 
			
		||||
        result[i].gamma_snk = gammaList[i].first;
 | 
			
		||||
        result[i].gamma_src = gammaList[i].second;
 | 
			
		||||
        result[i].corr.resize(buf.size());
 | 
			
		||||
        for (unsigned int t = 0; t < buf.size(); ++t)
 | 
			
		||||
        {
 | 
			
		||||
            result[i].corr[t] = TensorRemove(buf[t]);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    write(writer, "meson", result);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
END_MODULE_NAMESPACE
 | 
			
		||||
 | 
			
		||||
END_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
#endif // Hadrons_Meson_hpp_
 | 
			
		||||
							
								
								
									
										114
									
								
								extras/Hadrons/Modules/MContraction/WeakHamiltonian.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								extras/Hadrons/Modules/MContraction/WeakHamiltonian.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,114 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
Source file: extras/Hadrons/Modules/MContraction/WeakHamiltonian.hpp
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2017
 | 
			
		||||
 | 
			
		||||
Author: Andrew Lawson    <andrew.lawson1991@gmail.com>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
 | 
			
		||||
#ifndef Hadrons_WeakHamiltonian_hpp_
 | 
			
		||||
#define Hadrons_WeakHamiltonian_hpp_
 | 
			
		||||
 | 
			
		||||
#include <Grid/Hadrons/Global.hpp>
 | 
			
		||||
#include <Grid/Hadrons/Module.hpp>
 | 
			
		||||
#include <Grid/Hadrons/ModuleFactory.hpp>
 | 
			
		||||
 | 
			
		||||
BEGIN_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                         WeakHamiltonian                                    *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
BEGIN_MODULE_NAMESPACE(MContraction)
 | 
			
		||||
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
 * Utilities for contractions involving the Weak Hamiltonian.
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
//// Sum and store correlator.
 | 
			
		||||
#define MAKE_DIAG(exp, buf, res, n)\
 | 
			
		||||
sliceSum(exp, buf, Tp);\
 | 
			
		||||
res.name = (n);\
 | 
			
		||||
res.corr.resize(buf.size());\
 | 
			
		||||
for (unsigned int t = 0; t < buf.size(); ++t)\
 | 
			
		||||
{\
 | 
			
		||||
    res.corr[t] = TensorRemove(buf[t]);\
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//// Contraction of mu index: use 'mu' variable in exp.
 | 
			
		||||
#define SUM_MU(buf,exp)\
 | 
			
		||||
buf = zero;\
 | 
			
		||||
for (unsigned int mu = 0; mu < ndim; ++mu)\
 | 
			
		||||
{\
 | 
			
		||||
    buf += exp;\
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
enum 
 | 
			
		||||
{
 | 
			
		||||
  i_V = 0,
 | 
			
		||||
  i_A = 1,
 | 
			
		||||
  n_i = 2
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class WeakHamiltonianPar: Serializable
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    GRID_SERIALIZABLE_CLASS_MEMBERS(WeakHamiltonianPar,
 | 
			
		||||
                                    std::string, q1,
 | 
			
		||||
                                    std::string, q2,
 | 
			
		||||
                                    std::string, q3,
 | 
			
		||||
                                    std::string, q4,
 | 
			
		||||
                                    std::string, output);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define MAKE_WEAK_MODULE(modname)\
 | 
			
		||||
class T##modname: public Module<WeakHamiltonianPar>\
 | 
			
		||||
{\
 | 
			
		||||
public:\
 | 
			
		||||
    TYPE_ALIASES(FIMPL,)\
 | 
			
		||||
    class Result: Serializable\
 | 
			
		||||
    {\
 | 
			
		||||
    public:\
 | 
			
		||||
        GRID_SERIALIZABLE_CLASS_MEMBERS(Result,\
 | 
			
		||||
                                        std::string, name,\
 | 
			
		||||
                                        std::vector<Complex>, corr);\
 | 
			
		||||
    };\
 | 
			
		||||
public:\
 | 
			
		||||
    /* constructor */ \
 | 
			
		||||
    T##modname(const std::string name);\
 | 
			
		||||
    /* destructor */ \
 | 
			
		||||
    virtual ~T##modname(void) = default;\
 | 
			
		||||
    /* dependency relation */ \
 | 
			
		||||
    virtual std::vector<std::string> getInput(void);\
 | 
			
		||||
    virtual std::vector<std::string> getOutput(void);\
 | 
			
		||||
    /* setup */ \
 | 
			
		||||
    virtual void setup(void);\
 | 
			
		||||
    /* execution */ \
 | 
			
		||||
    virtual void execute(void);\
 | 
			
		||||
    std::vector<std::string> VA_label = {"V", "A"};\
 | 
			
		||||
};\
 | 
			
		||||
MODULE_REGISTER_NS(modname, T##modname, MContraction);
 | 
			
		||||
 | 
			
		||||
END_MODULE_NAMESPACE
 | 
			
		||||
 | 
			
		||||
END_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
#endif // Hadrons_WeakHamiltonian_hpp_
 | 
			
		||||
							
								
								
									
										137
									
								
								extras/Hadrons/Modules/MContraction/WeakHamiltonianEye.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										137
									
								
								extras/Hadrons/Modules/MContraction/WeakHamiltonianEye.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,137 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
Source file: extras/Hadrons/Modules/MContraction/WeakHamiltonianEye.cc
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2017
 | 
			
		||||
 | 
			
		||||
Author: Andrew Lawson    <andrew.lawson1991@gmail.com>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
 | 
			
		||||
#include <Grid/Hadrons/Modules/MContraction/WeakHamiltonianEye.hpp>
 | 
			
		||||
 | 
			
		||||
using namespace Grid;
 | 
			
		||||
using namespace Hadrons;
 | 
			
		||||
using namespace MContraction;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Weak Hamiltonian current-current contractions, Eye-type.
 | 
			
		||||
 * 
 | 
			
		||||
 * These contractions are generated by the Q1 and Q2 operators in the physical
 | 
			
		||||
 * basis (see e.g. Fig 3 of arXiv:1507.03094).
 | 
			
		||||
 * 
 | 
			
		||||
 * Schematics:        q4                 |                  
 | 
			
		||||
 *                  /-<-¬                |                             
 | 
			
		||||
 *                 /     \               |             q2           q3
 | 
			
		||||
 *                 \     /               |        /----<------*------<----¬                        
 | 
			
		||||
 *            q2    \   /    q3          |       /          /-*-¬          \
 | 
			
		||||
 *       /-----<-----* *-----<----¬      |      /          /     \          \
 | 
			
		||||
 *    i *            H_W           * f   |   i *           \     /  q4      * f
 | 
			
		||||
 *       \                        /      |      \           \->-/          /   
 | 
			
		||||
 *        \                      /       |       \                        /       
 | 
			
		||||
 *         \---------->---------/        |        \----------->----------/        
 | 
			
		||||
 *                   q1                  |                   q1                  
 | 
			
		||||
 *                                       |
 | 
			
		||||
 *                Saucer (S)             |                  Eye (E)
 | 
			
		||||
 * 
 | 
			
		||||
 * S: trace(q3*g5*q1*adj(q2)*g5*gL[mu][p_1]*q4*gL[mu][p_2])
 | 
			
		||||
 * E: trace(q3*g5*q1*adj(q2)*g5*gL[mu][p_1])*trace(q4*gL[mu][p_2])
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                  TWeakHamiltonianEye implementation                        *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
// constructor /////////////////////////////////////////////////////////////////
 | 
			
		||||
TWeakHamiltonianEye::TWeakHamiltonianEye(const std::string name)
 | 
			
		||||
: Module<WeakHamiltonianPar>(name)
 | 
			
		||||
{}
 | 
			
		||||
 | 
			
		||||
// dependencies/products ///////////////////////////////////////////////////////
 | 
			
		||||
std::vector<std::string> TWeakHamiltonianEye::getInput(void)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<std::string> in = {par().q1, par().q2, par().q3, par().q4};
 | 
			
		||||
    
 | 
			
		||||
    return in;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::vector<std::string> TWeakHamiltonianEye::getOutput(void)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<std::string> out = {getName()};
 | 
			
		||||
    
 | 
			
		||||
    return out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// setup ///////////////////////////////////////////////////////////////////////
 | 
			
		||||
void TWeakHamiltonianEye::setup(void)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// execution ///////////////////////////////////////////////////////////////////
 | 
			
		||||
void TWeakHamiltonianEye::execute(void)
 | 
			
		||||
{
 | 
			
		||||
    LOG(Message) << "Computing Weak Hamiltonian (Eye type) contractions '" 
 | 
			
		||||
                 << getName() << "' using quarks '" << par().q1 << "', '" 
 | 
			
		||||
                 << par().q2 << ", '" << par().q3 << "' and '" << par().q4 
 | 
			
		||||
                 << "'." << std::endl;
 | 
			
		||||
 | 
			
		||||
    CorrWriter             writer(par().output);
 | 
			
		||||
    PropagatorField &q1 = *env().template getObject<PropagatorField>(par().q1);
 | 
			
		||||
    PropagatorField &q2 = *env().template getObject<PropagatorField>(par().q2);
 | 
			
		||||
    PropagatorField &q3 = *env().template getObject<PropagatorField>(par().q3);
 | 
			
		||||
    PropagatorField &q4 = *env().template getObject<PropagatorField>(par().q4);
 | 
			
		||||
    Gamma g5            = Gamma(Gamma::Algebra::Gamma5);
 | 
			
		||||
    LatticeComplex        expbuf(env().getGrid());
 | 
			
		||||
    std::vector<TComplex> corrbuf;
 | 
			
		||||
    std::vector<Result>   result(n_eye_diag);
 | 
			
		||||
    unsigned int ndim   = env().getNd();
 | 
			
		||||
 | 
			
		||||
    PropagatorField              tmp1(env().getGrid());
 | 
			
		||||
    LatticeComplex               tmp2(env().getGrid());
 | 
			
		||||
    std::vector<PropagatorField> S_body(ndim, tmp1);
 | 
			
		||||
    std::vector<PropagatorField> S_loop(ndim, tmp1);
 | 
			
		||||
    std::vector<LatticeComplex>  E_body(ndim, tmp2);
 | 
			
		||||
    std::vector<LatticeComplex>  E_loop(ndim, tmp2);
 | 
			
		||||
 | 
			
		||||
    // Setup for S-type contractions.
 | 
			
		||||
    for (int mu = 0; mu < ndim; ++mu)
 | 
			
		||||
    {
 | 
			
		||||
        S_body[mu] = MAKE_SE_BODY(q1, q2, q3, GammaL(Gamma::gmu[mu]));
 | 
			
		||||
        S_loop[mu] = MAKE_SE_LOOP(q4, GammaL(Gamma::gmu[mu]));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Perform S-type contractions.    
 | 
			
		||||
    SUM_MU(expbuf, trace(S_body[mu]*S_loop[mu]))
 | 
			
		||||
    MAKE_DIAG(expbuf, corrbuf, result[S_diag], "HW_S")
 | 
			
		||||
 | 
			
		||||
    // Recycle sub-expressions for E-type contractions.
 | 
			
		||||
    for (unsigned int mu = 0; mu < ndim; ++mu)
 | 
			
		||||
    {
 | 
			
		||||
        E_body[mu] = trace(S_body[mu]);
 | 
			
		||||
        E_loop[mu] = trace(S_loop[mu]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Perform E-type contractions.
 | 
			
		||||
    SUM_MU(expbuf, E_body[mu]*E_loop[mu])
 | 
			
		||||
    MAKE_DIAG(expbuf, corrbuf, result[E_diag], "HW_E")
 | 
			
		||||
 | 
			
		||||
    write(writer, "HW_Eye", result);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										58
									
								
								extras/Hadrons/Modules/MContraction/WeakHamiltonianEye.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								extras/Hadrons/Modules/MContraction/WeakHamiltonianEye.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,58 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
Source file: extras/Hadrons/Modules/MContraction/WeakHamiltonianEye.hpp
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2017
 | 
			
		||||
 | 
			
		||||
Author: Andrew Lawson    <andrew.lawson1991@gmail.com>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
 | 
			
		||||
#ifndef Hadrons_WeakHamiltonianEye_hpp_
 | 
			
		||||
#define Hadrons_WeakHamiltonianEye_hpp_
 | 
			
		||||
 | 
			
		||||
#include <Grid/Hadrons/Modules/MContraction/WeakHamiltonian.hpp>
 | 
			
		||||
 | 
			
		||||
BEGIN_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                         WeakHamiltonianEye                                 *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
BEGIN_MODULE_NAMESPACE(MContraction)
 | 
			
		||||
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
    S_diag = 0,
 | 
			
		||||
    E_diag = 1,
 | 
			
		||||
    n_eye_diag = 2
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Saucer and Eye subdiagram contractions.
 | 
			
		||||
#define MAKE_SE_BODY(Q_1, Q_2, Q_3, gamma) (Q_3*g5*Q_1*adj(Q_2)*g5*gamma)
 | 
			
		||||
#define MAKE_SE_LOOP(Q_loop, gamma) (Q_loop*gamma)
 | 
			
		||||
 | 
			
		||||
MAKE_WEAK_MODULE(WeakHamiltonianEye)
 | 
			
		||||
 | 
			
		||||
END_MODULE_NAMESPACE
 | 
			
		||||
 | 
			
		||||
END_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
#endif // Hadrons_WeakHamiltonianEye_hpp_
 | 
			
		||||
							
								
								
									
										139
									
								
								extras/Hadrons/Modules/MContraction/WeakHamiltonianNonEye.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										139
									
								
								extras/Hadrons/Modules/MContraction/WeakHamiltonianNonEye.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,139 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
Source file: extras/Hadrons/Modules/MContraction/WeakHamiltonianNonEye.cc
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2017
 | 
			
		||||
 | 
			
		||||
Author: Andrew Lawson    <andrew.lawson1991@gmail.com>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
 | 
			
		||||
#include <Grid/Hadrons/Modules/MContraction/WeakHamiltonianNonEye.hpp>
 | 
			
		||||
 | 
			
		||||
using namespace Grid;
 | 
			
		||||
using namespace Hadrons;
 | 
			
		||||
using namespace MContraction;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Weak Hamiltonian current-current contractions, Non-Eye-type.
 | 
			
		||||
 * 
 | 
			
		||||
 * These contractions are generated by the Q1 and Q2 operators in the physical
 | 
			
		||||
 * basis (see e.g. Fig 3 of arXiv:1507.03094).
 | 
			
		||||
 * 
 | 
			
		||||
 * Schematic:     
 | 
			
		||||
 *            q2             q3          |           q2              q3
 | 
			
		||||
 *          /--<--¬       /--<--¬        |        /--<--¬         /--<--¬       
 | 
			
		||||
 *         /       \     /       \       |       /       \       /       \      
 | 
			
		||||
 *        /         \   /         \      |      /         \     /         \     
 | 
			
		||||
 *       /           \ /           \     |     /           \   /           \    
 | 
			
		||||
 *    i *             * H_W         *  f |  i *             * * H_W         * f 
 | 
			
		||||
 *      \             *             |    |     \           /   \           /
 | 
			
		||||
 *       \           / \           /     |      \         /     \         /    
 | 
			
		||||
 *        \         /   \         /      |       \       /       \       /  
 | 
			
		||||
 *         \       /     \       /       |        \-->--/         \-->--/      
 | 
			
		||||
 *          \-->--/       \-->--/        |          q1               q4 
 | 
			
		||||
 *            q1             q4          |
 | 
			
		||||
 *                Connected (C)          |                 Wing (W)
 | 
			
		||||
 *
 | 
			
		||||
 * C: trace(q1*adj(q2)*g5*gL[mu]*q3*adj(q4)*g5*gL[mu])
 | 
			
		||||
 * W: trace(q1*adj(q2)*g5*gL[mu])*trace(q3*adj(q4)*g5*gL[mu])
 | 
			
		||||
 * 
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                  TWeakHamiltonianNonEye implementation                     *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
// constructor /////////////////////////////////////////////////////////////////
 | 
			
		||||
TWeakHamiltonianNonEye::TWeakHamiltonianNonEye(const std::string name)
 | 
			
		||||
: Module<WeakHamiltonianPar>(name)
 | 
			
		||||
{}
 | 
			
		||||
 | 
			
		||||
// dependencies/products ///////////////////////////////////////////////////////
 | 
			
		||||
std::vector<std::string> TWeakHamiltonianNonEye::getInput(void)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<std::string> in = {par().q1, par().q2, par().q3, par().q4};
 | 
			
		||||
    
 | 
			
		||||
    return in;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::vector<std::string> TWeakHamiltonianNonEye::getOutput(void)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<std::string> out = {getName()};
 | 
			
		||||
    
 | 
			
		||||
    return out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// setup ///////////////////////////////////////////////////////////////////////
 | 
			
		||||
void TWeakHamiltonianNonEye::setup(void)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// execution ///////////////////////////////////////////////////////////////////
 | 
			
		||||
void TWeakHamiltonianNonEye::execute(void)
 | 
			
		||||
{
 | 
			
		||||
    LOG(Message) << "Computing Weak Hamiltonian (Non-Eye type) contractions '" 
 | 
			
		||||
                 << getName() << "' using quarks '" << par().q1 << "', '" 
 | 
			
		||||
                 << par().q2 << ", '" << par().q3 << "' and '" << par().q4 
 | 
			
		||||
                 << "'." << std::endl;
 | 
			
		||||
    
 | 
			
		||||
    CorrWriter             writer(par().output);
 | 
			
		||||
    PropagatorField &q1 = *env().template getObject<PropagatorField>(par().q1);
 | 
			
		||||
    PropagatorField &q2 = *env().template getObject<PropagatorField>(par().q2);
 | 
			
		||||
    PropagatorField &q3 = *env().template getObject<PropagatorField>(par().q3);
 | 
			
		||||
    PropagatorField &q4 = *env().template getObject<PropagatorField>(par().q4);
 | 
			
		||||
    Gamma g5            = Gamma(Gamma::Algebra::Gamma5);
 | 
			
		||||
    LatticeComplex        expbuf(env().getGrid());
 | 
			
		||||
    std::vector<TComplex> corrbuf;
 | 
			
		||||
    std::vector<Result>   result(n_noneye_diag); 
 | 
			
		||||
    unsigned int ndim   = env().getNd();
 | 
			
		||||
 | 
			
		||||
    PropagatorField              tmp1(env().getGrid());
 | 
			
		||||
    LatticeComplex               tmp2(env().getGrid());
 | 
			
		||||
    std::vector<PropagatorField> C_i_side_loop(ndim, tmp1);
 | 
			
		||||
    std::vector<PropagatorField> C_f_side_loop(ndim, tmp1);
 | 
			
		||||
    std::vector<LatticeComplex>  W_i_side_loop(ndim, tmp2);
 | 
			
		||||
    std::vector<LatticeComplex>  W_f_side_loop(ndim, tmp2);
 | 
			
		||||
 | 
			
		||||
    // Setup for C-type contractions.
 | 
			
		||||
    for (int mu = 0; mu < ndim; ++mu)
 | 
			
		||||
    {
 | 
			
		||||
        C_i_side_loop[mu] = MAKE_CW_SUBDIAG(q1, q2, GammaL(Gamma::gmu[mu]));
 | 
			
		||||
        C_f_side_loop[mu] = MAKE_CW_SUBDIAG(q3, q4, GammaL(Gamma::gmu[mu]));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Perform C-type contractions.    
 | 
			
		||||
    SUM_MU(expbuf, trace(C_i_side_loop[mu]*C_f_side_loop[mu]))
 | 
			
		||||
    MAKE_DIAG(expbuf, corrbuf, result[C_diag], "HW_C")
 | 
			
		||||
 | 
			
		||||
    // Recycle sub-expressions for W-type contractions.
 | 
			
		||||
    for (unsigned int mu = 0; mu < ndim; ++mu)
 | 
			
		||||
    {
 | 
			
		||||
        W_i_side_loop[mu] = trace(C_i_side_loop[mu]);
 | 
			
		||||
        W_f_side_loop[mu] = trace(C_f_side_loop[mu]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Perform W-type contractions.
 | 
			
		||||
    SUM_MU(expbuf, W_i_side_loop[mu]*W_f_side_loop[mu])
 | 
			
		||||
    MAKE_DIAG(expbuf, corrbuf, result[W_diag], "HW_W")
 | 
			
		||||
 | 
			
		||||
    write(writer, "HW_NonEye", result);
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,57 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
Source file: extras/Hadrons/Modules/MContraction/WeakHamiltonianNonEye.hpp
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2017
 | 
			
		||||
 | 
			
		||||
Author: Andrew Lawson    <andrew.lawson1991@gmail.com>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
 | 
			
		||||
#ifndef Hadrons_WeakHamiltonianNonEye_hpp_
 | 
			
		||||
#define Hadrons_WeakHamiltonianNonEye_hpp_
 | 
			
		||||
 | 
			
		||||
#include <Grid/Hadrons/Modules/MContraction/WeakHamiltonian.hpp>
 | 
			
		||||
 | 
			
		||||
BEGIN_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                         WeakHamiltonianNonEye                              *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
BEGIN_MODULE_NAMESPACE(MContraction)
 | 
			
		||||
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
    W_diag = 0,
 | 
			
		||||
    C_diag = 1,
 | 
			
		||||
    n_noneye_diag = 2
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Wing and Connected subdiagram contractions
 | 
			
		||||
#define MAKE_CW_SUBDIAG(Q_1, Q_2, gamma) (Q_1*adj(Q_2)*g5*gamma)
 | 
			
		||||
 | 
			
		||||
MAKE_WEAK_MODULE(WeakHamiltonianNonEye)
 | 
			
		||||
 | 
			
		||||
END_MODULE_NAMESPACE
 | 
			
		||||
 | 
			
		||||
END_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
#endif // Hadrons_WeakHamiltonianNonEye_hpp_
 | 
			
		||||
							
								
								
									
										135
									
								
								extras/Hadrons/Modules/MContraction/WeakNeutral4ptDisc.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										135
									
								
								extras/Hadrons/Modules/MContraction/WeakNeutral4ptDisc.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,135 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
Source file: extras/Hadrons/Modules/MContraction/WeakNeutral4ptDisc.cc
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2017
 | 
			
		||||
 | 
			
		||||
Author: Andrew Lawson    <andrew.lawson1991@gmail.com>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
 | 
			
		||||
#include <Grid/Hadrons/Modules/MContraction/WeakNeutral4ptDisc.hpp>
 | 
			
		||||
 | 
			
		||||
using namespace Grid;
 | 
			
		||||
using namespace Hadrons;
 | 
			
		||||
using namespace MContraction;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Weak Hamiltonian + current contractions, disconnected topology for neutral 
 | 
			
		||||
 * mesons.
 | 
			
		||||
 * 
 | 
			
		||||
 * These contractions are generated by operators Q_1,...,10 of the dS=1 Weak
 | 
			
		||||
 * Hamiltonian in the physical basis and an additional current J (see e.g. 
 | 
			
		||||
 * Fig 11 of arXiv:1507.03094).
 | 
			
		||||
 * 
 | 
			
		||||
 * Schematic:
 | 
			
		||||
 *                        
 | 
			
		||||
 *           q2          q4             q3
 | 
			
		||||
 *       /--<--¬     /---<--¬       /---<--¬
 | 
			
		||||
 *     /         \ /         \     /        \
 | 
			
		||||
 *  i *           * H_W      |  J *          * f
 | 
			
		||||
 *     \         / \         /     \        /
 | 
			
		||||
 *      \--->---/   \-------/       \------/
 | 
			
		||||
 *          q1 
 | 
			
		||||
 * 
 | 
			
		||||
 * options
 | 
			
		||||
 * - q1: input propagator 1 (string)
 | 
			
		||||
 * - q2: input propagator 2 (string)
 | 
			
		||||
 * - q3: input propagator 3 (string), assumed to be sequential propagator 
 | 
			
		||||
 * - q4: input propagator 4 (string), assumed to be a loop
 | 
			
		||||
 * 
 | 
			
		||||
 * type 1: trace(q1*adj(q2)*g5*gL[mu])*trace(loop*gL[mu])*trace(q3*g5)
 | 
			
		||||
 * type 2: trace(q1*adj(q2)*g5*gL[mu]*loop*gL[mu])*trace(q3*g5)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
 *                  TWeakNeutral4ptDisc implementation                         *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
// constructor /////////////////////////////////////////////////////////////////
 | 
			
		||||
TWeakNeutral4ptDisc::TWeakNeutral4ptDisc(const std::string name)
 | 
			
		||||
: Module<WeakHamiltonianPar>(name)
 | 
			
		||||
{}
 | 
			
		||||
 | 
			
		||||
// dependencies/products ///////////////////////////////////////////////////////
 | 
			
		||||
std::vector<std::string> TWeakNeutral4ptDisc::getInput(void)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<std::string> in = {par().q1, par().q2, par().q3, par().q4};
 | 
			
		||||
    
 | 
			
		||||
    return in;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::vector<std::string> TWeakNeutral4ptDisc::getOutput(void)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<std::string> out = {getName()};
 | 
			
		||||
    
 | 
			
		||||
    return out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// setup ///////////////////////////////////////////////////////////////////////
 | 
			
		||||
void TWeakNeutral4ptDisc::setup(void)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// execution ///////////////////////////////////////////////////////////////////
 | 
			
		||||
void TWeakNeutral4ptDisc::execute(void)
 | 
			
		||||
{
 | 
			
		||||
    LOG(Message) << "Computing Weak Hamiltonian neutral disconnected contractions '" 
 | 
			
		||||
                 << getName() << "' using quarks '" << par().q1 << "', '" 
 | 
			
		||||
                 << par().q2 << ", '" << par().q3 << "' and '" << par().q4 
 | 
			
		||||
                 << "'." << std::endl;
 | 
			
		||||
 | 
			
		||||
    CorrWriter             writer(par().output);
 | 
			
		||||
    PropagatorField &q1 = *env().template getObject<PropagatorField>(par().q1);
 | 
			
		||||
    PropagatorField &q2 = *env().template getObject<PropagatorField>(par().q2);
 | 
			
		||||
    PropagatorField &q3 = *env().template getObject<PropagatorField>(par().q3);
 | 
			
		||||
    PropagatorField &q4 = *env().template getObject<PropagatorField>(par().q4);
 | 
			
		||||
    Gamma g5            = Gamma(Gamma::Algebra::Gamma5);
 | 
			
		||||
    LatticeComplex        expbuf(env().getGrid());
 | 
			
		||||
    std::vector<TComplex> corrbuf;
 | 
			
		||||
    std::vector<Result>   result(n_neut_disc_diag);
 | 
			
		||||
    unsigned int ndim   = env().getNd();
 | 
			
		||||
 | 
			
		||||
    PropagatorField              tmp(env().getGrid());
 | 
			
		||||
    std::vector<PropagatorField> meson(ndim, tmp);
 | 
			
		||||
    std::vector<PropagatorField> loop(ndim, tmp);
 | 
			
		||||
    LatticeComplex               curr(env().getGrid());
 | 
			
		||||
 | 
			
		||||
    // Setup for type 1 contractions.
 | 
			
		||||
    for (int mu = 0; mu < ndim; ++mu)
 | 
			
		||||
    {
 | 
			
		||||
        meson[mu] = MAKE_DISC_MESON(q1, q2, GammaL(Gamma::gmu[mu]));
 | 
			
		||||
        loop[mu] = MAKE_DISC_LOOP(q4, GammaL(Gamma::gmu[mu]));
 | 
			
		||||
    }
 | 
			
		||||
    curr = MAKE_DISC_CURR(q3, GammaL(Gamma::Algebra::Gamma5));
 | 
			
		||||
 | 
			
		||||
    // Perform type 1 contractions.    
 | 
			
		||||
    SUM_MU(expbuf, trace(meson[mu]*loop[mu]))
 | 
			
		||||
    expbuf *= curr;
 | 
			
		||||
    MAKE_DIAG(expbuf, corrbuf, result[neut_disc_1_diag], "HW_disc0_1")
 | 
			
		||||
 | 
			
		||||
    // Perform type 2 contractions.
 | 
			
		||||
    SUM_MU(expbuf, trace(meson[mu])*trace(loop[mu]))
 | 
			
		||||
    expbuf *= curr;
 | 
			
		||||
    MAKE_DIAG(expbuf, corrbuf, result[neut_disc_2_diag], "HW_disc0_2")
 | 
			
		||||
 | 
			
		||||
    write(writer, "HW_disc0", result);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										59
									
								
								extras/Hadrons/Modules/MContraction/WeakNeutral4ptDisc.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								extras/Hadrons/Modules/MContraction/WeakNeutral4ptDisc.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,59 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
Source file: extras/Hadrons/Modules/MContraction/WeakNeutral4ptDisc.hpp
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2017
 | 
			
		||||
 | 
			
		||||
Author: Andrew Lawson    <andrew.lawson1991@gmail.com>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
 | 
			
		||||
#ifndef Hadrons_WeakNeutral4ptDisc_hpp_
 | 
			
		||||
#define Hadrons_WeakNeutral4ptDisc_hpp_
 | 
			
		||||
 | 
			
		||||
#include <Grid/Hadrons/Modules/MContraction/WeakHamiltonian.hpp>
 | 
			
		||||
 | 
			
		||||
BEGIN_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                         WeakNeutral4ptDisc                                 *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
BEGIN_MODULE_NAMESPACE(MContraction)
 | 
			
		||||
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
    neut_disc_1_diag = 0,
 | 
			
		||||
    neut_disc_2_diag = 1,
 | 
			
		||||
    n_neut_disc_diag = 2
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Neutral 4pt disconnected subdiagram contractions.
 | 
			
		||||
#define MAKE_DISC_MESON(Q_1, Q_2, gamma) (Q_1*adj(Q_2)*g5*gamma)
 | 
			
		||||
#define MAKE_DISC_LOOP(Q_LOOP, gamma) (Q_LOOP*gamma)
 | 
			
		||||
#define MAKE_DISC_CURR(Q_c, gamma) (trace(Q_c*gamma))
 | 
			
		||||
 | 
			
		||||
MAKE_WEAK_MODULE(WeakNeutral4ptDisc)
 | 
			
		||||
 | 
			
		||||
END_MODULE_NAMESPACE
 | 
			
		||||
 | 
			
		||||
END_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
#endif // Hadrons_WeakNeutral4ptDisc_hpp_
 | 
			
		||||
							
								
								
									
										78
									
								
								extras/Hadrons/Modules/MGauge/Load.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								extras/Hadrons/Modules/MGauge/Load.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,78 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
Source file: extras/Hadrons/Modules/MGauge/Load.cc
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2015
 | 
			
		||||
Copyright (C) 2016
 | 
			
		||||
 | 
			
		||||
Author: Antonin Portelli <antonin.portelli@me.com>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
 | 
			
		||||
#include <Grid/Hadrons/Modules/MGauge/Load.hpp>
 | 
			
		||||
 | 
			
		||||
using namespace Grid;
 | 
			
		||||
using namespace Hadrons;
 | 
			
		||||
using namespace MGauge;
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
*                           TLoad implementation                               *
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
// constructor /////////////////////////////////////////////////////////////////
 | 
			
		||||
TLoad::TLoad(const std::string name)
 | 
			
		||||
: Module<LoadPar>(name)
 | 
			
		||||
{}
 | 
			
		||||
 | 
			
		||||
// dependencies/products ///////////////////////////////////////////////////////
 | 
			
		||||
std::vector<std::string> TLoad::getInput(void)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<std::string> in;
 | 
			
		||||
    
 | 
			
		||||
    return in;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::vector<std::string> TLoad::getOutput(void)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<std::string> out = {getName()};
 | 
			
		||||
    
 | 
			
		||||
    return out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// setup ///////////////////////////////////////////////////////////////////////
 | 
			
		||||
void TLoad::setup(void)
 | 
			
		||||
{
 | 
			
		||||
    env().registerLattice<LatticeGaugeField>(getName());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// execution ///////////////////////////////////////////////////////////////////
 | 
			
		||||
void TLoad::execute(void)
 | 
			
		||||
{
 | 
			
		||||
    FieldMetaData  header;
 | 
			
		||||
    std::string fileName = par().file + "."
 | 
			
		||||
                           + std::to_string(env().getTrajectory());
 | 
			
		||||
    
 | 
			
		||||
    LOG(Message) << "Loading NERSC configuration from file '" << fileName
 | 
			
		||||
                 << "'" << std::endl;
 | 
			
		||||
    LatticeGaugeField &U = *env().createLattice<LatticeGaugeField>(getName());
 | 
			
		||||
    NerscIO::readConfiguration(U, header, fileName);
 | 
			
		||||
    LOG(Message) << "NERSC header:" << std::endl;
 | 
			
		||||
    dump_meta_data(header, LOG(Message));
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										73
									
								
								extras/Hadrons/Modules/MGauge/Load.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								extras/Hadrons/Modules/MGauge/Load.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,73 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
Source file: extras/Hadrons/Modules/MGauge/Load.hpp
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2015
 | 
			
		||||
Copyright (C) 2016
 | 
			
		||||
 | 
			
		||||
Author: Antonin Portelli <antonin.portelli@me.com>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
 | 
			
		||||
#ifndef Hadrons_Load_hpp_
 | 
			
		||||
#define Hadrons_Load_hpp_
 | 
			
		||||
 | 
			
		||||
#include <Grid/Hadrons/Global.hpp>
 | 
			
		||||
#include <Grid/Hadrons/Module.hpp>
 | 
			
		||||
#include <Grid/Hadrons/ModuleFactory.hpp>
 | 
			
		||||
 | 
			
		||||
BEGIN_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                         Load a NERSC configuration                         *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
BEGIN_MODULE_NAMESPACE(MGauge)
 | 
			
		||||
 | 
			
		||||
class LoadPar: Serializable
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    GRID_SERIALIZABLE_CLASS_MEMBERS(LoadPar,
 | 
			
		||||
                                    std::string, file);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class TLoad: public Module<LoadPar>
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    // constructor
 | 
			
		||||
    TLoad(const std::string name);
 | 
			
		||||
    // destructor
 | 
			
		||||
    virtual ~TLoad(void) = default;
 | 
			
		||||
    // dependency relation
 | 
			
		||||
    virtual std::vector<std::string> getInput(void);
 | 
			
		||||
    virtual std::vector<std::string> getOutput(void);
 | 
			
		||||
    // setup
 | 
			
		||||
    virtual void setup(void);
 | 
			
		||||
    // execution
 | 
			
		||||
    virtual void execute(void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
MODULE_REGISTER_NS(Load, TLoad, MGauge);
 | 
			
		||||
 | 
			
		||||
END_MODULE_NAMESPACE
 | 
			
		||||
 | 
			
		||||
END_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
#endif // Hadrons_Load_hpp_
 | 
			
		||||
							
								
								
									
										69
									
								
								extras/Hadrons/Modules/MGauge/Random.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								extras/Hadrons/Modules/MGauge/Random.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,69 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
Source file: extras/Hadrons/Modules/MGauge/Random.cc
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2015
 | 
			
		||||
Copyright (C) 2016
 | 
			
		||||
 | 
			
		||||
Author: Antonin Portelli <antonin.portelli@me.com>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
 | 
			
		||||
#include <Grid/Hadrons/Modules/MGauge/Random.hpp>
 | 
			
		||||
 | 
			
		||||
using namespace Grid;
 | 
			
		||||
using namespace Hadrons;
 | 
			
		||||
using namespace MGauge;
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
*                           TRandom implementation                            *
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
// constructor /////////////////////////////////////////////////////////////////
 | 
			
		||||
TRandom::TRandom(const std::string name)
 | 
			
		||||
: Module<NoPar>(name)
 | 
			
		||||
{}
 | 
			
		||||
 | 
			
		||||
// dependencies/products ///////////////////////////////////////////////////////
 | 
			
		||||
std::vector<std::string> TRandom::getInput(void)
 | 
			
		||||
{
 | 
			
		||||
    return std::vector<std::string>();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::vector<std::string> TRandom::getOutput(void)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<std::string> out = {getName()};
 | 
			
		||||
    
 | 
			
		||||
    return out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// setup ///////////////////////////////////////////////////////////////////////
 | 
			
		||||
void TRandom::setup(void)
 | 
			
		||||
{
 | 
			
		||||
    env().registerLattice<LatticeGaugeField>(getName());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// execution ///////////////////////////////////////////////////////////////////
 | 
			
		||||
void TRandom::execute(void)
 | 
			
		||||
{
 | 
			
		||||
    LOG(Message) << "Generating random gauge configuration" << std::endl;
 | 
			
		||||
    LatticeGaugeField &U = *env().createLattice<LatticeGaugeField>(getName());
 | 
			
		||||
    SU3::HotConfiguration(*env().get4dRng(), U);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										66
									
								
								extras/Hadrons/Modules/MGauge/Random.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								extras/Hadrons/Modules/MGauge/Random.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,66 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
Source file: extras/Hadrons/Modules/MGauge/Random.hpp
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2015
 | 
			
		||||
Copyright (C) 2016
 | 
			
		||||
 | 
			
		||||
Author: Antonin Portelli <antonin.portelli@me.com>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
 | 
			
		||||
#ifndef Hadrons_Random_hpp_
 | 
			
		||||
#define Hadrons_Random_hpp_
 | 
			
		||||
 | 
			
		||||
#include <Grid/Hadrons/Global.hpp>
 | 
			
		||||
#include <Grid/Hadrons/Module.hpp>
 | 
			
		||||
#include <Grid/Hadrons/ModuleFactory.hpp>
 | 
			
		||||
 | 
			
		||||
BEGIN_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                             Random gauge                                   *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
BEGIN_MODULE_NAMESPACE(MGauge)
 | 
			
		||||
 | 
			
		||||
class TRandom: public Module<NoPar>
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    // constructor
 | 
			
		||||
    TRandom(const std::string name);
 | 
			
		||||
    // destructor
 | 
			
		||||
    virtual ~TRandom(void) = default;
 | 
			
		||||
    // dependency relation
 | 
			
		||||
    virtual std::vector<std::string> getInput(void);
 | 
			
		||||
    virtual std::vector<std::string> getOutput(void);
 | 
			
		||||
    // setup
 | 
			
		||||
    virtual void setup(void);
 | 
			
		||||
    // execution
 | 
			
		||||
    virtual void execute(void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
MODULE_REGISTER_NS(Random, TRandom, MGauge);
 | 
			
		||||
 | 
			
		||||
END_MODULE_NAMESPACE
 | 
			
		||||
 | 
			
		||||
END_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
#endif // Hadrons_Random_hpp_
 | 
			
		||||
							
								
								
									
										69
									
								
								extras/Hadrons/Modules/MGauge/Unit.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								extras/Hadrons/Modules/MGauge/Unit.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,69 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
Source file: extras/Hadrons/Modules/MGauge/Unit.cc
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2015
 | 
			
		||||
Copyright (C) 2016
 | 
			
		||||
 | 
			
		||||
Author: Antonin Portelli <antonin.portelli@me.com>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
 | 
			
		||||
#include <Grid/Hadrons/Modules/MGauge/Unit.hpp>
 | 
			
		||||
 | 
			
		||||
using namespace Grid;
 | 
			
		||||
using namespace Hadrons;
 | 
			
		||||
using namespace MGauge;
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
*                            TUnit implementation                             *
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
// constructor /////////////////////////////////////////////////////////////////
 | 
			
		||||
TUnit::TUnit(const std::string name)
 | 
			
		||||
: Module<NoPar>(name)
 | 
			
		||||
{}
 | 
			
		||||
 | 
			
		||||
// dependencies/products ///////////////////////////////////////////////////////
 | 
			
		||||
std::vector<std::string> TUnit::getInput(void)
 | 
			
		||||
{
 | 
			
		||||
    return std::vector<std::string>();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::vector<std::string> TUnit::getOutput(void)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<std::string> out = {getName()};
 | 
			
		||||
    
 | 
			
		||||
    return out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// setup ///////////////////////////////////////////////////////////////////////
 | 
			
		||||
void TUnit::setup(void)
 | 
			
		||||
{
 | 
			
		||||
    env().registerLattice<LatticeGaugeField>(getName());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// execution ///////////////////////////////////////////////////////////////////
 | 
			
		||||
void TUnit::execute(void)
 | 
			
		||||
{
 | 
			
		||||
    LOG(Message) << "Creating unit gauge configuration" << std::endl;
 | 
			
		||||
    LatticeGaugeField &U = *env().createLattice<LatticeGaugeField>(getName());
 | 
			
		||||
    SU3::ColdConfiguration(*env().get4dRng(), U);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										66
									
								
								extras/Hadrons/Modules/MGauge/Unit.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								extras/Hadrons/Modules/MGauge/Unit.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,66 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
Source file: extras/Hadrons/Modules/MGauge/Unit.hpp
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2015
 | 
			
		||||
Copyright (C) 2016
 | 
			
		||||
 | 
			
		||||
Author: Antonin Portelli <antonin.portelli@me.com>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
 | 
			
		||||
#ifndef Hadrons_Unit_hpp_
 | 
			
		||||
#define Hadrons_Unit_hpp_
 | 
			
		||||
 | 
			
		||||
#include <Grid/Hadrons/Global.hpp>
 | 
			
		||||
#include <Grid/Hadrons/Module.hpp>
 | 
			
		||||
#include <Grid/Hadrons/ModuleFactory.hpp>
 | 
			
		||||
 | 
			
		||||
BEGIN_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                              Unit gauge                                    *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
BEGIN_MODULE_NAMESPACE(MGauge)
 | 
			
		||||
 | 
			
		||||
class TUnit: public Module<NoPar>
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    // constructor
 | 
			
		||||
    TUnit(const std::string name);
 | 
			
		||||
    // destructor
 | 
			
		||||
    virtual ~TUnit(void) = default;
 | 
			
		||||
    // dependencies/products
 | 
			
		||||
    virtual std::vector<std::string> getInput(void);
 | 
			
		||||
    virtual std::vector<std::string> getOutput(void);
 | 
			
		||||
    // setup
 | 
			
		||||
    virtual void setup(void);
 | 
			
		||||
    // execution
 | 
			
		||||
    virtual void execute(void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
MODULE_REGISTER_NS(Unit, TUnit, MGauge);
 | 
			
		||||
 | 
			
		||||
END_MODULE_NAMESPACE
 | 
			
		||||
 | 
			
		||||
END_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
#endif // Hadrons_Unit_hpp_
 | 
			
		||||
							
								
								
									
										132
									
								
								extras/Hadrons/Modules/MLoop/NoiseLoop.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								extras/Hadrons/Modules/MLoop/NoiseLoop.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,132 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
Source file: extras/Hadrons/Modules/MLoop/NoiseLoop.hpp
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2016
 | 
			
		||||
 | 
			
		||||
Author: Andrew Lawson <andrew.lawson1991@gmail.com>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
 | 
			
		||||
#ifndef Hadrons_NoiseLoop_hpp_
 | 
			
		||||
#define Hadrons_NoiseLoop_hpp_
 | 
			
		||||
 | 
			
		||||
#include <Grid/Hadrons/Global.hpp>
 | 
			
		||||
#include <Grid/Hadrons/Module.hpp>
 | 
			
		||||
#include <Grid/Hadrons/ModuleFactory.hpp>
 | 
			
		||||
 | 
			
		||||
BEGIN_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 
 | 
			
		||||
 Noise loop propagator
 | 
			
		||||
 -----------------------------
 | 
			
		||||
 * loop_x = q_x * adj(eta_x)
 | 
			
		||||
 
 | 
			
		||||
 * options:
 | 
			
		||||
 - q = Result of inversion on noise source.
 | 
			
		||||
 - eta = noise source.
 | 
			
		||||
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                         NoiseLoop                                          *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
BEGIN_MODULE_NAMESPACE(MLoop)
 | 
			
		||||
 | 
			
		||||
class NoiseLoopPar: Serializable
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    GRID_SERIALIZABLE_CLASS_MEMBERS(NoiseLoopPar,
 | 
			
		||||
                                    std::string, q,
 | 
			
		||||
                                    std::string, eta);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
class TNoiseLoop: public Module<NoiseLoopPar>
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    TYPE_ALIASES(FImpl,);
 | 
			
		||||
public:
 | 
			
		||||
    // constructor
 | 
			
		||||
    TNoiseLoop(const std::string name);
 | 
			
		||||
    // destructor
 | 
			
		||||
    virtual ~TNoiseLoop(void) = default;
 | 
			
		||||
    // dependency relation
 | 
			
		||||
    virtual std::vector<std::string> getInput(void);
 | 
			
		||||
    virtual std::vector<std::string> getOutput(void);
 | 
			
		||||
    // setup
 | 
			
		||||
    virtual void setup(void);
 | 
			
		||||
    // execution
 | 
			
		||||
    virtual void execute(void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
MODULE_REGISTER_NS(NoiseLoop, TNoiseLoop<FIMPL>, MLoop);
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                 TNoiseLoop implementation                                  *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
// constructor /////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
TNoiseLoop<FImpl>::TNoiseLoop(const std::string name)
 | 
			
		||||
: Module<NoiseLoopPar>(name)
 | 
			
		||||
{}
 | 
			
		||||
 | 
			
		||||
// dependencies/products ///////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
std::vector<std::string> TNoiseLoop<FImpl>::getInput(void)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<std::string> in = {par().q, par().eta};
 | 
			
		||||
    
 | 
			
		||||
    return in;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
std::vector<std::string> TNoiseLoop<FImpl>::getOutput(void)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<std::string> out = {getName()};
 | 
			
		||||
    
 | 
			
		||||
    return out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// setup ///////////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
void TNoiseLoop<FImpl>::setup(void)
 | 
			
		||||
{
 | 
			
		||||
    env().template registerLattice<PropagatorField>(getName());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// execution ///////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
void TNoiseLoop<FImpl>::execute(void)
 | 
			
		||||
{
 | 
			
		||||
    PropagatorField &loop = *env().template createLattice<PropagatorField>(getName());
 | 
			
		||||
    PropagatorField &q    = *env().template getObject<PropagatorField>(par().q);
 | 
			
		||||
    PropagatorField &eta  = *env().template getObject<PropagatorField>(par().eta);
 | 
			
		||||
    loop = q*adj(eta);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
END_MODULE_NAMESPACE
 | 
			
		||||
 | 
			
		||||
END_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
#endif // Hadrons_NoiseLoop_hpp_
 | 
			
		||||
							
								
								
									
										132
									
								
								extras/Hadrons/Modules/MSolver/RBPrecCG.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								extras/Hadrons/Modules/MSolver/RBPrecCG.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,132 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
Source file: extras/Hadrons/Modules/MSolver/RBPrecCG.hpp
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2015
 | 
			
		||||
Copyright (C) 2016
 | 
			
		||||
 | 
			
		||||
Author: Antonin Portelli <antonin.portelli@me.com>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
 | 
			
		||||
#ifndef Hadrons_RBPrecCG_hpp_
 | 
			
		||||
#define Hadrons_RBPrecCG_hpp_
 | 
			
		||||
 | 
			
		||||
#include <Grid/Hadrons/Global.hpp>
 | 
			
		||||
#include <Grid/Hadrons/Module.hpp>
 | 
			
		||||
#include <Grid/Hadrons/ModuleFactory.hpp>
 | 
			
		||||
 | 
			
		||||
BEGIN_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                     Schur red-black preconditioned CG                      *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
BEGIN_MODULE_NAMESPACE(MSolver)
 | 
			
		||||
 | 
			
		||||
class RBPrecCGPar: Serializable
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    GRID_SERIALIZABLE_CLASS_MEMBERS(RBPrecCGPar,
 | 
			
		||||
                                    std::string, action,
 | 
			
		||||
                                    double     , residual);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
class TRBPrecCG: public Module<RBPrecCGPar>
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    TYPE_ALIASES(FImpl,);
 | 
			
		||||
public:
 | 
			
		||||
    // constructor
 | 
			
		||||
    TRBPrecCG(const std::string name);
 | 
			
		||||
    // destructor
 | 
			
		||||
    virtual ~TRBPrecCG(void) = default;
 | 
			
		||||
    // dependencies/products
 | 
			
		||||
    virtual std::vector<std::string> getInput(void);
 | 
			
		||||
    virtual std::vector<std::string> getOutput(void);
 | 
			
		||||
    // setup
 | 
			
		||||
    virtual void setup(void);
 | 
			
		||||
    // execution
 | 
			
		||||
    virtual void execute(void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
MODULE_REGISTER_NS(RBPrecCG, TRBPrecCG<FIMPL>, MSolver);
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                      TRBPrecCG template implementation                     *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
// constructor /////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
TRBPrecCG<FImpl>::TRBPrecCG(const std::string name)
 | 
			
		||||
: Module(name)
 | 
			
		||||
{}
 | 
			
		||||
 | 
			
		||||
// dependencies/products ///////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
std::vector<std::string> TRBPrecCG<FImpl>::getInput(void)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<std::string> in = {par().action};
 | 
			
		||||
    
 | 
			
		||||
    return in;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
std::vector<std::string> TRBPrecCG<FImpl>::getOutput(void)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<std::string> out = {getName()};
 | 
			
		||||
    
 | 
			
		||||
    return out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// setup ///////////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
void TRBPrecCG<FImpl>::setup(void)
 | 
			
		||||
{
 | 
			
		||||
    auto Ls = env().getObjectLs(par().action);
 | 
			
		||||
    
 | 
			
		||||
    env().registerObject(getName(), 0, Ls);
 | 
			
		||||
    env().addOwnership(getName(), par().action);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// execution ///////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
void TRBPrecCG<FImpl>::execute(void)
 | 
			
		||||
{
 | 
			
		||||
    auto &mat   = *(env().template getObject<FMat>(par().action));
 | 
			
		||||
    auto solver = [&mat, this](FermionField &sol, const FermionField &source)
 | 
			
		||||
    {
 | 
			
		||||
        ConjugateGradient<FermionField>           cg(par().residual, 10000);
 | 
			
		||||
        SchurRedBlackDiagMooeeSolve<FermionField> schurSolver(cg);
 | 
			
		||||
        
 | 
			
		||||
        schurSolver(mat, source, sol);
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
    LOG(Message) << "setting up Schur red-black preconditioned CG for"
 | 
			
		||||
                 << " action '" << par().action << "' with residual "
 | 
			
		||||
                 << par().residual << std::endl;
 | 
			
		||||
    env().setObject(getName(), new SolverFn(solver));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
END_MODULE_NAMESPACE
 | 
			
		||||
 | 
			
		||||
END_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
#endif // Hadrons_RBPrecCG_hpp_
 | 
			
		||||
							
								
								
									
										135
									
								
								extras/Hadrons/Modules/MSource/Point.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										135
									
								
								extras/Hadrons/Modules/MSource/Point.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,135 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
Source file: extras/Hadrons/Modules/MSource/Point.hpp
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2015
 | 
			
		||||
Copyright (C) 2016
 | 
			
		||||
 | 
			
		||||
Author: Antonin Portelli <antonin.portelli@me.com>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
 | 
			
		||||
#ifndef Hadrons_Point_hpp_
 | 
			
		||||
#define Hadrons_Point_hpp_
 | 
			
		||||
 | 
			
		||||
#include <Grid/Hadrons/Global.hpp>
 | 
			
		||||
#include <Grid/Hadrons/Module.hpp>
 | 
			
		||||
#include <Grid/Hadrons/ModuleFactory.hpp>
 | 
			
		||||
 | 
			
		||||
BEGIN_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 
 | 
			
		||||
 Point source
 | 
			
		||||
 ------------
 | 
			
		||||
 * src_x = delta_x,position
 | 
			
		||||
 
 | 
			
		||||
 * options:
 | 
			
		||||
 - position: space-separated integer sequence (e.g. "0 1 1 0")
 | 
			
		||||
 
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                                  TPoint                                     *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
BEGIN_MODULE_NAMESPACE(MSource)
 | 
			
		||||
 | 
			
		||||
class PointPar: Serializable
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    GRID_SERIALIZABLE_CLASS_MEMBERS(PointPar,
 | 
			
		||||
                                    std::string, position);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
class TPoint: public Module<PointPar>
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    TYPE_ALIASES(FImpl,);
 | 
			
		||||
public:
 | 
			
		||||
    // constructor
 | 
			
		||||
    TPoint(const std::string name);
 | 
			
		||||
    // destructor
 | 
			
		||||
    virtual ~TPoint(void) = default;
 | 
			
		||||
    // dependency relation
 | 
			
		||||
    virtual std::vector<std::string> getInput(void);
 | 
			
		||||
    virtual std::vector<std::string> getOutput(void);
 | 
			
		||||
    // setup
 | 
			
		||||
    virtual void setup(void);
 | 
			
		||||
    // execution
 | 
			
		||||
    virtual void execute(void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
MODULE_REGISTER_NS(Point, TPoint<FIMPL>, MSource);
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                       TPoint template implementation                       *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
// constructor /////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
TPoint<FImpl>::TPoint(const std::string name)
 | 
			
		||||
: Module<PointPar>(name)
 | 
			
		||||
{}
 | 
			
		||||
 | 
			
		||||
// dependencies/products ///////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
std::vector<std::string> TPoint<FImpl>::getInput(void)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<std::string> in;
 | 
			
		||||
    
 | 
			
		||||
    return in;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
std::vector<std::string> TPoint<FImpl>::getOutput(void)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<std::string> out = {getName()};
 | 
			
		||||
    
 | 
			
		||||
    return out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// setup ///////////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
void TPoint<FImpl>::setup(void)
 | 
			
		||||
{
 | 
			
		||||
    env().template registerLattice<PropagatorField>(getName());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// execution ///////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
void TPoint<FImpl>::execute(void)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<int> position = strToVec<int>(par().position);
 | 
			
		||||
    typename SitePropagator::scalar_object id;
 | 
			
		||||
    
 | 
			
		||||
    LOG(Message) << "Creating point source at position [" << par().position
 | 
			
		||||
                 << "]" << std::endl;
 | 
			
		||||
    PropagatorField &src = *env().template createLattice<PropagatorField>(getName());
 | 
			
		||||
    id  = 1.;
 | 
			
		||||
    src = zero;
 | 
			
		||||
    pokeSite(id, src, position);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
END_MODULE_NAMESPACE
 | 
			
		||||
 | 
			
		||||
END_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
#endif // Hadrons_Point_hpp_
 | 
			
		||||
							
								
								
									
										164
									
								
								extras/Hadrons/Modules/MSource/SeqGamma.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										164
									
								
								extras/Hadrons/Modules/MSource/SeqGamma.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,164 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
Source file: extras/Hadrons/Modules/MSource/SeqGamma.hpp
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2015
 | 
			
		||||
Copyright (C) 2016
 | 
			
		||||
Copyright (C) 2017
 | 
			
		||||
 | 
			
		||||
Author: Antonin Portelli <antonin.portelli@me.com>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
 | 
			
		||||
#ifndef Hadrons_SeqGamma_hpp_
 | 
			
		||||
#define Hadrons_SeqGamma_hpp_
 | 
			
		||||
 | 
			
		||||
#include <Grid/Hadrons/Global.hpp>
 | 
			
		||||
#include <Grid/Hadrons/Module.hpp>
 | 
			
		||||
#include <Grid/Hadrons/ModuleFactory.hpp>
 | 
			
		||||
 | 
			
		||||
BEGIN_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 
 | 
			
		||||
 Sequential source
 | 
			
		||||
 -----------------------------
 | 
			
		||||
 * src_x = q_x * theta(x_3 - tA) * theta(tB - x_3) * gamma * exp(i x.mom)
 | 
			
		||||
 
 | 
			
		||||
 * options:
 | 
			
		||||
 - q: input propagator (string)
 | 
			
		||||
 - tA: begin timeslice (integer)
 | 
			
		||||
 - tB: end timesilce (integer)
 | 
			
		||||
 - gamma: gamma product to insert (integer)
 | 
			
		||||
 - mom: momentum insertion, space-separated float sequence (e.g ".1 .2 1. 0.")
 | 
			
		||||
 
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                         SeqGamma                                 *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
BEGIN_MODULE_NAMESPACE(MSource)
 | 
			
		||||
 | 
			
		||||
class SeqGammaPar: Serializable
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    GRID_SERIALIZABLE_CLASS_MEMBERS(SeqGammaPar,
 | 
			
		||||
                                    std::string,    q,
 | 
			
		||||
                                    unsigned int,   tA,
 | 
			
		||||
                                    unsigned int,   tB,
 | 
			
		||||
                                    Gamma::Algebra, gamma,
 | 
			
		||||
                                    std::string,    mom);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
class TSeqGamma: public Module<SeqGammaPar>
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    TYPE_ALIASES(FImpl,);
 | 
			
		||||
public:
 | 
			
		||||
    // constructor
 | 
			
		||||
    TSeqGamma(const std::string name);
 | 
			
		||||
    // destructor
 | 
			
		||||
    virtual ~TSeqGamma(void) = default;
 | 
			
		||||
    // dependency relation
 | 
			
		||||
    virtual std::vector<std::string> getInput(void);
 | 
			
		||||
    virtual std::vector<std::string> getOutput(void);
 | 
			
		||||
    // setup
 | 
			
		||||
    virtual void setup(void);
 | 
			
		||||
    // execution
 | 
			
		||||
    virtual void execute(void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
MODULE_REGISTER_NS(SeqGamma, TSeqGamma<FIMPL>, MSource);
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                         TSeqGamma implementation                           *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
// constructor /////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
TSeqGamma<FImpl>::TSeqGamma(const std::string name)
 | 
			
		||||
: Module<SeqGammaPar>(name)
 | 
			
		||||
{}
 | 
			
		||||
 | 
			
		||||
// dependencies/products ///////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
std::vector<std::string> TSeqGamma<FImpl>::getInput(void)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<std::string> in = {par().q};
 | 
			
		||||
    
 | 
			
		||||
    return in;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
std::vector<std::string> TSeqGamma<FImpl>::getOutput(void)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<std::string> out = {getName()};
 | 
			
		||||
    
 | 
			
		||||
    return out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// setup ///////////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
void TSeqGamma<FImpl>::setup(void)
 | 
			
		||||
{
 | 
			
		||||
    env().template registerLattice<PropagatorField>(getName());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// execution ///////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
void TSeqGamma<FImpl>::execute(void)
 | 
			
		||||
{
 | 
			
		||||
    if (par().tA == par().tB)
 | 
			
		||||
    {
 | 
			
		||||
        LOG(Message) << "Generating gamma_" << par().gamma
 | 
			
		||||
                     << " sequential source at t= " << par().tA << std::endl;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        LOG(Message) << "Generating gamma_" << par().gamma
 | 
			
		||||
                     << " sequential source for "
 | 
			
		||||
                     << par().tA << " <= t <= " << par().tB << std::endl;
 | 
			
		||||
    }
 | 
			
		||||
    PropagatorField &src = *env().template createLattice<PropagatorField>(getName());
 | 
			
		||||
    PropagatorField &q   = *env().template getObject<PropagatorField>(par().q);
 | 
			
		||||
    Lattice<iScalar<vInteger>> t(env().getGrid());
 | 
			
		||||
    LatticeComplex             ph(env().getGrid()), coor(env().getGrid());
 | 
			
		||||
    Gamma                      g(par().gamma);
 | 
			
		||||
    std::vector<Real>          p;
 | 
			
		||||
    Complex                    i(0.0,1.0);
 | 
			
		||||
    
 | 
			
		||||
    p  = strToVec<Real>(par().mom);
 | 
			
		||||
    ph = zero;
 | 
			
		||||
    for(unsigned int mu = 0; mu < env().getNd(); mu++)
 | 
			
		||||
    {
 | 
			
		||||
        LatticeCoordinate(coor, mu);
 | 
			
		||||
        ph = ph + p[mu]*coor*((1./(env().getGrid()->_fdimensions[mu])));
 | 
			
		||||
    }
 | 
			
		||||
    ph = exp((Real)(2*M_PI)*i*ph);
 | 
			
		||||
    LatticeCoordinate(t, Tp);
 | 
			
		||||
    src = where((t >= par().tA) and (t <= par().tB), ph*(g*q), 0.*q);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
END_MODULE_NAMESPACE
 | 
			
		||||
 | 
			
		||||
END_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
#endif // Hadrons_SeqGamma_hpp_
 | 
			
		||||
							
								
								
									
										147
									
								
								extras/Hadrons/Modules/MSource/Wall.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										147
									
								
								extras/Hadrons/Modules/MSource/Wall.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,147 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
Source file: extras/Hadrons/Modules/MSource/Wall.hpp
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2017
 | 
			
		||||
 | 
			
		||||
Author: Andrew Lawson <andrew.lawson1991@gmail.com>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
 | 
			
		||||
#ifndef Hadrons_WallSource_hpp_
 | 
			
		||||
#define Hadrons_WallSource_hpp_
 | 
			
		||||
 | 
			
		||||
#include <Grid/Hadrons/Global.hpp>
 | 
			
		||||
#include <Grid/Hadrons/Module.hpp>
 | 
			
		||||
#include <Grid/Hadrons/ModuleFactory.hpp>
 | 
			
		||||
 | 
			
		||||
BEGIN_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 
 | 
			
		||||
 Wall source
 | 
			
		||||
 -----------------------------
 | 
			
		||||
 * src_x = delta(x_3 - tW) * exp(i x.mom)
 | 
			
		||||
 
 | 
			
		||||
 * options:
 | 
			
		||||
 - tW: source timeslice (integer)
 | 
			
		||||
 - mom: momentum insertion, space-separated float sequence (e.g ".1 .2 1. 0.")
 | 
			
		||||
 
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                         Wall                                               *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
BEGIN_MODULE_NAMESPACE(MSource)
 | 
			
		||||
 | 
			
		||||
class WallPar: Serializable
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    GRID_SERIALIZABLE_CLASS_MEMBERS(WallPar,
 | 
			
		||||
                                    unsigned int, tW,
 | 
			
		||||
                                    std::string, mom);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
class TWall: public Module<WallPar>
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    TYPE_ALIASES(FImpl,);
 | 
			
		||||
public:
 | 
			
		||||
    // constructor
 | 
			
		||||
    TWall(const std::string name);
 | 
			
		||||
    // destructor
 | 
			
		||||
    virtual ~TWall(void) = default;
 | 
			
		||||
    // dependency relation
 | 
			
		||||
    virtual std::vector<std::string> getInput(void);
 | 
			
		||||
    virtual std::vector<std::string> getOutput(void);
 | 
			
		||||
    // setup
 | 
			
		||||
    virtual void setup(void);
 | 
			
		||||
    // execution
 | 
			
		||||
    virtual void execute(void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
MODULE_REGISTER_NS(Wall, TWall<FIMPL>, MSource);
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                 TWall implementation                                       *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
// constructor /////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
TWall<FImpl>::TWall(const std::string name)
 | 
			
		||||
: Module<WallPar>(name)
 | 
			
		||||
{}
 | 
			
		||||
 | 
			
		||||
// dependencies/products ///////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
std::vector<std::string> TWall<FImpl>::getInput(void)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<std::string> in;
 | 
			
		||||
    
 | 
			
		||||
    return in;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
std::vector<std::string> TWall<FImpl>::getOutput(void)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<std::string> out = {getName()};
 | 
			
		||||
    
 | 
			
		||||
    return out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// setup ///////////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
void TWall<FImpl>::setup(void)
 | 
			
		||||
{
 | 
			
		||||
    env().template registerLattice<PropagatorField>(getName());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// execution ///////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
void TWall<FImpl>::execute(void)
 | 
			
		||||
{    
 | 
			
		||||
    LOG(Message) << "Generating wall source at t = " << par().tW 
 | 
			
		||||
                 << " with momentum " << par().mom << std::endl;
 | 
			
		||||
    
 | 
			
		||||
    PropagatorField &src = *env().template createLattice<PropagatorField>(getName());
 | 
			
		||||
    Lattice<iScalar<vInteger>> t(env().getGrid());
 | 
			
		||||
    LatticeComplex             ph(env().getGrid()), coor(env().getGrid());
 | 
			
		||||
    std::vector<Real>          p;
 | 
			
		||||
    Complex                    i(0.0,1.0);
 | 
			
		||||
    
 | 
			
		||||
    p  = strToVec<Real>(par().mom);
 | 
			
		||||
    ph = zero;
 | 
			
		||||
    for(unsigned int mu = 0; mu < Nd; mu++)
 | 
			
		||||
    {
 | 
			
		||||
        LatticeCoordinate(coor, mu);
 | 
			
		||||
        ph = ph + p[mu]*coor*((1./(env().getGrid()->_fdimensions[mu])));
 | 
			
		||||
    }
 | 
			
		||||
    ph = exp((Real)(2*M_PI)*i*ph);
 | 
			
		||||
    LatticeCoordinate(t, Tp);
 | 
			
		||||
    src = 1.;
 | 
			
		||||
    src = where((t == par().tW), src*ph, 0.*src);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
END_MODULE_NAMESPACE
 | 
			
		||||
 | 
			
		||||
END_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
#endif // Hadrons_WallSource_hpp_
 | 
			
		||||
							
								
								
									
										151
									
								
								extras/Hadrons/Modules/MSource/Z2.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								extras/Hadrons/Modules/MSource/Z2.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,151 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
Source file: extras/Hadrons/Modules/MSource/Z2.hpp
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2015
 | 
			
		||||
Copyright (C) 2016
 | 
			
		||||
 | 
			
		||||
Author: Antonin Portelli <antonin.portelli@me.com>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
 | 
			
		||||
#ifndef Hadrons_Z2_hpp_
 | 
			
		||||
#define Hadrons_Z2_hpp_
 | 
			
		||||
 | 
			
		||||
#include <Grid/Hadrons/Global.hpp>
 | 
			
		||||
#include <Grid/Hadrons/Module.hpp>
 | 
			
		||||
#include <Grid/Hadrons/ModuleFactory.hpp>
 | 
			
		||||
 | 
			
		||||
BEGIN_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 
 | 
			
		||||
 Z_2 stochastic source
 | 
			
		||||
 -----------------------------
 | 
			
		||||
 * src_x = eta_x * theta(x_3 - tA) * theta(tB - x_3)
 | 
			
		||||
 
 | 
			
		||||
 the eta_x are independent uniform random numbers in {+/- 1 +/- i}
 | 
			
		||||
 
 | 
			
		||||
 * options:
 | 
			
		||||
 - tA: begin timeslice (integer)
 | 
			
		||||
 - tB: end timesilce (integer)
 | 
			
		||||
 
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                          Z2 stochastic source                              *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
BEGIN_MODULE_NAMESPACE(MSource)
 | 
			
		||||
 | 
			
		||||
class Z2Par: Serializable
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    GRID_SERIALIZABLE_CLASS_MEMBERS(Z2Par,
 | 
			
		||||
                                    unsigned int, tA,
 | 
			
		||||
                                    unsigned int, tB);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
class TZ2: public Module<Z2Par>
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    TYPE_ALIASES(FImpl,);
 | 
			
		||||
public:
 | 
			
		||||
    // constructor
 | 
			
		||||
    TZ2(const std::string name);
 | 
			
		||||
    // destructor
 | 
			
		||||
    virtual ~TZ2(void) = default;
 | 
			
		||||
    // dependency relation
 | 
			
		||||
    virtual std::vector<std::string> getInput(void);
 | 
			
		||||
    virtual std::vector<std::string> getOutput(void);
 | 
			
		||||
    // setup
 | 
			
		||||
    virtual void setup(void);
 | 
			
		||||
    // execution
 | 
			
		||||
    virtual void execute(void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
MODULE_REGISTER_NS(Z2, TZ2<FIMPL>, MSource);
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                       TZ2 template implementation                          *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
// constructor /////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
TZ2<FImpl>::TZ2(const std::string name)
 | 
			
		||||
: Module<Z2Par>(name)
 | 
			
		||||
{}
 | 
			
		||||
 | 
			
		||||
// dependencies/products ///////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
std::vector<std::string> TZ2<FImpl>::getInput(void)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<std::string> in;
 | 
			
		||||
    
 | 
			
		||||
    return in;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
std::vector<std::string> TZ2<FImpl>::getOutput(void)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<std::string> out = {getName()};
 | 
			
		||||
    
 | 
			
		||||
    return out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// setup ///////////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
void TZ2<FImpl>::setup(void)
 | 
			
		||||
{
 | 
			
		||||
    env().template registerLattice<PropagatorField>(getName());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// execution ///////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
void TZ2<FImpl>::execute(void)
 | 
			
		||||
{
 | 
			
		||||
    Lattice<iScalar<vInteger>> t(env().getGrid());
 | 
			
		||||
    LatticeComplex             eta(env().getGrid());
 | 
			
		||||
    Complex                    shift(1., 1.);
 | 
			
		||||
    
 | 
			
		||||
    if (par().tA == par().tB)
 | 
			
		||||
    {
 | 
			
		||||
        LOG(Message) << "Generating Z_2 wall source at t= " << par().tA
 | 
			
		||||
        << std::endl;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        LOG(Message) << "Generating Z_2 band for " << par().tA << " <= t <= "
 | 
			
		||||
        << par().tB << std::endl;
 | 
			
		||||
    }
 | 
			
		||||
    PropagatorField &src = *env().template createLattice<PropagatorField>(getName());
 | 
			
		||||
    LatticeCoordinate(t, Tp);
 | 
			
		||||
    bernoulli(*env().get4dRng(), eta);
 | 
			
		||||
    eta = (2.*eta - shift)*(1./::sqrt(2.));
 | 
			
		||||
    eta = where((t >= par().tA) and (t <= par().tB), eta, 0.*eta);
 | 
			
		||||
    src = 1.;
 | 
			
		||||
    src = src*eta;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
END_MODULE_NAMESPACE
 | 
			
		||||
 | 
			
		||||
END_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
#endif // Hadrons_Z2_hpp_
 | 
			
		||||
							
								
								
									
										185
									
								
								extras/Hadrons/Modules/Quark.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										185
									
								
								extras/Hadrons/Modules/Quark.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,185 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
Source file: extras/Hadrons/Modules/Quark.hpp
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2015
 | 
			
		||||
Copyright (C) 2016
 | 
			
		||||
 | 
			
		||||
Author: Antonin Portelli <antonin.portelli@me.com>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
 | 
			
		||||
#ifndef Hadrons_Quark_hpp_
 | 
			
		||||
#define Hadrons_Quark_hpp_
 | 
			
		||||
 | 
			
		||||
#include <Grid/Hadrons/Global.hpp>
 | 
			
		||||
#include <Grid/Hadrons/Module.hpp>
 | 
			
		||||
#include <Grid/Hadrons/ModuleFactory.hpp>
 | 
			
		||||
 | 
			
		||||
BEGIN_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                               TQuark                                       *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
class QuarkPar: Serializable
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    GRID_SERIALIZABLE_CLASS_MEMBERS(QuarkPar,
 | 
			
		||||
                                    std::string, source,
 | 
			
		||||
                                    std::string, solver);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
class TQuark: public Module<QuarkPar>
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    TYPE_ALIASES(FImpl,);
 | 
			
		||||
public:
 | 
			
		||||
    // constructor
 | 
			
		||||
    TQuark(const std::string name);
 | 
			
		||||
    // destructor
 | 
			
		||||
    virtual ~TQuark(void) = default;
 | 
			
		||||
    // dependencies/products
 | 
			
		||||
    virtual std::vector<std::string> getInput(void);
 | 
			
		||||
    virtual std::vector<std::string> getOutput(void);
 | 
			
		||||
    // setup
 | 
			
		||||
    virtual void setup(void);
 | 
			
		||||
    // execution
 | 
			
		||||
    virtual void execute(void);
 | 
			
		||||
private:
 | 
			
		||||
    unsigned int Ls_;
 | 
			
		||||
    SolverFn     *solver_{nullptr};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
MODULE_REGISTER(Quark, TQuark<FIMPL>);
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                          TQuark implementation                             *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
// constructor /////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
TQuark<FImpl>::TQuark(const std::string name)
 | 
			
		||||
: Module(name)
 | 
			
		||||
{}
 | 
			
		||||
 | 
			
		||||
// dependencies/products ///////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
std::vector<std::string> TQuark<FImpl>::getInput(void)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<std::string> in = {par().source, par().solver};
 | 
			
		||||
    
 | 
			
		||||
    return in;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
std::vector<std::string> TQuark<FImpl>::getOutput(void)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<std::string> out = {getName(), getName() + "_5d"};
 | 
			
		||||
    
 | 
			
		||||
    return out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// setup ///////////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
void TQuark<FImpl>::setup(void)
 | 
			
		||||
{
 | 
			
		||||
    Ls_ = env().getObjectLs(par().solver);
 | 
			
		||||
    env().template registerLattice<PropagatorField>(getName());
 | 
			
		||||
    if (Ls_ > 1)
 | 
			
		||||
    {
 | 
			
		||||
        env().template registerLattice<PropagatorField>(getName() + "_5d", Ls_);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// execution ///////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
void TQuark<FImpl>::execute(void)
 | 
			
		||||
{
 | 
			
		||||
    LOG(Message) << "Computing quark propagator '" << getName() << "'"
 | 
			
		||||
                 << std::endl;
 | 
			
		||||
    
 | 
			
		||||
    FermionField    source(env().getGrid(Ls_)), sol(env().getGrid(Ls_)),
 | 
			
		||||
                    tmp(env().getGrid());
 | 
			
		||||
    std::string     propName = (Ls_ == 1) ? getName() : (getName() + "_5d");
 | 
			
		||||
    PropagatorField &prop    = *env().template createLattice<PropagatorField>(propName);
 | 
			
		||||
    PropagatorField &fullSrc = *env().template getObject<PropagatorField>(par().source);
 | 
			
		||||
    SolverFn        &solver  = *env().template getObject<SolverFn>(par().solver);
 | 
			
		||||
    if (Ls_ > 1)
 | 
			
		||||
    {
 | 
			
		||||
        env().template createLattice<PropagatorField>(getName());
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    LOG(Message) << "Inverting using solver '" << par().solver
 | 
			
		||||
                 << "' on source '" << par().source << "'" << std::endl;
 | 
			
		||||
    for (unsigned int s = 0; s < Ns; ++s)
 | 
			
		||||
    for (unsigned int c = 0; c < Nc; ++c)
 | 
			
		||||
    {
 | 
			
		||||
        LOG(Message) << "Inversion for spin= " << s << ", color= " << c
 | 
			
		||||
        << std::endl;
 | 
			
		||||
        // source conversion for 4D sources
 | 
			
		||||
        if (!env().isObject5d(par().source))
 | 
			
		||||
        {
 | 
			
		||||
            if (Ls_ == 1)
 | 
			
		||||
            {
 | 
			
		||||
                PropToFerm(source, fullSrc, s, c);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                source = zero;
 | 
			
		||||
                PropToFerm(tmp, fullSrc, s, c);
 | 
			
		||||
                InsertSlice(tmp, source, 0, 0);
 | 
			
		||||
                InsertSlice(tmp, source, Ls_-1, 0);
 | 
			
		||||
                axpby_ssp_pplus(source, 0., source, 1., source, 0, 0);
 | 
			
		||||
                axpby_ssp_pminus(source, 0., source, 1., source, Ls_-1, Ls_-1);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        // source conversion for 5D sources
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            if (Ls_ != env().getObjectLs(par().source))
 | 
			
		||||
            {
 | 
			
		||||
                HADRON_ERROR("Ls mismatch between quark action and source");
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                PropToFerm(source, fullSrc, s, c);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        sol = zero;
 | 
			
		||||
        solver(sol, source);
 | 
			
		||||
        FermToProp(prop, sol, s, c);
 | 
			
		||||
        // create 4D propagators from 5D one if necessary
 | 
			
		||||
        if (Ls_ > 1)
 | 
			
		||||
        {
 | 
			
		||||
            PropagatorField &p4d =
 | 
			
		||||
                *env().template getObject<PropagatorField>(getName());
 | 
			
		||||
            
 | 
			
		||||
            axpby_ssp_pminus(sol, 0., sol, 1., sol, 0, 0);
 | 
			
		||||
            axpby_ssp_pplus(sol, 1., sol, 1., sol, 0, Ls_-1);
 | 
			
		||||
            ExtractSlice(tmp, sol, 0, 0);
 | 
			
		||||
            FermToProp(p4d, tmp, s, c);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
END_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
#endif // Hadrons_Quark_hpp_
 | 
			
		||||
							
								
								
									
										39
									
								
								extras/Hadrons/Modules/templates/Module.cc.template
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								extras/Hadrons/Modules/templates/Module.cc.template
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,39 @@
 | 
			
		||||
#include <Grid/Hadrons/Modules/___FILEBASENAME___.hpp>
 | 
			
		||||
 | 
			
		||||
using namespace Grid;
 | 
			
		||||
using namespace Hadrons;
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
*                  T___FILEBASENAME___ implementation                             *
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
// constructor /////////////////////////////////////////////////////////////////
 | 
			
		||||
T___FILEBASENAME___::T___FILEBASENAME___(const std::string name)
 | 
			
		||||
: Module<___FILEBASENAME___Par>(name)
 | 
			
		||||
{}
 | 
			
		||||
 | 
			
		||||
// dependencies/products ///////////////////////////////////////////////////////
 | 
			
		||||
std::vector<std::string> T___FILEBASENAME___::getInput(void)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<std::string> in;
 | 
			
		||||
    
 | 
			
		||||
    return in;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::vector<std::string> T___FILEBASENAME___::getOutput(void)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<std::string> out = {getName()};
 | 
			
		||||
    
 | 
			
		||||
    return out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// setup ///////////////////////////////////////////////////////////////////////
 | 
			
		||||
void T___FILEBASENAME___::setup(void)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// execution ///////////////////////////////////////////////////////////////////
 | 
			
		||||
void T___FILEBASENAME___::execute(void)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										40
									
								
								extras/Hadrons/Modules/templates/Module.hpp.template
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								extras/Hadrons/Modules/templates/Module.hpp.template
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
			
		||||
#ifndef Hadrons____FILEBASENAME____hpp_
 | 
			
		||||
#define Hadrons____FILEBASENAME____hpp_
 | 
			
		||||
 | 
			
		||||
#include <Grid/Hadrons/Global.hpp>
 | 
			
		||||
#include <Grid/Hadrons/Module.hpp>
 | 
			
		||||
#include <Grid/Hadrons/ModuleFactory.hpp>
 | 
			
		||||
 | 
			
		||||
BEGIN_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                         ___FILEBASENAME___                                 *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
class ___FILEBASENAME___Par: Serializable
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    GRID_SERIALIZABLE_CLASS_MEMBERS(___FILEBASENAME___Par, 
 | 
			
		||||
                                    unsigned int, i);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class T___FILEBASENAME___: public Module<___FILEBASENAME___Par>
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    // constructor
 | 
			
		||||
    T___FILEBASENAME___(const std::string name);
 | 
			
		||||
    // destructor
 | 
			
		||||
    virtual ~T___FILEBASENAME___(void) = default;
 | 
			
		||||
    // dependency relation
 | 
			
		||||
    virtual std::vector<std::string> getInput(void);
 | 
			
		||||
    virtual std::vector<std::string> getOutput(void);
 | 
			
		||||
    // setup
 | 
			
		||||
    virtual void setup(void);
 | 
			
		||||
    // execution
 | 
			
		||||
    virtual void execute(void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
MODULE_REGISTER(___FILEBASENAME___, T___FILEBASENAME___);
 | 
			
		||||
 | 
			
		||||
END_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
#endif // Hadrons____FILEBASENAME____hpp_
 | 
			
		||||
							
								
								
									
										40
									
								
								extras/Hadrons/Modules/templates/Module_in_NS.cc.template
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								extras/Hadrons/Modules/templates/Module_in_NS.cc.template
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
			
		||||
#include <Grid/Hadrons/Modules/___NAMESPACE___/___FILEBASENAME___.hpp>
 | 
			
		||||
 | 
			
		||||
using namespace Grid;
 | 
			
		||||
using namespace Hadrons;
 | 
			
		||||
using namespace ___NAMESPACE___;
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
*                  T___FILEBASENAME___ implementation                             *
 | 
			
		||||
******************************************************************************/
 | 
			
		||||
// constructor /////////////////////////////////////////////////////////////////
 | 
			
		||||
T___FILEBASENAME___::T___FILEBASENAME___(const std::string name)
 | 
			
		||||
: Module<___FILEBASENAME___Par>(name)
 | 
			
		||||
{}
 | 
			
		||||
 | 
			
		||||
// dependencies/products ///////////////////////////////////////////////////////
 | 
			
		||||
std::vector<std::string> T___FILEBASENAME___::getInput(void)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<std::string> in;
 | 
			
		||||
    
 | 
			
		||||
    return in;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::vector<std::string> T___FILEBASENAME___::getOutput(void)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<std::string> out = {getName()};
 | 
			
		||||
    
 | 
			
		||||
    return out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// setup ///////////////////////////////////////////////////////////////////////
 | 
			
		||||
void T___FILEBASENAME___::setup(void)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// execution ///////////////////////////////////////////////////////////////////
 | 
			
		||||
void T___FILEBASENAME___::execute(void)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										44
									
								
								extras/Hadrons/Modules/templates/Module_in_NS.hpp.template
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								extras/Hadrons/Modules/templates/Module_in_NS.hpp.template
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,44 @@
 | 
			
		||||
#ifndef Hadrons____FILEBASENAME____hpp_
 | 
			
		||||
#define Hadrons____FILEBASENAME____hpp_
 | 
			
		||||
 | 
			
		||||
#include <Grid/Hadrons/Global.hpp>
 | 
			
		||||
#include <Grid/Hadrons/Module.hpp>
 | 
			
		||||
#include <Grid/Hadrons/ModuleFactory.hpp>
 | 
			
		||||
 | 
			
		||||
BEGIN_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                         ___FILEBASENAME___                                 *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
BEGIN_MODULE_NAMESPACE(___NAMESPACE___)
 | 
			
		||||
 | 
			
		||||
class ___FILEBASENAME___Par: Serializable
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    GRID_SERIALIZABLE_CLASS_MEMBERS(___FILEBASENAME___Par,
 | 
			
		||||
                                    unsigned int, i);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class T___FILEBASENAME___: public Module<___FILEBASENAME___Par>
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    // constructor
 | 
			
		||||
    T___FILEBASENAME___(const std::string name);
 | 
			
		||||
    // destructor
 | 
			
		||||
    virtual ~T___FILEBASENAME___(void) = default;
 | 
			
		||||
    // dependency relation
 | 
			
		||||
    virtual std::vector<std::string> getInput(void);
 | 
			
		||||
    virtual std::vector<std::string> getOutput(void);
 | 
			
		||||
    // setup
 | 
			
		||||
    virtual void setup(void);
 | 
			
		||||
    // execution
 | 
			
		||||
    virtual void execute(void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
MODULE_REGISTER_NS(___FILEBASENAME___, T___FILEBASENAME___, ___NAMESPACE___);
 | 
			
		||||
 | 
			
		||||
END_MODULE_NAMESPACE
 | 
			
		||||
 | 
			
		||||
END_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
#endif // Hadrons____FILEBASENAME____hpp_
 | 
			
		||||
							
								
								
									
										81
									
								
								extras/Hadrons/Modules/templates/Module_tmp.hpp.template
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								extras/Hadrons/Modules/templates/Module_tmp.hpp.template
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,81 @@
 | 
			
		||||
#ifndef Hadrons____FILEBASENAME____hpp_
 | 
			
		||||
#define Hadrons____FILEBASENAME____hpp_
 | 
			
		||||
 | 
			
		||||
#include <Grid/Hadrons/Global.hpp>
 | 
			
		||||
#include <Grid/Hadrons/Module.hpp>
 | 
			
		||||
#include <Grid/Hadrons/ModuleFactory.hpp>
 | 
			
		||||
 | 
			
		||||
BEGIN_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                         ___FILEBASENAME___                                 *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
class ___FILEBASENAME___Par: Serializable
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    GRID_SERIALIZABLE_CLASS_MEMBERS(___FILEBASENAME___Par,
 | 
			
		||||
                                    unsigned int, i);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
class T___FILEBASENAME___: public Module<___FILEBASENAME___Par>
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    // constructor
 | 
			
		||||
    T___FILEBASENAME___(const std::string name);
 | 
			
		||||
    // destructor
 | 
			
		||||
    virtual ~T___FILEBASENAME___(void) = default;
 | 
			
		||||
    // dependency relation
 | 
			
		||||
    virtual std::vector<std::string> getInput(void);
 | 
			
		||||
    virtual std::vector<std::string> getOutput(void);
 | 
			
		||||
    // setup
 | 
			
		||||
    virtual void setup(void);
 | 
			
		||||
    // execution
 | 
			
		||||
    virtual void execute(void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
MODULE_REGISTER(___FILEBASENAME___, T___FILEBASENAME___<FIMPL>);
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                 T___FILEBASENAME___ implementation                             *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
// constructor /////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
T___FILEBASENAME___<FImpl>::T___FILEBASENAME___(const std::string name)
 | 
			
		||||
: Module<___FILEBASENAME___Par>(name)
 | 
			
		||||
{}
 | 
			
		||||
 | 
			
		||||
// dependencies/products ///////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
std::vector<std::string> T___FILEBASENAME___<FImpl>::getInput(void)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<std::string> in;
 | 
			
		||||
    
 | 
			
		||||
    return in;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
std::vector<std::string> T___FILEBASENAME___<FImpl>::getOutput(void)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<std::string> out = {getName()};
 | 
			
		||||
    
 | 
			
		||||
    return out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// setup ///////////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
void T___FILEBASENAME___<FImpl>::setup(void)
 | 
			
		||||
{
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// execution ///////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
void T___FILEBASENAME___<FImpl>::execute(void)
 | 
			
		||||
{
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
END_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
#endif // Hadrons____FILEBASENAME____hpp_
 | 
			
		||||
@@ -0,0 +1,85 @@
 | 
			
		||||
#ifndef Hadrons____FILEBASENAME____hpp_
 | 
			
		||||
#define Hadrons____FILEBASENAME____hpp_
 | 
			
		||||
 | 
			
		||||
#include <Grid/Hadrons/Global.hpp>
 | 
			
		||||
#include <Grid/Hadrons/Module.hpp>
 | 
			
		||||
#include <Grid/Hadrons/ModuleFactory.hpp>
 | 
			
		||||
 | 
			
		||||
BEGIN_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                         ___FILEBASENAME___                                 *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
BEGIN_MODULE_NAMESPACE(___NAMESPACE___)
 | 
			
		||||
 | 
			
		||||
class ___FILEBASENAME___Par: Serializable
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    GRID_SERIALIZABLE_CLASS_MEMBERS(___FILEBASENAME___Par,
 | 
			
		||||
                                    unsigned int, i);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
class T___FILEBASENAME___: public Module<___FILEBASENAME___Par>
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    // constructor
 | 
			
		||||
    T___FILEBASENAME___(const std::string name);
 | 
			
		||||
    // destructor
 | 
			
		||||
    virtual ~T___FILEBASENAME___(void) = default;
 | 
			
		||||
    // dependency relation
 | 
			
		||||
    virtual std::vector<std::string> getInput(void);
 | 
			
		||||
    virtual std::vector<std::string> getOutput(void);
 | 
			
		||||
    // setup
 | 
			
		||||
    virtual void setup(void);
 | 
			
		||||
    // execution
 | 
			
		||||
    virtual void execute(void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
MODULE_REGISTER_NS(___FILEBASENAME___, T___FILEBASENAME___<FIMPL>, ___NAMESPACE___);
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *                 T___FILEBASENAME___ implementation                             *
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
// constructor /////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
T___FILEBASENAME___<FImpl>::T___FILEBASENAME___(const std::string name)
 | 
			
		||||
: Module<___FILEBASENAME___Par>(name)
 | 
			
		||||
{}
 | 
			
		||||
 | 
			
		||||
// dependencies/products ///////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
std::vector<std::string> T___FILEBASENAME___<FImpl>::getInput(void)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<std::string> in;
 | 
			
		||||
    
 | 
			
		||||
    return in;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
std::vector<std::string> T___FILEBASENAME___<FImpl>::getOutput(void)
 | 
			
		||||
{
 | 
			
		||||
    std::vector<std::string> out = {getName()};
 | 
			
		||||
    
 | 
			
		||||
    return out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// setup ///////////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
void T___FILEBASENAME___<FImpl>::setup(void)
 | 
			
		||||
{
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// execution ///////////////////////////////////////////////////////////////////
 | 
			
		||||
template <typename FImpl>
 | 
			
		||||
void T___FILEBASENAME___<FImpl>::execute(void)
 | 
			
		||||
{
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
END_MODULE_NAMESPACE
 | 
			
		||||
 | 
			
		||||
END_HADRONS_NAMESPACE
 | 
			
		||||
 | 
			
		||||
#endif // Hadrons____FILEBASENAME____hpp_
 | 
			
		||||
							
								
								
									
										31
									
								
								extras/Hadrons/add_module.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										31
									
								
								extras/Hadrons/add_module.sh
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,31 @@
 | 
			
		||||
#!/usr/bin/env bash
 | 
			
		||||
 | 
			
		||||
if (( $# != 1 && $# != 2)); then
 | 
			
		||||
    echo "usage: `basename $0` <module name> [<namespace>]" 1>&2
 | 
			
		||||
    exit 1
 | 
			
		||||
fi
 | 
			
		||||
NAME=$1
 | 
			
		||||
NS=$2
 | 
			
		||||
 | 
			
		||||
if (( $# == 1 )); then
 | 
			
		||||
	if [ -e "Modules/${NAME}.cc" ] || [ -e "Modules/${NAME}.hpp" ]; then
 | 
			
		||||
	    echo "error: files Modules/${NAME}.* already exists" 1>&2
 | 
			
		||||
	    exit 1
 | 
			
		||||
	fi
 | 
			
		||||
	sed "s/___FILEBASENAME___/${NAME}/g" Modules/templates/Module.cc.template > Modules/${NAME}.cc
 | 
			
		||||
	sed "s/___FILEBASENAME___/${NAME}/g" Modules/templates/Module.hpp.template > Modules/${NAME}.hpp
 | 
			
		||||
elif (( $# == 2 )); then
 | 
			
		||||
	mkdir -p Modules/${NS}
 | 
			
		||||
	if [ -e "Modules/${NS}/${NAME}.cc" ] || [ -e "Modules/${NS}/${NAME}.hpp" ]; then
 | 
			
		||||
	    echo "error: files Modules/${NS}/${NAME}.* already exists" 1>&2
 | 
			
		||||
	    exit 1
 | 
			
		||||
	fi
 | 
			
		||||
	TMPCC=".${NS}.${NAME}.tmp.cc"
 | 
			
		||||
	TMPHPP=".${NS}.${NAME}.tmp.hpp"
 | 
			
		||||
	sed "s/___FILEBASENAME___/${NAME}/g" Modules/templates/Module_in_NS.cc.template  > ${TMPCC}
 | 
			
		||||
	sed "s/___FILEBASENAME___/${NAME}/g" Modules/templates/Module_in_NS.hpp.template > ${TMPHPP}
 | 
			
		||||
	sed "s/___NAMESPACE___/${NS}/g" ${TMPCC}  > Modules/${NS}/${NAME}.cc
 | 
			
		||||
	sed "s/___NAMESPACE___/${NS}/g" ${TMPHPP} > Modules/${NS}/${NAME}.hpp
 | 
			
		||||
	rm -f ${TMPCC} ${TMPHPP}
 | 
			
		||||
fi
 | 
			
		||||
./make_module_list.sh
 | 
			
		||||
							
								
								
									
										28
									
								
								extras/Hadrons/add_module_template.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										28
									
								
								extras/Hadrons/add_module_template.sh
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,28 @@
 | 
			
		||||
#!/usr/bin/env bash
 | 
			
		||||
 | 
			
		||||
if (( $# != 1 && $# != 2)); then
 | 
			
		||||
    echo "usage: `basename $0` <module name> [<namespace>]" 1>&2
 | 
			
		||||
    exit 1
 | 
			
		||||
fi
 | 
			
		||||
NAME=$1
 | 
			
		||||
NS=$2
 | 
			
		||||
 | 
			
		||||
if (( $# == 1 )); then
 | 
			
		||||
	if [ -e "Modules/${NAME}.cc" ] || [ -e "Modules/${NAME}.hpp" ]; then
 | 
			
		||||
	    echo "error: files Modules/${NAME}.* already exists" 1>&2
 | 
			
		||||
	    exit 1
 | 
			
		||||
	fi
 | 
			
		||||
	sed "s/___FILEBASENAME___/${NAME}/g" Modules/templates/Module_tmp.hpp.template > Modules/${NAME}.hpp
 | 
			
		||||
elif (( $# == 2 )); then
 | 
			
		||||
	mkdir -p Modules/${NS}
 | 
			
		||||
	if [ -e "Modules/${NS}/${NAME}.cc" ] || [ -e "Modules/${NS}/${NAME}.hpp" ]; then
 | 
			
		||||
	    echo "error: files Modules/${NS}/${NAME}.* already exists" 1>&2
 | 
			
		||||
	    exit 1
 | 
			
		||||
	fi
 | 
			
		||||
	TMPCC=".${NS}.${NAME}.tmp.cc"
 | 
			
		||||
	TMPHPP=".${NS}.${NAME}.tmp.hpp"
 | 
			
		||||
	sed "s/___FILEBASENAME___/${NAME}/g" Modules/templates/Module_tmp_in_NS.hpp.template > ${TMPHPP}
 | 
			
		||||
	sed "s/___NAMESPACE___/${NS}/g" ${TMPHPP} > Modules/${NS}/${NAME}.hpp
 | 
			
		||||
	rm -f ${TMPCC} ${TMPHPP}
 | 
			
		||||
fi
 | 
			
		||||
./make_module_list.sh
 | 
			
		||||
							
								
								
									
										12
									
								
								extras/Hadrons/make_module_list.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										12
									
								
								extras/Hadrons/make_module_list.sh
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
#!/usr/bin/env bash
 | 
			
		||||
 | 
			
		||||
echo 'modules_cc =\' > modules.inc
 | 
			
		||||
find Modules -name '*.cc' -type f -print | sed 's/^/  /;$q;s/$/ \\/' >> modules.inc
 | 
			
		||||
echo '' >> modules.inc
 | 
			
		||||
echo 'modules_hpp =\' >> modules.inc
 | 
			
		||||
find Modules -name '*.hpp' -type f -print | sed 's/^/  /;$q;s/$/ \\/' >> modules.inc
 | 
			
		||||
echo '' >> modules.inc
 | 
			
		||||
rm -f Modules.hpp
 | 
			
		||||
for f in `find Modules -name '*.hpp'`; do
 | 
			
		||||
	echo "#include <Grid/Hadrons/${f}>" >> Modules.hpp
 | 
			
		||||
done
 | 
			
		||||
							
								
								
									
										30
									
								
								extras/Hadrons/modules.inc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								extras/Hadrons/modules.inc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
			
		||||
modules_cc =\
 | 
			
		||||
  Modules/MContraction/WeakHamiltonianEye.cc \
 | 
			
		||||
  Modules/MContraction/WeakHamiltonianNonEye.cc \
 | 
			
		||||
  Modules/MContraction/WeakNeutral4ptDisc.cc \
 | 
			
		||||
  Modules/MGauge/Load.cc \
 | 
			
		||||
  Modules/MGauge/Random.cc \
 | 
			
		||||
  Modules/MGauge/Unit.cc
 | 
			
		||||
 | 
			
		||||
modules_hpp =\
 | 
			
		||||
  Modules/MAction/DWF.hpp \
 | 
			
		||||
  Modules/MAction/Wilson.hpp \
 | 
			
		||||
  Modules/MContraction/Baryon.hpp \
 | 
			
		||||
  Modules/MContraction/DiscLoop.hpp \
 | 
			
		||||
  Modules/MContraction/Gamma3pt.hpp \
 | 
			
		||||
  Modules/MContraction/Meson.hpp \
 | 
			
		||||
  Modules/MContraction/WeakHamiltonian.hpp \
 | 
			
		||||
  Modules/MContraction/WeakHamiltonianEye.hpp \
 | 
			
		||||
  Modules/MContraction/WeakHamiltonianNonEye.hpp \
 | 
			
		||||
  Modules/MContraction/WeakNeutral4ptDisc.hpp \
 | 
			
		||||
  Modules/MGauge/Load.hpp \
 | 
			
		||||
  Modules/MGauge/Random.hpp \
 | 
			
		||||
  Modules/MGauge/Unit.hpp \
 | 
			
		||||
  Modules/MLoop/NoiseLoop.hpp \
 | 
			
		||||
  Modules/MSolver/RBPrecCG.hpp \
 | 
			
		||||
  Modules/MSource/Point.hpp \
 | 
			
		||||
  Modules/MSource/SeqGamma.hpp \
 | 
			
		||||
  Modules/MSource/Wall.hpp \
 | 
			
		||||
  Modules/MSource/Z2.hpp \
 | 
			
		||||
  Modules/Quark.hpp
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1
									
								
								extras/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								extras/Makefile.am
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
SUBDIRS = Hadrons
 | 
			
		||||
@@ -20,4 +20,17 @@ The simple testcase in this directory is the submitted bug report that encapsula
 | 
			
		||||
problem. The test case works with icpc and with clang++, but fails consistently on g++
 | 
			
		||||
current variants.
 | 
			
		||||
 | 
			
		||||
Peter
 | 
			
		||||
Peter
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
************
 | 
			
		||||
 | 
			
		||||
Second GCC bug reported, see Issue 100.
 | 
			
		||||
 | 
			
		||||
https://wandbox.org/permlink/tzssJza6R9XnqANw
 | 
			
		||||
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80652
 | 
			
		||||
 | 
			
		||||
Getting Travis fails under gcc-5 for Test_simd, now that I added more comprehensive testing to the
 | 
			
		||||
CI test suite. The limitations of Travis runtime limits & weak cores are being shown.
 | 
			
		||||
 | 
			
		||||
Travis uses 5.4.1 for g++-5.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										86
									
								
								grid-config.in
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										86
									
								
								grid-config.in
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,86 @@
 | 
			
		||||
#! /bin/sh
 | 
			
		||||
 | 
			
		||||
prefix=@prefix@
 | 
			
		||||
exec_prefix=@exec_prefix@
 | 
			
		||||
includedir=@includedir@
 | 
			
		||||
 | 
			
		||||
usage()
 | 
			
		||||
{
 | 
			
		||||
  cat <<EOF
 | 
			
		||||
Usage: grid-config [OPTION]
 | 
			
		||||
 | 
			
		||||
Known values for OPTION are:
 | 
			
		||||
 | 
			
		||||
  --prefix     show Grid installation prefix
 | 
			
		||||
  --cxxflags   print pre-processor and compiler flags
 | 
			
		||||
  --ldflags    print library linking flags
 | 
			
		||||
  --libs       print library linking information
 | 
			
		||||
  --summary    print full build summary
 | 
			
		||||
  --help       display this help and exit
 | 
			
		||||
  --version    output version information
 | 
			
		||||
  --git        print git revision
 | 
			
		||||
 | 
			
		||||
EOF
 | 
			
		||||
  
 | 
			
		||||
  exit $1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
if test $# -eq 0; then
 | 
			
		||||
  usage 1
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
cflags=false
 | 
			
		||||
libs=false
 | 
			
		||||
 | 
			
		||||
while test $# -gt 0; do
 | 
			
		||||
  case "$1" in
 | 
			
		||||
    -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
 | 
			
		||||
    *) optarg= ;;
 | 
			
		||||
  esac
 | 
			
		||||
  
 | 
			
		||||
  case "$1" in
 | 
			
		||||
    --prefix)
 | 
			
		||||
      echo $prefix
 | 
			
		||||
    ;;
 | 
			
		||||
    
 | 
			
		||||
    --version)
 | 
			
		||||
      echo @VERSION@
 | 
			
		||||
      exit 0
 | 
			
		||||
    ;;
 | 
			
		||||
    
 | 
			
		||||
    --git)
 | 
			
		||||
      echo "@GRID_BRANCH@ @GRID_SHA@"
 | 
			
		||||
      exit 0
 | 
			
		||||
    ;;
 | 
			
		||||
    
 | 
			
		||||
    --help)
 | 
			
		||||
      usage 0
 | 
			
		||||
    ;;
 | 
			
		||||
    
 | 
			
		||||
    --cxxflags)
 | 
			
		||||
      echo @GRID_CXXFLAGS@
 | 
			
		||||
    ;;
 | 
			
		||||
    
 | 
			
		||||
    --ldflags)
 | 
			
		||||
      echo @GRID_LDFLAGS@
 | 
			
		||||
    ;;
 | 
			
		||||
    
 | 
			
		||||
    --libs)
 | 
			
		||||
      echo @GRID_LIBS@
 | 
			
		||||
    ;;
 | 
			
		||||
    
 | 
			
		||||
    --summary)
 | 
			
		||||
      echo ""
 | 
			
		||||
      echo "@GRID_SUMMARY@"
 | 
			
		||||
      echo ""
 | 
			
		||||
    ;;
 | 
			
		||||
    
 | 
			
		||||
    *)
 | 
			
		||||
      usage
 | 
			
		||||
      exit 1
 | 
			
		||||
    ;;
 | 
			
		||||
  esac
 | 
			
		||||
  shift
 | 
			
		||||
done
 | 
			
		||||
 | 
			
		||||
exit 0
 | 
			
		||||
							
								
								
									
										37
									
								
								lib/DisableWarnings.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								lib/DisableWarnings.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid
 | 
			
		||||
 | 
			
		||||
Source file: ./lib/DisableWarnings.h
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2016
 | 
			
		||||
 | 
			
		||||
Author: Guido Cossu <guido.cossu@ed.ac.uk>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution
 | 
			
		||||
directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
 | 
			
		||||
#ifndef DISABLE_WARNINGS_H
 | 
			
		||||
#define DISABLE_WARNINGS_H
 | 
			
		||||
 | 
			
		||||
 //disables and intel compiler specific warning (in json.hpp)
 | 
			
		||||
#pragma warning disable 488  
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										54
									
								
								lib/Grid.h
									
									
									
									
									
								
							
							
						
						
									
										54
									
								
								lib/Grid.h
									
									
									
									
									
								
							@@ -38,52 +38,12 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
#ifndef GRID_H
 | 
			
		||||
#define GRID_H
 | 
			
		||||
 | 
			
		||||
///////////////////
 | 
			
		||||
// Std C++ dependencies
 | 
			
		||||
///////////////////
 | 
			
		||||
#include <cassert>
 | 
			
		||||
#include <complex>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <iomanip>
 | 
			
		||||
#include <random>
 | 
			
		||||
#include <functional>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
#include <ctime>
 | 
			
		||||
#include <sys/time.h>
 | 
			
		||||
#include <chrono>
 | 
			
		||||
 | 
			
		||||
///////////////////
 | 
			
		||||
// Grid headers
 | 
			
		||||
///////////////////
 | 
			
		||||
#include <Grid/serialisation/Serialisation.h>
 | 
			
		||||
#include "Config.h"
 | 
			
		||||
#include <Grid/Timer.h>
 | 
			
		||||
#include <Grid/PerfCount.h>
 | 
			
		||||
#include <Grid/Log.h>
 | 
			
		||||
#include <Grid/AlignedAllocator.h>
 | 
			
		||||
#include <Grid/Simd.h>
 | 
			
		||||
#include <Grid/Threads.h>
 | 
			
		||||
#include <Grid/Lexicographic.h>
 | 
			
		||||
#include <Grid/Init.h>
 | 
			
		||||
#include <Grid/Communicator.h> 
 | 
			
		||||
#include <Grid/Cartesian.h>    
 | 
			
		||||
#include <Grid/Tensors.h>      
 | 
			
		||||
#include <Grid/Lattice.h>      
 | 
			
		||||
#include <Grid/Cshift.h>       
 | 
			
		||||
#include <Grid/Stencil.h>      
 | 
			
		||||
#include <Grid/Algorithms.h>   
 | 
			
		||||
#include <Grid/parallelIO/BinaryIO.h>
 | 
			
		||||
#include <Grid/FFT.h>
 | 
			
		||||
 | 
			
		||||
#include <Grid/qcd/QCD.h>
 | 
			
		||||
#include <Grid/parallelIO/NerscIO.h>
 | 
			
		||||
#include <Grid/qcd/hmc/NerscCheckpointer.h>
 | 
			
		||||
#include <Grid/qcd/hmc/HmcRunner.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include <Grid/GridCore.h>
 | 
			
		||||
#include <Grid/GridQCDcore.h>
 | 
			
		||||
#include <Grid/qcd/action/Action.h>
 | 
			
		||||
#include <Grid/qcd/utils/GaugeFix.h>
 | 
			
		||||
#include <Grid/qcd/smearing/Smearing.h>
 | 
			
		||||
#include <Grid/parallelIO/MetaData.h>
 | 
			
		||||
#include <Grid/qcd/hmc/HMC_aggregate.h>
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -2,11 +2,13 @@
 | 
			
		||||
 | 
			
		||||
    Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
    Source file: ./lib/algorithms/iterative/MatrixUtils.h
 | 
			
		||||
    Source file: ./lib/Grid.h
 | 
			
		||||
 | 
			
		||||
    Copyright (C) 2015
 | 
			
		||||
 | 
			
		||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
Author: azusayamaguchi <ayamaguc@YAMAKAZE.local>
 | 
			
		||||
Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
 | 
			
		||||
    This program is free software; you can redistribute it and/or modify
 | 
			
		||||
    it under the terms of the GNU General Public License as published by
 | 
			
		||||
@@ -25,51 +27,34 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
    See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
    *************************************************************************************/
 | 
			
		||||
    /*  END LEGAL */
 | 
			
		||||
#ifndef GRID_MATRIX_UTILS_H
 | 
			
		||||
#define GRID_MATRIX_UTILS_H
 | 
			
		||||
//
 | 
			
		||||
//  Grid.h
 | 
			
		||||
//  simd
 | 
			
		||||
//
 | 
			
		||||
//  Created by Peter Boyle on 09/05/2014.
 | 
			
		||||
//  Copyright (c) 2014 University of Edinburgh. All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
#ifndef GRID_BASE_H
 | 
			
		||||
#define GRID_BASE_H
 | 
			
		||||
 | 
			
		||||
  namespace MatrixUtils { 
 | 
			
		||||
#include <Grid/GridStd.h>
 | 
			
		||||
 | 
			
		||||
    template<class T> inline void Size(Matrix<T>& A,int &N,int &M){
 | 
			
		||||
      N=A.size(); assert(N>0);
 | 
			
		||||
      M=A[0].size();
 | 
			
		||||
      for(int i=0;i<N;i++){
 | 
			
		||||
	assert(A[i].size()==M);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
#include <Grid/perfmon/Timer.h>
 | 
			
		||||
#include <Grid/perfmon/PerfCount.h>
 | 
			
		||||
#include <Grid/log/Log.h>
 | 
			
		||||
#include <Grid/allocator/AlignedAllocator.h>
 | 
			
		||||
#include <Grid/simd/Simd.h>
 | 
			
		||||
#include <Grid/serialisation/Serialisation.h>
 | 
			
		||||
#include <Grid/threads/Threads.h>
 | 
			
		||||
#include <Grid/util/Util.h>
 | 
			
		||||
#include <Grid/communicator/Communicator.h> 
 | 
			
		||||
#include <Grid/cartesian/Cartesian.h>    
 | 
			
		||||
#include <Grid/tensors/Tensors.h>      
 | 
			
		||||
#include <Grid/lattice/Lattice.h>      
 | 
			
		||||
#include <Grid/cshift/Cshift.h>       
 | 
			
		||||
#include <Grid/stencil/Stencil.h>      
 | 
			
		||||
#include <Grid/parallelIO/BinaryIO.h>
 | 
			
		||||
#include <Grid/algorithms/Algorithms.h>   
 | 
			
		||||
 | 
			
		||||
    template<class T> inline void SizeSquare(Matrix<T>& A,int &N)
 | 
			
		||||
    {
 | 
			
		||||
      int M;
 | 
			
		||||
      Size(A,N,M);
 | 
			
		||||
      assert(N==M);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class T> inline void Fill(Matrix<T>& A,T & val)
 | 
			
		||||
    { 
 | 
			
		||||
      int N,M;
 | 
			
		||||
      Size(A,N,M);
 | 
			
		||||
      for(int i=0;i<N;i++){
 | 
			
		||||
      for(int j=0;j<M;j++){
 | 
			
		||||
	A[i][j]=val;
 | 
			
		||||
      }}
 | 
			
		||||
    }
 | 
			
		||||
    template<class T> inline void Diagonal(Matrix<T>& A,T & val)
 | 
			
		||||
    { 
 | 
			
		||||
      int N;
 | 
			
		||||
      SizeSquare(A,N);
 | 
			
		||||
      for(int i=0;i<N;i++){
 | 
			
		||||
	A[i][i]=val;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    template<class T> inline void Identity(Matrix<T>& A)
 | 
			
		||||
    {
 | 
			
		||||
      Fill(A,0.0);
 | 
			
		||||
      Diagonal(A,1.0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
@@ -2,12 +2,12 @@
 | 
			
		||||
 | 
			
		||||
    Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
    Source file: ./lib/qcd/hmc/HMC.cc
 | 
			
		||||
    Source file: ./lib/Grid.h
 | 
			
		||||
 | 
			
		||||
    Copyright (C) 2015
 | 
			
		||||
 | 
			
		||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
Author: neo <cossu@post.kek.jp>
 | 
			
		||||
Author: azusayamaguchi <ayamaguc@YAMAKAZE.local>
 | 
			
		||||
Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
 | 
			
		||||
    This program is free software; you can redistribute it and/or modify
 | 
			
		||||
@@ -27,10 +27,16 @@ Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
    See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
    *************************************************************************************/
 | 
			
		||||
    /*  END LEGAL */
 | 
			
		||||
#include <Grid.h>
 | 
			
		||||
#ifndef GRID_QCD_CORE_H
 | 
			
		||||
#define GRID_QCD_CORE_H
 | 
			
		||||
 | 
			
		||||
namespace Grid{
 | 
			
		||||
  namespace QCD{
 | 
			
		||||
/////////////////////////
 | 
			
		||||
// Core Grid QCD headers
 | 
			
		||||
/////////////////////////
 | 
			
		||||
#include <Grid/GridCore.h>
 | 
			
		||||
#include <Grid/qcd/QCD.h>
 | 
			
		||||
#include <Grid/qcd/spin/Spin.h>
 | 
			
		||||
#include <Grid/qcd/utils/Utils.h>
 | 
			
		||||
#include <Grid/qcd/representations/Representations.h>
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										29
									
								
								lib/GridStd.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								lib/GridStd.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
			
		||||
#ifndef GRID_STD_H
 | 
			
		||||
#define GRID_STD_H
 | 
			
		||||
 | 
			
		||||
///////////////////
 | 
			
		||||
// Std C++ dependencies
 | 
			
		||||
///////////////////
 | 
			
		||||
#include <cassert>
 | 
			
		||||
#include <complex>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <iomanip>
 | 
			
		||||
#include <random>
 | 
			
		||||
#include <functional>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
#include <ctime>
 | 
			
		||||
#include <sys/time.h>
 | 
			
		||||
#include <chrono>
 | 
			
		||||
#include <zlib.h>
 | 
			
		||||
 | 
			
		||||
///////////////////
 | 
			
		||||
// Grid config
 | 
			
		||||
///////////////////
 | 
			
		||||
#include "Config.h"
 | 
			
		||||
 | 
			
		||||
#endif /* GRID_STD_H */
 | 
			
		||||
							
								
								
									
										9
									
								
								lib/Grid_Eigen_Dense.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								lib/Grid_Eigen_Dense.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#if defined __GNUC__
 | 
			
		||||
#pragma GCC diagnostic push
 | 
			
		||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
 | 
			
		||||
#endif
 | 
			
		||||
#include <Grid/Eigen/Dense>
 | 
			
		||||
#if defined __GNUC__
 | 
			
		||||
#pragma GCC diagnostic pop
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										1
									
								
								lib/Hadrons
									
									
									
									
									
										Symbolic link
									
								
							
							
						
						
									
										1
									
								
								lib/Hadrons
									
									
									
									
									
										Symbolic link
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
../extras/Hadrons
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
extra_sources=
 | 
			
		||||
extra_headers=
 | 
			
		||||
if BUILD_COMMS_MPI
 | 
			
		||||
  extra_sources+=communicator/Communicator_mpi.cc
 | 
			
		||||
  extra_sources+=communicator/Communicator_base.cc
 | 
			
		||||
@@ -24,6 +25,12 @@ if BUILD_COMMS_NONE
 | 
			
		||||
  extra_sources+=communicator/Communicator_base.cc
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
if BUILD_HDF5
 | 
			
		||||
  extra_sources+=serialisation/Hdf5IO.cc 
 | 
			
		||||
  extra_headers+=serialisation/Hdf5IO.h
 | 
			
		||||
  extra_headers+=serialisation/Hdf5Type.h
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Libraries
 | 
			
		||||
#
 | 
			
		||||
@@ -32,6 +39,9 @@ include Eigen.inc
 | 
			
		||||
 | 
			
		||||
lib_LIBRARIES = libGrid.a
 | 
			
		||||
 | 
			
		||||
libGrid_a_SOURCES              = $(CCFILES) $(extra_sources)
 | 
			
		||||
CCFILES += $(extra_sources)
 | 
			
		||||
HFILES  += $(extra_headers)
 | 
			
		||||
 | 
			
		||||
libGrid_a_SOURCES              = $(CCFILES)
 | 
			
		||||
libGrid_adir                   = $(pkgincludedir)
 | 
			
		||||
nobase_dist_pkginclude_HEADERS = $(HFILES) $(eigen_files) Config.h
 | 
			
		||||
 
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							@@ -1,154 +0,0 @@
 | 
			
		||||
    /*************************************************************************************
 | 
			
		||||
 | 
			
		||||
    Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
    Source file: ./lib/Old/Tensor_peek.h
 | 
			
		||||
 | 
			
		||||
    Copyright (C) 2015
 | 
			
		||||
 | 
			
		||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
 | 
			
		||||
    This program is free software; you can redistribute it and/or modify
 | 
			
		||||
    it under the terms of the GNU General Public License as published by
 | 
			
		||||
    the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
    (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
    This program is distributed in the hope that it will be useful,
 | 
			
		||||
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
    GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
    You should have received a copy of the GNU General Public License along
 | 
			
		||||
    with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
    See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
    *************************************************************************************/
 | 
			
		||||
    /*  END LEGAL */
 | 
			
		||||
#ifndef GRID_MATH_PEEK_H
 | 
			
		||||
#define GRID_MATH_PEEK_H
 | 
			
		||||
namespace Grid {
 | 
			
		||||
 | 
			
		||||
//////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// Peek on a specific index; returns a scalar in that index, tensor inherits rest
 | 
			
		||||
//////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// If we hit the right index, return scalar with no further recursion
 | 
			
		||||
 | 
			
		||||
//template<int Level> inline ComplexF peekIndex(const ComplexF arg) { return arg;}
 | 
			
		||||
//template<int Level> inline ComplexD peekIndex(const ComplexD arg) { return arg;}
 | 
			
		||||
//template<int Level> inline RealF peekIndex(const RealF arg) { return arg;}
 | 
			
		||||
//template<int Level> inline RealD peekIndex(const RealD arg) { return arg;}
 | 
			
		||||
#if 0
 | 
			
		||||
// Scalar peek, no indices
 | 
			
		||||
template<int Level,class vtype,typename std::enable_if< iScalar<vtype>::TensorLevel == Level >::type * =nullptr> inline 
 | 
			
		||||
  auto peekIndex(const iScalar<vtype> &arg) ->  iScalar<vtype> 
 | 
			
		||||
{
 | 
			
		||||
  return arg;
 | 
			
		||||
}
 | 
			
		||||
// Vector peek, one index
 | 
			
		||||
template<int Level,class vtype,int N,typename std::enable_if< iScalar<vtype>::TensorLevel == Level >::type * =nullptr> inline 
 | 
			
		||||
  auto peekIndex(const iVector<vtype,N> &arg,int i) -> iScalar<vtype> // Index matches
 | 
			
		||||
{
 | 
			
		||||
  iScalar<vtype> ret;                              // return scalar
 | 
			
		||||
  ret._internal = arg._internal[i];
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
// Matrix peek, two indices
 | 
			
		||||
template<int Level,class vtype,int N,typename std::enable_if< iScalar<vtype>::TensorLevel == Level >::type * =nullptr> inline 
 | 
			
		||||
  auto peekIndex(const iMatrix<vtype,N> &arg,int i,int j) ->  iScalar<vtype>
 | 
			
		||||
{
 | 
			
		||||
  iScalar<vtype> ret;                              // return scalar
 | 
			
		||||
  ret._internal = arg._internal[i][j];
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/////////////
 | 
			
		||||
// No match peek for scalar,vector,matrix must forward on either 0,1,2 args. Must have 9 routines with notvalue
 | 
			
		||||
/////////////
 | 
			
		||||
// scalar
 | 
			
		||||
template<int Level,class vtype,typename std::enable_if< iScalar<vtype>::TensorLevel != Level >::type * =nullptr> inline 
 | 
			
		||||
  auto peekIndex(const iScalar<vtype> &arg) -> iScalar<decltype(peekIndex<Level>(arg._internal))>
 | 
			
		||||
{
 | 
			
		||||
  iScalar<decltype(peekIndex<Level>(arg._internal))> ret;
 | 
			
		||||
  ret._internal= peekIndex<Level>(arg._internal);
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
template<int Level,class vtype, typename std::enable_if< iScalar<vtype>::TensorLevel != Level >::type * =nullptr> inline 
 | 
			
		||||
  auto peekIndex(const iScalar<vtype> &arg,int i) ->  iScalar<decltype(peekIndex<Level>(arg._internal,i))> 
 | 
			
		||||
{
 | 
			
		||||
  iScalar<decltype(peekIndex<Level>(arg._internal,i))> ret;
 | 
			
		||||
  ret._internal=peekIndex<Level>(arg._internal,i);
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
template<int Level,class vtype, typename std::enable_if< iScalar<vtype>::TensorLevel != Level >::type * =nullptr> inline 
 | 
			
		||||
  auto peekIndex(const iScalar<vtype> &arg,int i,int j) ->  iScalar<decltype(peekIndex<Level>(arg._internal,i,j))>
 | 
			
		||||
{
 | 
			
		||||
  iScalar<decltype(peekIndex<Level>(arg._internal,i,j))> ret;
 | 
			
		||||
  ret._internal=peekIndex<Level>(arg._internal,i,j);
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
// vector
 | 
			
		||||
template<int Level,class vtype,int N, typename std::enable_if< iScalar<vtype>::TensorLevel != Level >::type * =nullptr> inline 
 | 
			
		||||
auto peekIndex(const iVector<vtype,N> &arg) ->   iVector<decltype(peekIndex<Level>(arg._internal[0])),N>
 | 
			
		||||
{
 | 
			
		||||
  iVector<decltype(peekIndex<Level>(arg._internal[0])),N> ret;
 | 
			
		||||
  for(int ii=0;ii<N;ii++){
 | 
			
		||||
    ret._internal[ii]=peekIndex<Level>(arg._internal[ii]);
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
template<int Level,class vtype,int N, typename std::enable_if< iScalar<vtype>::TensorLevel != Level >::type * =nullptr> inline 
 | 
			
		||||
  auto peekIndex(const iVector<vtype,N> &arg,int i) ->  iVector<decltype(peekIndex<Level>(arg._internal[0],i)),N>
 | 
			
		||||
{
 | 
			
		||||
  iVector<decltype(peekIndex<Level>(arg._internal[0],i)),N> ret;
 | 
			
		||||
  for(int ii=0;ii<N;ii++){
 | 
			
		||||
    ret._internal[ii]=peekIndex<Level>(arg._internal[ii],i);
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
template<int Level,class vtype,int N, typename std::enable_if< iScalar<vtype>::TensorLevel != Level >::type * =nullptr> inline 
 | 
			
		||||
  auto peekIndex(const iVector<vtype,N> &arg,int i,int j) ->  iVector<decltype(peekIndex<Level>(arg._internal[0],i,j)),N> 
 | 
			
		||||
{
 | 
			
		||||
  iVector<decltype(peekIndex<Level>(arg._internal[0],i,j)),N> ret;
 | 
			
		||||
  for(int ii=0;ii<N;ii++){
 | 
			
		||||
    ret._internal[ii]=peekIndex<Level>(arg._internal[ii],i,j);
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// matrix
 | 
			
		||||
template<int Level,class vtype,int N, typename std::enable_if< iScalar<vtype>::TensorLevel != Level >::type * =nullptr> inline 
 | 
			
		||||
auto peekIndex(const iMatrix<vtype,N> &arg) ->   iMatrix<decltype(peekIndex<Level>(arg._internal[0][0])),N> 
 | 
			
		||||
{
 | 
			
		||||
  iMatrix<decltype(peekIndex<Level>(arg._internal[0][0])),N> ret;
 | 
			
		||||
  for(int ii=0;ii<N;ii++){
 | 
			
		||||
  for(int jj=0;jj<N;jj++){
 | 
			
		||||
    ret._internal[ii][jj]=peekIndex<Level>(arg._internal[ii][jj]);// Could avoid this because peeking a scalar is dumb
 | 
			
		||||
  }}
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
template<int Level,class vtype,int N, typename std::enable_if< iScalar<vtype>::TensorLevel != Level >::type * =nullptr> inline 
 | 
			
		||||
  auto peekIndex(const iMatrix<vtype,N> &arg,int i) ->   iMatrix<decltype(peekIndex<Level>(arg._internal[0][0],i)),N>
 | 
			
		||||
{
 | 
			
		||||
  iMatrix<decltype(peekIndex<Level>(arg._internal[0][0],i)),N> ret;
 | 
			
		||||
  for(int ii=0;ii<N;ii++){
 | 
			
		||||
  for(int jj=0;jj<N;jj++){
 | 
			
		||||
    ret._internal[ii][jj]=peekIndex<Level>(arg._internal[ii][jj],i);
 | 
			
		||||
  }}
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
template<int Level,class vtype,int N, typename std::enable_if< iScalar<vtype>::TensorLevel != Level >::type * =nullptr> inline 
 | 
			
		||||
  auto peekIndex(const iMatrix<vtype,N> &arg,int i,int j) ->   iMatrix<decltype(peekIndex<Level>(arg._internal[0][0],i,j)),N>
 | 
			
		||||
{
 | 
			
		||||
  iMatrix<decltype(peekIndex<Level>(arg._internal[0][0],i,j)),N> ret;
 | 
			
		||||
  for(int ii=0;ii<N;ii++){
 | 
			
		||||
  for(int jj=0;jj<N;jj++){
 | 
			
		||||
    ret._internal[ii][jj]=peekIndex<Level>(arg._internal[ii][jj],i,j);
 | 
			
		||||
  }}
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,127 +0,0 @@
 | 
			
		||||
    /*************************************************************************************
 | 
			
		||||
 | 
			
		||||
    Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
    Source file: ./lib/Old/Tensor_poke.h
 | 
			
		||||
 | 
			
		||||
    Copyright (C) 2015
 | 
			
		||||
 | 
			
		||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
 | 
			
		||||
    This program is free software; you can redistribute it and/or modify
 | 
			
		||||
    it under the terms of the GNU General Public License as published by
 | 
			
		||||
    the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
    (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
    This program is distributed in the hope that it will be useful,
 | 
			
		||||
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
    GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
    You should have received a copy of the GNU General Public License along
 | 
			
		||||
    with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
    See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
    *************************************************************************************/
 | 
			
		||||
    /*  END LEGAL */
 | 
			
		||||
#ifndef GRID_MATH_POKE_H
 | 
			
		||||
#define GRID_MATH_POKE_H
 | 
			
		||||
namespace Grid {
 | 
			
		||||
 | 
			
		||||
//////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// Poke a specific index; 
 | 
			
		||||
//////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
#if 0
 | 
			
		||||
// Scalar poke
 | 
			
		||||
template<int Level,class vtype,typename std::enable_if< iScalar<vtype>::TensorLevel == Level >::type * =nullptr> inline 
 | 
			
		||||
  void pokeIndex(iScalar<vtype> &ret, const iScalar<vtype> &arg)
 | 
			
		||||
{
 | 
			
		||||
  ret._internal = arg._internal;
 | 
			
		||||
}
 | 
			
		||||
// Vector poke, one index
 | 
			
		||||
template<int Level,class vtype,int N,typename std::enable_if< iScalar<vtype>::TensorLevel == Level >::type * =nullptr> inline 
 | 
			
		||||
  void pokeIndex(iVector<vtype,N> &ret, const iScalar<vtype> &arg,int i)
 | 
			
		||||
{
 | 
			
		||||
  ret._internal[i] = arg._internal;
 | 
			
		||||
}
 | 
			
		||||
//Matrix poke, two indices
 | 
			
		||||
template<int Level,class vtype,int N,typename std::enable_if< iScalar<vtype>::TensorLevel == Level >::type * =nullptr> inline 
 | 
			
		||||
  void pokeIndex(iMatrix<vtype,N> &ret, const iScalar<vtype> &arg,int i,int j)
 | 
			
		||||
{
 | 
			
		||||
  ret._internal[i][j] = arg._internal;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/////////////
 | 
			
		||||
// No match poke for scalar,vector,matrix must forward on either 0,1,2 args. Must have 9 routines with notvalue
 | 
			
		||||
/////////////
 | 
			
		||||
// scalar
 | 
			
		||||
template<int Level,class vtype,typename std::enable_if< iScalar<vtype>::TensorLevel != Level >::type * =nullptr> inline 
 | 
			
		||||
void pokeIndex(iScalar<vtype> &ret, const iScalar<decltype(peekIndex<Level>(ret._internal))>  &arg)
 | 
			
		||||
{
 | 
			
		||||
  pokeIndex<Level>(ret._internal,arg._internal);
 | 
			
		||||
}
 | 
			
		||||
template<int Level,class vtype,typename std::enable_if< iScalar<vtype>::TensorLevel != Level >::type * =nullptr> inline 
 | 
			
		||||
  void pokeIndex(iScalar<vtype> &ret, const iScalar<decltype(peekIndex<Level>(ret._internal,0))> &arg, int i)
 | 
			
		||||
		 
 | 
			
		||||
{
 | 
			
		||||
  pokeIndex<Level>(ret._internal,arg._internal,i);
 | 
			
		||||
}
 | 
			
		||||
template<int Level,class vtype,typename std::enable_if< iScalar<vtype>::TensorLevel != Level >::type * =nullptr> inline 
 | 
			
		||||
  void pokeIndex(iScalar<vtype> &ret, const iScalar<decltype(peekIndex<Level>(ret._internal,0,0))> &arg,int i,int j)
 | 
			
		||||
{
 | 
			
		||||
  pokeIndex<Level>(ret._internal,arg._internal,i,j);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Vector
 | 
			
		||||
template<int Level,class vtype,int N,typename std::enable_if< iScalar<vtype>::TensorLevel != Level >::type * =nullptr> inline 
 | 
			
		||||
  void pokeIndex(iVector<vtype,N> &ret, iVector<decltype(peekIndex<Level>(ret._internal)),N>  &arg)
 | 
			
		||||
{
 | 
			
		||||
  for(int ii=0;ii<N;ii++){
 | 
			
		||||
    pokeIndex<Level>(ret._internal[ii],arg._internal[ii]);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
template<int Level,class vtype,int N,typename std::enable_if< iScalar<vtype>::TensorLevel != Level >::type * =nullptr> inline 
 | 
			
		||||
  void pokeIndex(iVector<vtype,N> &ret, const iVector<decltype(peekIndex<Level>(ret._internal,0)),N> &arg,int i)
 | 
			
		||||
{
 | 
			
		||||
  for(int ii=0;ii<N;ii++){
 | 
			
		||||
    pokeIndex<Level>(ret._internal[ii],arg._internal[ii],i);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
template<int Level,class vtype,int N,typename std::enable_if< iScalar<vtype>::TensorLevel != Level >::type * =nullptr> inline 
 | 
			
		||||
  void pokeIndex(iVector<vtype,N> &ret, const iVector<decltype(peekIndex<Level>(ret._internal,0,0)),N> &arg,int i,int j)
 | 
			
		||||
{
 | 
			
		||||
  for(int ii=0;ii<N;ii++){
 | 
			
		||||
    pokeIndex<Level>(ret._internal[ii],arg._internal[ii],i,j);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Matrix
 | 
			
		||||
template<int Level,class vtype,int N,typename std::enable_if< iScalar<vtype>::TensorLevel != Level >::type * =nullptr> inline 
 | 
			
		||||
  void pokeIndex(iMatrix<vtype,N> &ret, const iMatrix<decltype(peekIndex<Level>(ret._internal)),N> &arg)		 
 | 
			
		||||
{
 | 
			
		||||
  for(int ii=0;ii<N;ii++){
 | 
			
		||||
  for(int jj=0;jj<N;jj++){
 | 
			
		||||
    pokeIndex<Level>(ret._internal[ii][jj],arg._internal[ii][jj]);
 | 
			
		||||
  }}
 | 
			
		||||
}
 | 
			
		||||
template<int Level,class vtype,int N,typename std::enable_if< iScalar<vtype>::TensorLevel != Level >::type * =nullptr> inline 
 | 
			
		||||
  void pokeIndex(iMatrix<vtype,N> &ret, const iMatrix<decltype(peekIndex<Level>(ret._internal,0)),N> &arg,int i)
 | 
			
		||||
{
 | 
			
		||||
  for(int ii=0;ii<N;ii++){
 | 
			
		||||
  for(int jj=0;jj<N;jj++){
 | 
			
		||||
    pokeIndex<Level>(ret._internal[ii][jj],arg._internal[ii][jj],i);
 | 
			
		||||
  }}
 | 
			
		||||
}
 | 
			
		||||
template<int Level,class vtype,int N,typename std::enable_if< iScalar<vtype>::TensorLevel != Level >::type * =nullptr> inline 
 | 
			
		||||
  void pokeIndex(iMatrix<vtype,N> &ret, const iMatrix<decltype(peekIndex<Level>(ret._internal,0,0)),N> &arg, int i,int j)
 | 
			
		||||
{
 | 
			
		||||
  for(int ii=0;ii<N;ii++){
 | 
			
		||||
  for(int jj=0;jj<N;jj++){
 | 
			
		||||
    pokeIndex<Level>(ret._internal[ii][jj],arg._internal[ii][jj],i,j);
 | 
			
		||||
  }}
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
@@ -42,15 +42,14 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
#include <Grid/algorithms/iterative/ConjugateResidual.h>
 | 
			
		||||
#include <Grid/algorithms/iterative/NormalEquations.h>
 | 
			
		||||
#include <Grid/algorithms/iterative/SchurRedBlack.h>
 | 
			
		||||
 | 
			
		||||
#include <Grid/algorithms/iterative/ConjugateGradientMultiShift.h>
 | 
			
		||||
#include <Grid/algorithms/iterative/ConjugateGradientMixedPrec.h>
 | 
			
		||||
 | 
			
		||||
// Lanczos support
 | 
			
		||||
#include <Grid/algorithms/iterative/MatrixUtils.h>
 | 
			
		||||
//#include <Grid/algorithms/iterative/MatrixUtils.h>
 | 
			
		||||
#include <Grid/algorithms/iterative/ImplicitlyRestartedLanczos.h>
 | 
			
		||||
 | 
			
		||||
#include <Grid/algorithms/CoarsenedMatrix.h>
 | 
			
		||||
#include <Grid/algorithms/FFT.h>
 | 
			
		||||
 | 
			
		||||
// Eigen/lanczos
 | 
			
		||||
// EigCg
 | 
			
		||||
@@ -267,8 +267,7 @@ namespace Grid {
 | 
			
		||||
      SimpleCompressor<siteVector> compressor;
 | 
			
		||||
      Stencil.HaloExchange(in,compressor);
 | 
			
		||||
 | 
			
		||||
PARALLEL_FOR_LOOP
 | 
			
		||||
      for(int ss=0;ss<Grid()->oSites();ss++){
 | 
			
		||||
      parallel_for(int ss=0;ss<Grid()->oSites();ss++){
 | 
			
		||||
        siteVector res = zero;
 | 
			
		||||
	siteVector nbr;
 | 
			
		||||
	int ptype;
 | 
			
		||||
@@ -380,8 +379,7 @@ PARALLEL_FOR_LOOP
 | 
			
		||||
	  Subspace.ProjectToSubspace(oProj,oblock);
 | 
			
		||||
	  //	  blockProject(iProj,iblock,Subspace.subspace);
 | 
			
		||||
	  //	  blockProject(oProj,oblock,Subspace.subspace);
 | 
			
		||||
PARALLEL_FOR_LOOP
 | 
			
		||||
	  for(int ss=0;ss<Grid()->oSites();ss++){
 | 
			
		||||
	  parallel_for(int ss=0;ss<Grid()->oSites();ss++){
 | 
			
		||||
	    for(int j=0;j<nbasis;j++){
 | 
			
		||||
	      if( disp!= 0 ) {
 | 
			
		||||
		A[p]._odata[ss](j,i) = oProj._odata[ss](j);
 | 
			
		||||
@@ -427,7 +425,7 @@ PARALLEL_FOR_LOOP
 | 
			
		||||
	A[p]=zero;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      GridParallelRNG  RNG(Grid()); RNG.SeedRandomDevice();
 | 
			
		||||
      GridParallelRNG  RNG(Grid()); RNG.SeedFixedIntegers(std::vector<int>({55,72,19,17,34}));
 | 
			
		||||
      Lattice<iScalar<CComplex> > val(Grid()); random(RNG,val);
 | 
			
		||||
 | 
			
		||||
      Complex one(1.0);
 | 
			
		||||
 
 | 
			
		||||
@@ -235,7 +235,7 @@ namespace Grid {
 | 
			
		||||
	Field tmp(in._grid);
 | 
			
		||||
 | 
			
		||||
	_Mat.MeooeDag(in,tmp);
 | 
			
		||||
	_Mat.MooeeInvDag(tmp,out);
 | 
			
		||||
        _Mat.MooeeInvDag(tmp,out);
 | 
			
		||||
	_Mat.MeooeDag(out,tmp);
 | 
			
		||||
 | 
			
		||||
	_Mat.MooeeDag(in,out);
 | 
			
		||||
 
 | 
			
		||||
@@ -197,8 +197,9 @@ namespace Grid {
 | 
			
		||||
    void operator() (LinearOperatorBase<Field> &Linop, const Field &in, Field &out) {
 | 
			
		||||
 | 
			
		||||
      GridBase *grid=in._grid;
 | 
			
		||||
//std::cout << "Chevyshef(): in._grid="<<in._grid<<std::endl;
 | 
			
		||||
//<<" Linop.Grid()="<<Linop.Grid()<<"Linop.RedBlackGrid()="<<Linop.RedBlackGrid()<<std::endl;
 | 
			
		||||
 | 
			
		||||
      // std::cout << "Chevyshef(): in._grid="<<in._grid<<std::endl;
 | 
			
		||||
      //std::cout <<" Linop.Grid()="<<Linop.Grid()<<"Linop.RedBlackGrid()="<<Linop.RedBlackGrid()<<std::endl;
 | 
			
		||||
 | 
			
		||||
      int vol=grid->gSites();
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -25,7 +25,7 @@ Author: Azusa Yamaguchi <ayamaguc@staffmail.ed.ac.uk>
 | 
			
		||||
    See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
    *************************************************************************************/
 | 
			
		||||
    /*  END LEGAL */
 | 
			
		||||
#include <Grid.h>
 | 
			
		||||
#include <Grid/GridCore.h>
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
double MultiShiftFunction::approx(double x)
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,7 @@
 | 
			
		||||
#include<iomanip>
 | 
			
		||||
#include<cassert>
 | 
			
		||||
 | 
			
		||||
#include<algorithms/approx/Remez.h>
 | 
			
		||||
#include<Grid/algorithms/approx/Remez.h>
 | 
			
		||||
 | 
			
		||||
// Constructor
 | 
			
		||||
AlgRemez::AlgRemez(double lower, double upper, long precision) 
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,7 @@
 | 
			
		||||
#define INCLUDED_ALG_REMEZ_H
 | 
			
		||||
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <Config.h>
 | 
			
		||||
#include <Grid/GridStd.h>
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_LIBGMP
 | 
			
		||||
#include "bigfloat.h"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										593
									
								
								lib/algorithms/iterative/BlockConjugateGradient.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										593
									
								
								lib/algorithms/iterative/BlockConjugateGradient.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,593 @@
 | 
			
		||||
/*************************************************************************************
 | 
			
		||||
 | 
			
		||||
Grid physics library, www.github.com/paboyle/Grid
 | 
			
		||||
 | 
			
		||||
Source file: ./lib/algorithms/iterative/BlockConjugateGradient.h
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2017
 | 
			
		||||
 | 
			
		||||
Author: Azusa Yamaguchi <ayamaguc@staffmail.ed.ac.uk>
 | 
			
		||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
 | 
			
		||||
This program is free software; you can redistribute it and/or modify
 | 
			
		||||
it under the terms of the GNU General Public License as published by
 | 
			
		||||
the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
(at your option) any later version.
 | 
			
		||||
 | 
			
		||||
This program is distributed in the hope that it will be useful,
 | 
			
		||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
You should have received a copy of the GNU General Public License along
 | 
			
		||||
with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
See the full license in the file "LICENSE" in the top level distribution
 | 
			
		||||
directory
 | 
			
		||||
*************************************************************************************/
 | 
			
		||||
/*  END LEGAL */
 | 
			
		||||
#ifndef GRID_BLOCK_CONJUGATE_GRADIENT_H
 | 
			
		||||
#define GRID_BLOCK_CONJUGATE_GRADIENT_H
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
 | 
			
		||||
enum BlockCGtype { BlockCG, BlockCGrQ, CGmultiRHS };
 | 
			
		||||
 | 
			
		||||
//////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// Block conjugate gradient. Dimension zero should be the block direction
 | 
			
		||||
//////////////////////////////////////////////////////////////////////////
 | 
			
		||||
template <class Field>
 | 
			
		||||
class BlockConjugateGradient : public OperatorFunction<Field> {
 | 
			
		||||
 public:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  typedef typename Field::scalar_type scomplex;
 | 
			
		||||
 | 
			
		||||
  int blockDim ;
 | 
			
		||||
  int Nblock;
 | 
			
		||||
 | 
			
		||||
  BlockCGtype CGtype;
 | 
			
		||||
  bool ErrorOnNoConverge;  // throw an assert when the CG fails to converge.
 | 
			
		||||
                           // Defaults true.
 | 
			
		||||
  RealD Tolerance;
 | 
			
		||||
  Integer MaxIterations;
 | 
			
		||||
  Integer IterationsToComplete; //Number of iterations the CG took to finish. Filled in upon completion
 | 
			
		||||
  
 | 
			
		||||
  BlockConjugateGradient(BlockCGtype cgtype,int _Orthog,RealD tol, Integer maxit, bool err_on_no_conv = true)
 | 
			
		||||
    : Tolerance(tol), CGtype(cgtype),   blockDim(_Orthog),  MaxIterations(maxit), ErrorOnNoConverge(err_on_no_conv)
 | 
			
		||||
  {};
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// Thin QR factorisation (google it)
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
void ThinQRfact (Eigen::MatrixXcd &m_rr,
 | 
			
		||||
		 Eigen::MatrixXcd &C,
 | 
			
		||||
		 Eigen::MatrixXcd &Cinv,
 | 
			
		||||
		 Field & Q,
 | 
			
		||||
		 const Field & R)
 | 
			
		||||
{
 | 
			
		||||
  int Orthog = blockDim; // First dimension is block dim; this is an assumption
 | 
			
		||||
  ////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
  //Dimensions
 | 
			
		||||
  // R_{ferm x Nblock} =  Q_{ferm x Nblock} x  C_{Nblock x Nblock} -> ferm x Nblock
 | 
			
		||||
  //
 | 
			
		||||
  // Rdag R = m_rr = Herm = L L^dag        <-- Cholesky decomposition (LLT routine in Eigen)
 | 
			
		||||
  //
 | 
			
		||||
  //   Q  C = R => Q = R C^{-1}
 | 
			
		||||
  //
 | 
			
		||||
  // Want  Ident = Q^dag Q = C^{-dag} R^dag R C^{-1} = C^{-dag} L L^dag C^{-1} = 1_{Nblock x Nblock} 
 | 
			
		||||
  //
 | 
			
		||||
  // Set C = L^{dag}, and then Q^dag Q = ident 
 | 
			
		||||
  //
 | 
			
		||||
  // Checks:
 | 
			
		||||
  // Cdag C = Rdag R ; passes.
 | 
			
		||||
  // QdagQ  = 1      ; passes
 | 
			
		||||
  ////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
  sliceInnerProductMatrix(m_rr,R,R,Orthog);
 | 
			
		||||
 | 
			
		||||
  ////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
  // Cholesky from Eigen
 | 
			
		||||
  // There exists a ldlt that is documented as more stable
 | 
			
		||||
  ////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
  Eigen::MatrixXcd L    = m_rr.llt().matrixL(); 
 | 
			
		||||
 | 
			
		||||
  C    = L.adjoint();
 | 
			
		||||
  Cinv = C.inverse();
 | 
			
		||||
 | 
			
		||||
  ////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
  // Q = R C^{-1}
 | 
			
		||||
  //
 | 
			
		||||
  // Q_j  = R_i Cinv(i,j) 
 | 
			
		||||
  //
 | 
			
		||||
  // NB maddMatrix conventions are Right multiplication X[j] a[j,i] already
 | 
			
		||||
  ////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
  // FIXME:: make a sliceMulMatrix to avoid zero vector
 | 
			
		||||
  sliceMulMatrix(Q,Cinv,R,Orthog);
 | 
			
		||||
}
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// Call one of several implementations
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
void operator()(LinearOperatorBase<Field> &Linop, const Field &Src, Field &Psi) 
 | 
			
		||||
{
 | 
			
		||||
  if ( CGtype == BlockCGrQ ) {
 | 
			
		||||
    BlockCGrQsolve(Linop,Src,Psi);
 | 
			
		||||
  } else if (CGtype == BlockCG ) {
 | 
			
		||||
    BlockCGsolve(Linop,Src,Psi);
 | 
			
		||||
  } else if (CGtype == CGmultiRHS ) {
 | 
			
		||||
    CGmultiRHSsolve(Linop,Src,Psi);
 | 
			
		||||
  } else {
 | 
			
		||||
    assert(0);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// BlockCGrQ implementation:
 | 
			
		||||
//--------------------------
 | 
			
		||||
// X is guess/Solution
 | 
			
		||||
// B is RHS
 | 
			
		||||
// Solve A X_i = B_i    ;        i refers to Nblock index
 | 
			
		||||
////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
void BlockCGrQsolve(LinearOperatorBase<Field> &Linop, const Field &B, Field &X) 
 | 
			
		||||
{
 | 
			
		||||
  int Orthog = blockDim; // First dimension is block dim; this is an assumption
 | 
			
		||||
  Nblock = B._grid->_fdimensions[Orthog];
 | 
			
		||||
 | 
			
		||||
  std::cout<<GridLogMessage<<" Block Conjugate Gradient : Orthog "<<Orthog<<" Nblock "<<Nblock<<std::endl;
 | 
			
		||||
 | 
			
		||||
  X.checkerboard = B.checkerboard;
 | 
			
		||||
  conformable(X, B);
 | 
			
		||||
 | 
			
		||||
  Field tmp(B);
 | 
			
		||||
  Field Q(B);
 | 
			
		||||
  Field D(B);
 | 
			
		||||
  Field Z(B);
 | 
			
		||||
  Field AD(B);
 | 
			
		||||
 | 
			
		||||
  Eigen::MatrixXcd m_DZ     = Eigen::MatrixXcd::Identity(Nblock,Nblock);
 | 
			
		||||
  Eigen::MatrixXcd m_M      = Eigen::MatrixXcd::Identity(Nblock,Nblock);
 | 
			
		||||
  Eigen::MatrixXcd m_rr     = Eigen::MatrixXcd::Zero(Nblock,Nblock);
 | 
			
		||||
 | 
			
		||||
  Eigen::MatrixXcd m_C      = Eigen::MatrixXcd::Zero(Nblock,Nblock);
 | 
			
		||||
  Eigen::MatrixXcd m_Cinv   = Eigen::MatrixXcd::Zero(Nblock,Nblock);
 | 
			
		||||
  Eigen::MatrixXcd m_S      = Eigen::MatrixXcd::Zero(Nblock,Nblock);
 | 
			
		||||
  Eigen::MatrixXcd m_Sinv   = Eigen::MatrixXcd::Zero(Nblock,Nblock);
 | 
			
		||||
 | 
			
		||||
  Eigen::MatrixXcd m_tmp    = Eigen::MatrixXcd::Identity(Nblock,Nblock);
 | 
			
		||||
  Eigen::MatrixXcd m_tmp1   = Eigen::MatrixXcd::Identity(Nblock,Nblock);
 | 
			
		||||
 | 
			
		||||
  // Initial residual computation & set up
 | 
			
		||||
  std::vector<RealD> residuals(Nblock);
 | 
			
		||||
  std::vector<RealD> ssq(Nblock);
 | 
			
		||||
 | 
			
		||||
  sliceNorm(ssq,B,Orthog);
 | 
			
		||||
  RealD sssum=0;
 | 
			
		||||
  for(int b=0;b<Nblock;b++) sssum+=ssq[b];
 | 
			
		||||
 | 
			
		||||
  sliceNorm(residuals,B,Orthog);
 | 
			
		||||
  for(int b=0;b<Nblock;b++){ assert(std::isnan(residuals[b])==0); }
 | 
			
		||||
 | 
			
		||||
  sliceNorm(residuals,X,Orthog);
 | 
			
		||||
  for(int b=0;b<Nblock;b++){ assert(std::isnan(residuals[b])==0); }
 | 
			
		||||
 | 
			
		||||
  /************************************************************************
 | 
			
		||||
   * Block conjugate gradient rQ (Sebastien Birk Thesis, after Dubrulle 2001)
 | 
			
		||||
   ************************************************************************
 | 
			
		||||
   * Dimensions:
 | 
			
		||||
   *
 | 
			
		||||
   *   X,B==(Nferm x Nblock)
 | 
			
		||||
   *   A==(Nferm x Nferm)
 | 
			
		||||
   *  
 | 
			
		||||
   * Nferm = Nspin x Ncolour x Ncomplex x Nlattice_site
 | 
			
		||||
   * 
 | 
			
		||||
   * QC = R = B-AX, D = Q     ; QC => Thin QR factorisation (google it)
 | 
			
		||||
   * for k: 
 | 
			
		||||
   *   Z  = AD
 | 
			
		||||
   *   M  = [D^dag Z]^{-1}
 | 
			
		||||
   *   X  = X + D MC
 | 
			
		||||
   *   QS = Q - ZM
 | 
			
		||||
   *   D  = Q + D S^dag
 | 
			
		||||
   *   C  = S C
 | 
			
		||||
   */
 | 
			
		||||
  ///////////////////////////////////////
 | 
			
		||||
  // Initial block: initial search dir is guess
 | 
			
		||||
  ///////////////////////////////////////
 | 
			
		||||
  std::cout << GridLogMessage<<"BlockCGrQ algorithm initialisation " <<std::endl;
 | 
			
		||||
 | 
			
		||||
  //1.  QC = R = B-AX, D = Q     ; QC => Thin QR factorisation (google it)
 | 
			
		||||
 | 
			
		||||
  Linop.HermOp(X, AD);
 | 
			
		||||
  tmp = B - AD;  
 | 
			
		||||
  ThinQRfact (m_rr, m_C, m_Cinv, Q, tmp);
 | 
			
		||||
  D=Q;
 | 
			
		||||
 | 
			
		||||
  std::cout << GridLogMessage<<"BlockCGrQ computed initial residual and QR fact " <<std::endl;
 | 
			
		||||
 | 
			
		||||
  ///////////////////////////////////////
 | 
			
		||||
  // Timers
 | 
			
		||||
  ///////////////////////////////////////
 | 
			
		||||
  GridStopWatch sliceInnerTimer;
 | 
			
		||||
  GridStopWatch sliceMaddTimer;
 | 
			
		||||
  GridStopWatch QRTimer;
 | 
			
		||||
  GridStopWatch MatrixTimer;
 | 
			
		||||
  GridStopWatch SolverTimer;
 | 
			
		||||
  SolverTimer.Start();
 | 
			
		||||
 | 
			
		||||
  int k;
 | 
			
		||||
  for (k = 1; k <= MaxIterations; k++) {
 | 
			
		||||
 | 
			
		||||
    //3. Z  = AD
 | 
			
		||||
    MatrixTimer.Start();
 | 
			
		||||
    Linop.HermOp(D, Z);      
 | 
			
		||||
    MatrixTimer.Stop();
 | 
			
		||||
 | 
			
		||||
    //4. M  = [D^dag Z]^{-1}
 | 
			
		||||
    sliceInnerTimer.Start();
 | 
			
		||||
    sliceInnerProductMatrix(m_DZ,D,Z,Orthog);
 | 
			
		||||
    sliceInnerTimer.Stop();
 | 
			
		||||
    m_M       = m_DZ.inverse();
 | 
			
		||||
 | 
			
		||||
    //5. X  = X + D MC
 | 
			
		||||
    m_tmp     = m_M * m_C;
 | 
			
		||||
    sliceMaddTimer.Start();
 | 
			
		||||
    sliceMaddMatrix(X,m_tmp, D,X,Orthog);     
 | 
			
		||||
    sliceMaddTimer.Stop();
 | 
			
		||||
 | 
			
		||||
    //6. QS = Q - ZM
 | 
			
		||||
    sliceMaddTimer.Start();
 | 
			
		||||
    sliceMaddMatrix(tmp,m_M,Z,Q,Orthog,-1.0);
 | 
			
		||||
    sliceMaddTimer.Stop();
 | 
			
		||||
    QRTimer.Start();
 | 
			
		||||
    ThinQRfact (m_rr, m_S, m_Sinv, Q, tmp);
 | 
			
		||||
    QRTimer.Stop();
 | 
			
		||||
    
 | 
			
		||||
    //7. D  = Q + D S^dag
 | 
			
		||||
    m_tmp = m_S.adjoint();
 | 
			
		||||
    sliceMaddTimer.Start();
 | 
			
		||||
    sliceMaddMatrix(D,m_tmp,D,Q,Orthog);
 | 
			
		||||
    sliceMaddTimer.Stop();
 | 
			
		||||
 | 
			
		||||
    //8. C  = S C
 | 
			
		||||
    m_C = m_S*m_C;
 | 
			
		||||
    
 | 
			
		||||
    /*********************
 | 
			
		||||
     * convergence monitor
 | 
			
		||||
     *********************
 | 
			
		||||
     */
 | 
			
		||||
    m_rr = m_C.adjoint() * m_C;
 | 
			
		||||
 | 
			
		||||
    RealD max_resid=0;
 | 
			
		||||
    RealD rrsum=0;
 | 
			
		||||
    RealD rr;
 | 
			
		||||
 | 
			
		||||
    for(int b=0;b<Nblock;b++) {
 | 
			
		||||
      rrsum+=real(m_rr(b,b));
 | 
			
		||||
      rr = real(m_rr(b,b))/ssq[b];
 | 
			
		||||
      if ( rr > max_resid ) max_resid = rr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::cout << GridLogIterative << "\titeration "<<k<<" rr_sum "<<rrsum<<" ssq_sum "<< sssum
 | 
			
		||||
	      <<" ave "<<std::sqrt(rrsum/sssum) << " max "<< max_resid <<std::endl;
 | 
			
		||||
 | 
			
		||||
    if ( max_resid < Tolerance*Tolerance ) { 
 | 
			
		||||
 | 
			
		||||
      SolverTimer.Stop();
 | 
			
		||||
 | 
			
		||||
      std::cout << GridLogMessage<<"BlockCGrQ converged in "<<k<<" iterations"<<std::endl;
 | 
			
		||||
 | 
			
		||||
      for(int b=0;b<Nblock;b++){
 | 
			
		||||
	std::cout << GridLogMessage<< "\t\tblock "<<b<<" computed resid "
 | 
			
		||||
		  << std::sqrt(real(m_rr(b,b))/ssq[b])<<std::endl;
 | 
			
		||||
      }
 | 
			
		||||
      std::cout << GridLogMessage<<"\tMax residual is "<<std::sqrt(max_resid)<<std::endl;
 | 
			
		||||
 | 
			
		||||
      Linop.HermOp(X, AD);
 | 
			
		||||
      AD = AD-B;
 | 
			
		||||
      std::cout << GridLogMessage <<"\t True residual is " << std::sqrt(norm2(AD)/norm2(B)) <<std::endl;
 | 
			
		||||
 | 
			
		||||
      std::cout << GridLogMessage << "Time Breakdown "<<std::endl;
 | 
			
		||||
      std::cout << GridLogMessage << "\tElapsed    " << SolverTimer.Elapsed()     <<std::endl;
 | 
			
		||||
      std::cout << GridLogMessage << "\tMatrix     " << MatrixTimer.Elapsed()     <<std::endl;
 | 
			
		||||
      std::cout << GridLogMessage << "\tInnerProd  " << sliceInnerTimer.Elapsed() <<std::endl;
 | 
			
		||||
      std::cout << GridLogMessage << "\tMaddMatrix " << sliceMaddTimer.Elapsed()  <<std::endl;
 | 
			
		||||
      std::cout << GridLogMessage << "\tThinQRfact " << QRTimer.Elapsed()  <<std::endl;
 | 
			
		||||
	    
 | 
			
		||||
      IterationsToComplete = k;
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
  std::cout << GridLogMessage << "BlockConjugateGradient(rQ) did NOT converge" << std::endl;
 | 
			
		||||
 | 
			
		||||
  if (ErrorOnNoConverge) assert(0);
 | 
			
		||||
  IterationsToComplete = k;
 | 
			
		||||
}
 | 
			
		||||
//////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// Block conjugate gradient; Original O'Leary Dimension zero should be the block direction
 | 
			
		||||
//////////////////////////////////////////////////////////////////////////
 | 
			
		||||
void BlockCGsolve(LinearOperatorBase<Field> &Linop, const Field &Src, Field &Psi) 
 | 
			
		||||
{
 | 
			
		||||
  int Orthog = blockDim; // First dimension is block dim; this is an assumption
 | 
			
		||||
  Nblock = Src._grid->_fdimensions[Orthog];
 | 
			
		||||
 | 
			
		||||
  std::cout<<GridLogMessage<<" Block Conjugate Gradient : Orthog "<<Orthog<<" Nblock "<<Nblock<<std::endl;
 | 
			
		||||
 | 
			
		||||
  Psi.checkerboard = Src.checkerboard;
 | 
			
		||||
  conformable(Psi, Src);
 | 
			
		||||
 | 
			
		||||
  Field P(Src);
 | 
			
		||||
  Field AP(Src);
 | 
			
		||||
  Field R(Src);
 | 
			
		||||
  
 | 
			
		||||
  Eigen::MatrixXcd m_pAp    = Eigen::MatrixXcd::Identity(Nblock,Nblock);
 | 
			
		||||
  Eigen::MatrixXcd m_pAp_inv= Eigen::MatrixXcd::Identity(Nblock,Nblock);
 | 
			
		||||
  Eigen::MatrixXcd m_rr     = Eigen::MatrixXcd::Zero(Nblock,Nblock);
 | 
			
		||||
  Eigen::MatrixXcd m_rr_inv = Eigen::MatrixXcd::Zero(Nblock,Nblock);
 | 
			
		||||
 | 
			
		||||
  Eigen::MatrixXcd m_alpha      = Eigen::MatrixXcd::Zero(Nblock,Nblock);
 | 
			
		||||
  Eigen::MatrixXcd m_beta   = Eigen::MatrixXcd::Zero(Nblock,Nblock);
 | 
			
		||||
 | 
			
		||||
  // Initial residual computation & set up
 | 
			
		||||
  std::vector<RealD> residuals(Nblock);
 | 
			
		||||
  std::vector<RealD> ssq(Nblock);
 | 
			
		||||
 | 
			
		||||
  sliceNorm(ssq,Src,Orthog);
 | 
			
		||||
  RealD sssum=0;
 | 
			
		||||
  for(int b=0;b<Nblock;b++) sssum+=ssq[b];
 | 
			
		||||
 | 
			
		||||
  sliceNorm(residuals,Src,Orthog);
 | 
			
		||||
  for(int b=0;b<Nblock;b++){ assert(std::isnan(residuals[b])==0); }
 | 
			
		||||
 | 
			
		||||
  sliceNorm(residuals,Psi,Orthog);
 | 
			
		||||
  for(int b=0;b<Nblock;b++){ assert(std::isnan(residuals[b])==0); }
 | 
			
		||||
 | 
			
		||||
  // Initial search dir is guess
 | 
			
		||||
  Linop.HermOp(Psi, AP);
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  /************************************************************************
 | 
			
		||||
   * Block conjugate gradient (Stephen Pickles, thesis 1995, pp 71, O Leary 1980)
 | 
			
		||||
   ************************************************************************
 | 
			
		||||
   * O'Leary : R = B - A X
 | 
			
		||||
   * O'Leary : P = M R ; preconditioner M = 1
 | 
			
		||||
   * O'Leary : alpha = PAP^{-1} RMR
 | 
			
		||||
   * O'Leary : beta  = RMR^{-1}_old RMR_new
 | 
			
		||||
   * O'Leary : X=X+Palpha
 | 
			
		||||
   * O'Leary : R_new=R_old-AP alpha
 | 
			
		||||
   * O'Leary : P=MR_new+P beta
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  R = Src - AP;  
 | 
			
		||||
  P = R;
 | 
			
		||||
  sliceInnerProductMatrix(m_rr,R,R,Orthog);
 | 
			
		||||
 | 
			
		||||
  GridStopWatch sliceInnerTimer;
 | 
			
		||||
  GridStopWatch sliceMaddTimer;
 | 
			
		||||
  GridStopWatch MatrixTimer;
 | 
			
		||||
  GridStopWatch SolverTimer;
 | 
			
		||||
  SolverTimer.Start();
 | 
			
		||||
 | 
			
		||||
  int k;
 | 
			
		||||
  for (k = 1; k <= MaxIterations; k++) {
 | 
			
		||||
 | 
			
		||||
    RealD rrsum=0;
 | 
			
		||||
    for(int b=0;b<Nblock;b++) rrsum+=real(m_rr(b,b));
 | 
			
		||||
 | 
			
		||||
    std::cout << GridLogIterative << "\titeration "<<k<<" rr_sum "<<rrsum<<" ssq_sum "<< sssum
 | 
			
		||||
	      <<" / "<<std::sqrt(rrsum/sssum) <<std::endl;
 | 
			
		||||
 | 
			
		||||
    MatrixTimer.Start();
 | 
			
		||||
    Linop.HermOp(P, AP);
 | 
			
		||||
    MatrixTimer.Stop();
 | 
			
		||||
 | 
			
		||||
    // Alpha
 | 
			
		||||
    sliceInnerTimer.Start();
 | 
			
		||||
    sliceInnerProductMatrix(m_pAp,P,AP,Orthog);
 | 
			
		||||
    sliceInnerTimer.Stop();
 | 
			
		||||
    m_pAp_inv = m_pAp.inverse();
 | 
			
		||||
    m_alpha   = m_pAp_inv * m_rr ;
 | 
			
		||||
 | 
			
		||||
    // Psi, R update
 | 
			
		||||
    sliceMaddTimer.Start();
 | 
			
		||||
    sliceMaddMatrix(Psi,m_alpha, P,Psi,Orthog);     // add alpha *  P to psi
 | 
			
		||||
    sliceMaddMatrix(R  ,m_alpha,AP,  R,Orthog,-1.0);// sub alpha * AP to resid
 | 
			
		||||
    sliceMaddTimer.Stop();
 | 
			
		||||
 | 
			
		||||
    // Beta
 | 
			
		||||
    m_rr_inv = m_rr.inverse();
 | 
			
		||||
    sliceInnerTimer.Start();
 | 
			
		||||
    sliceInnerProductMatrix(m_rr,R,R,Orthog);
 | 
			
		||||
    sliceInnerTimer.Stop();
 | 
			
		||||
    m_beta = m_rr_inv *m_rr;
 | 
			
		||||
 | 
			
		||||
    // Search update
 | 
			
		||||
    sliceMaddTimer.Start();
 | 
			
		||||
    sliceMaddMatrix(AP,m_beta,P,R,Orthog);
 | 
			
		||||
    sliceMaddTimer.Stop();
 | 
			
		||||
    P= AP;
 | 
			
		||||
 | 
			
		||||
    /*********************
 | 
			
		||||
     * convergence monitor
 | 
			
		||||
     *********************
 | 
			
		||||
     */
 | 
			
		||||
    RealD max_resid=0;
 | 
			
		||||
    RealD rr;
 | 
			
		||||
    for(int b=0;b<Nblock;b++){
 | 
			
		||||
      rr = real(m_rr(b,b))/ssq[b];
 | 
			
		||||
      if ( rr > max_resid ) max_resid = rr;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    if ( max_resid < Tolerance*Tolerance ) { 
 | 
			
		||||
 | 
			
		||||
      SolverTimer.Stop();
 | 
			
		||||
 | 
			
		||||
      std::cout << GridLogMessage<<"BlockCG converged in "<<k<<" iterations"<<std::endl;
 | 
			
		||||
      for(int b=0;b<Nblock;b++){
 | 
			
		||||
	std::cout << GridLogMessage<< "\t\tblock "<<b<<" computed resid "
 | 
			
		||||
		  << std::sqrt(real(m_rr(b,b))/ssq[b])<<std::endl;
 | 
			
		||||
      }
 | 
			
		||||
      std::cout << GridLogMessage<<"\tMax residual is "<<std::sqrt(max_resid)<<std::endl;
 | 
			
		||||
 | 
			
		||||
      Linop.HermOp(Psi, AP);
 | 
			
		||||
      AP = AP-Src;
 | 
			
		||||
      std::cout << GridLogMessage <<"\t True residual is " << std::sqrt(norm2(AP)/norm2(Src)) <<std::endl;
 | 
			
		||||
 | 
			
		||||
      std::cout << GridLogMessage << "Time Breakdown "<<std::endl;
 | 
			
		||||
      std::cout << GridLogMessage << "\tElapsed    " << SolverTimer.Elapsed()     <<std::endl;
 | 
			
		||||
      std::cout << GridLogMessage << "\tMatrix     " << MatrixTimer.Elapsed()     <<std::endl;
 | 
			
		||||
      std::cout << GridLogMessage << "\tInnerProd  " << sliceInnerTimer.Elapsed() <<std::endl;
 | 
			
		||||
      std::cout << GridLogMessage << "\tMaddMatrix " << sliceMaddTimer.Elapsed()  <<std::endl;
 | 
			
		||||
	    
 | 
			
		||||
      IterationsToComplete = k;
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
  std::cout << GridLogMessage << "BlockConjugateGradient did NOT converge" << std::endl;
 | 
			
		||||
 | 
			
		||||
  if (ErrorOnNoConverge) assert(0);
 | 
			
		||||
  IterationsToComplete = k;
 | 
			
		||||
}
 | 
			
		||||
//////////////////////////////////////////////////////////////////////////
 | 
			
		||||
// multiRHS conjugate gradient. Dimension zero should be the block direction
 | 
			
		||||
// Use this for spread out across nodes
 | 
			
		||||
//////////////////////////////////////////////////////////////////////////
 | 
			
		||||
void CGmultiRHSsolve(LinearOperatorBase<Field> &Linop, const Field &Src, Field &Psi) 
 | 
			
		||||
{
 | 
			
		||||
  int Orthog = blockDim; // First dimension is block dim
 | 
			
		||||
  Nblock = Src._grid->_fdimensions[Orthog];
 | 
			
		||||
 | 
			
		||||
  std::cout<<GridLogMessage<<"MultiRHS Conjugate Gradient : Orthog "<<Orthog<<" Nblock "<<Nblock<<std::endl;
 | 
			
		||||
 | 
			
		||||
  Psi.checkerboard = Src.checkerboard;
 | 
			
		||||
  conformable(Psi, Src);
 | 
			
		||||
 | 
			
		||||
  Field P(Src);
 | 
			
		||||
  Field AP(Src);
 | 
			
		||||
  Field R(Src);
 | 
			
		||||
  
 | 
			
		||||
  std::vector<ComplexD> v_pAp(Nblock);
 | 
			
		||||
  std::vector<RealD> v_rr (Nblock);
 | 
			
		||||
  std::vector<RealD> v_rr_inv(Nblock);
 | 
			
		||||
  std::vector<RealD> v_alpha(Nblock);
 | 
			
		||||
  std::vector<RealD> v_beta(Nblock);
 | 
			
		||||
 | 
			
		||||
  // Initial residual computation & set up
 | 
			
		||||
  std::vector<RealD> residuals(Nblock);
 | 
			
		||||
  std::vector<RealD> ssq(Nblock);
 | 
			
		||||
 | 
			
		||||
  sliceNorm(ssq,Src,Orthog);
 | 
			
		||||
  RealD sssum=0;
 | 
			
		||||
  for(int b=0;b<Nblock;b++) sssum+=ssq[b];
 | 
			
		||||
 | 
			
		||||
  sliceNorm(residuals,Src,Orthog);
 | 
			
		||||
  for(int b=0;b<Nblock;b++){ assert(std::isnan(residuals[b])==0); }
 | 
			
		||||
 | 
			
		||||
  sliceNorm(residuals,Psi,Orthog);
 | 
			
		||||
  for(int b=0;b<Nblock;b++){ assert(std::isnan(residuals[b])==0); }
 | 
			
		||||
 | 
			
		||||
  // Initial search dir is guess
 | 
			
		||||
  Linop.HermOp(Psi, AP);
 | 
			
		||||
 | 
			
		||||
  R = Src - AP;  
 | 
			
		||||
  P = R;
 | 
			
		||||
  sliceNorm(v_rr,R,Orthog);
 | 
			
		||||
 | 
			
		||||
  GridStopWatch sliceInnerTimer;
 | 
			
		||||
  GridStopWatch sliceMaddTimer;
 | 
			
		||||
  GridStopWatch sliceNormTimer;
 | 
			
		||||
  GridStopWatch MatrixTimer;
 | 
			
		||||
  GridStopWatch SolverTimer;
 | 
			
		||||
 | 
			
		||||
  SolverTimer.Start();
 | 
			
		||||
  int k;
 | 
			
		||||
  for (k = 1; k <= MaxIterations; k++) {
 | 
			
		||||
 | 
			
		||||
    RealD rrsum=0;
 | 
			
		||||
    for(int b=0;b<Nblock;b++) rrsum+=real(v_rr[b]);
 | 
			
		||||
 | 
			
		||||
    std::cout << GridLogIterative << "\titeration "<<k<<" rr_sum "<<rrsum<<" ssq_sum "<< sssum
 | 
			
		||||
	      <<" / "<<std::sqrt(rrsum/sssum) <<std::endl;
 | 
			
		||||
 | 
			
		||||
    MatrixTimer.Start();
 | 
			
		||||
    Linop.HermOp(P, AP);
 | 
			
		||||
    MatrixTimer.Stop();
 | 
			
		||||
 | 
			
		||||
    // Alpha
 | 
			
		||||
    sliceInnerTimer.Start();
 | 
			
		||||
    sliceInnerProductVector(v_pAp,P,AP,Orthog);
 | 
			
		||||
    sliceInnerTimer.Stop();
 | 
			
		||||
    for(int b=0;b<Nblock;b++){
 | 
			
		||||
      v_alpha[b] = v_rr[b]/real(v_pAp[b]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Psi, R update
 | 
			
		||||
    sliceMaddTimer.Start();
 | 
			
		||||
    sliceMaddVector(Psi,v_alpha, P,Psi,Orthog);     // add alpha *  P to psi
 | 
			
		||||
    sliceMaddVector(R  ,v_alpha,AP,  R,Orthog,-1.0);// sub alpha * AP to resid
 | 
			
		||||
    sliceMaddTimer.Stop();
 | 
			
		||||
 | 
			
		||||
    // Beta
 | 
			
		||||
    for(int b=0;b<Nblock;b++){
 | 
			
		||||
      v_rr_inv[b] = 1.0/v_rr[b];
 | 
			
		||||
    }
 | 
			
		||||
    sliceNormTimer.Start();
 | 
			
		||||
    sliceNorm(v_rr,R,Orthog);
 | 
			
		||||
    sliceNormTimer.Stop();
 | 
			
		||||
    for(int b=0;b<Nblock;b++){
 | 
			
		||||
      v_beta[b] = v_rr_inv[b] *v_rr[b];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Search update
 | 
			
		||||
    sliceMaddTimer.Start();
 | 
			
		||||
    sliceMaddVector(P,v_beta,P,R,Orthog);
 | 
			
		||||
    sliceMaddTimer.Stop();
 | 
			
		||||
 | 
			
		||||
    /*********************
 | 
			
		||||
     * convergence monitor
 | 
			
		||||
     *********************
 | 
			
		||||
     */
 | 
			
		||||
    RealD max_resid=0;
 | 
			
		||||
    for(int b=0;b<Nblock;b++){
 | 
			
		||||
      RealD rr = v_rr[b]/ssq[b];
 | 
			
		||||
      if ( rr > max_resid ) max_resid = rr;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    if ( max_resid < Tolerance*Tolerance ) { 
 | 
			
		||||
 | 
			
		||||
      SolverTimer.Stop();
 | 
			
		||||
 | 
			
		||||
      std::cout << GridLogMessage<<"MultiRHS solver converged in " <<k<<" iterations"<<std::endl;
 | 
			
		||||
      for(int b=0;b<Nblock;b++){
 | 
			
		||||
	std::cout << GridLogMessage<< "\t\tBlock "<<b<<" computed resid "<< std::sqrt(v_rr[b]/ssq[b])<<std::endl;
 | 
			
		||||
      }
 | 
			
		||||
      std::cout << GridLogMessage<<"\tMax residual is "<<std::sqrt(max_resid)<<std::endl;
 | 
			
		||||
 | 
			
		||||
      Linop.HermOp(Psi, AP);
 | 
			
		||||
      AP = AP-Src;
 | 
			
		||||
      std::cout <<GridLogMessage << "\tTrue residual is " << std::sqrt(norm2(AP)/norm2(Src)) <<std::endl;
 | 
			
		||||
 | 
			
		||||
      std::cout << GridLogMessage << "Time Breakdown "<<std::endl;
 | 
			
		||||
      std::cout << GridLogMessage << "\tElapsed    " << SolverTimer.Elapsed()     <<std::endl;
 | 
			
		||||
      std::cout << GridLogMessage << "\tMatrix     " << MatrixTimer.Elapsed()     <<std::endl;
 | 
			
		||||
      std::cout << GridLogMessage << "\tInnerProd  " << sliceInnerTimer.Elapsed() <<std::endl;
 | 
			
		||||
      std::cout << GridLogMessage << "\tNorm       " << sliceNormTimer.Elapsed() <<std::endl;
 | 
			
		||||
      std::cout << GridLogMessage << "\tMaddMatrix " << sliceMaddTimer.Elapsed()  <<std::endl;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      IterationsToComplete = k;
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
  std::cout << GridLogMessage << "MultiRHSConjugateGradient did NOT converge" << std::endl;
 | 
			
		||||
 | 
			
		||||
  if (ErrorOnNoConverge) assert(0);
 | 
			
		||||
  IterationsToComplete = k;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
@@ -45,6 +45,8 @@ class ConjugateGradient : public OperatorFunction<Field> {
 | 
			
		||||
                           // Defaults true.
 | 
			
		||||
  RealD Tolerance;
 | 
			
		||||
  Integer MaxIterations;
 | 
			
		||||
  Integer IterationsToComplete; //Number of iterations the CG took to finish. Filled in upon completion
 | 
			
		||||
  
 | 
			
		||||
  ConjugateGradient(RealD tol, Integer maxit, bool err_on_no_conv = true)
 | 
			
		||||
      : Tolerance(tol),
 | 
			
		||||
        MaxIterations(maxit),
 | 
			
		||||
@@ -76,18 +78,12 @@ class ConjugateGradient : public OperatorFunction<Field> {
 | 
			
		||||
    cp = a;
 | 
			
		||||
    ssq = norm2(src);
 | 
			
		||||
 | 
			
		||||
    std::cout << GridLogIterative << std::setprecision(4)
 | 
			
		||||
              << "ConjugateGradient: guess " << guess << std::endl;
 | 
			
		||||
    std::cout << GridLogIterative << std::setprecision(4)
 | 
			
		||||
              << "ConjugateGradient:   src " << ssq << std::endl;
 | 
			
		||||
    std::cout << GridLogIterative << std::setprecision(4)
 | 
			
		||||
              << "ConjugateGradient:    mp " << d << std::endl;
 | 
			
		||||
    std::cout << GridLogIterative << std::setprecision(4)
 | 
			
		||||
              << "ConjugateGradient:   mmp " << b << std::endl;
 | 
			
		||||
    std::cout << GridLogIterative << std::setprecision(4)
 | 
			
		||||
              << "ConjugateGradient:  cp,r " << cp << std::endl;
 | 
			
		||||
    std::cout << GridLogIterative << std::setprecision(4)
 | 
			
		||||
              << "ConjugateGradient:     p " << a << std::endl;
 | 
			
		||||
    std::cout << GridLogIterative << std::setprecision(4) << "ConjugateGradient: guess " << guess << std::endl;
 | 
			
		||||
    std::cout << GridLogIterative << std::setprecision(4) << "ConjugateGradient:   src " << ssq << std::endl;
 | 
			
		||||
    std::cout << GridLogIterative << std::setprecision(4) << "ConjugateGradient:    mp " << d << std::endl;
 | 
			
		||||
    std::cout << GridLogIterative << std::setprecision(4) << "ConjugateGradient:   mmp " << b << std::endl;
 | 
			
		||||
    std::cout << GridLogIterative << std::setprecision(4) << "ConjugateGradient:  cp,r " << cp << std::endl;
 | 
			
		||||
    std::cout << GridLogIterative << std::setprecision(4) << "ConjugateGradient:     p " << a << std::endl;
 | 
			
		||||
 | 
			
		||||
    RealD rsq = Tolerance * Tolerance * ssq;
 | 
			
		||||
 | 
			
		||||
@@ -97,8 +93,7 @@ class ConjugateGradient : public OperatorFunction<Field> {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::cout << GridLogIterative << std::setprecision(4)
 | 
			
		||||
              << "ConjugateGradient: k=0 residual " << cp << " target " << rsq
 | 
			
		||||
              << std::endl;
 | 
			
		||||
              << "ConjugateGradient: k=0 residual " << cp << " target " << rsq << std::endl;
 | 
			
		||||
 | 
			
		||||
    GridStopWatch LinalgTimer;
 | 
			
		||||
    GridStopWatch MatrixTimer;
 | 
			
		||||
@@ -128,8 +123,11 @@ class ConjugateGradient : public OperatorFunction<Field> {
 | 
			
		||||
      p = p * b + r;
 | 
			
		||||
 | 
			
		||||
      LinalgTimer.Stop();
 | 
			
		||||
 | 
			
		||||
      std::cout << GridLogIterative << "ConjugateGradient: Iteration " << k
 | 
			
		||||
                << " residual " << cp << " target " << rsq << std::endl;
 | 
			
		||||
      std::cout << GridLogDebug << "a = "<< a << " b_pred = "<< b_pred << "  b = "<< b << std::endl;
 | 
			
		||||
      std::cout << GridLogDebug << "qq = "<< qq << " d = "<< d << "  c = "<< c << std::endl;
 | 
			
		||||
 | 
			
		||||
      // Stopping condition
 | 
			
		||||
      if (cp <= rsq) {
 | 
			
		||||
@@ -137,31 +135,33 @@ class ConjugateGradient : public OperatorFunction<Field> {
 | 
			
		||||
        Linop.HermOpAndNorm(psi, mmp, d, qq);
 | 
			
		||||
        p = mmp - src;
 | 
			
		||||
 | 
			
		||||
        RealD mmpnorm = sqrt(norm2(mmp));
 | 
			
		||||
        RealD psinorm = sqrt(norm2(psi));
 | 
			
		||||
        RealD srcnorm = sqrt(norm2(src));
 | 
			
		||||
        RealD resnorm = sqrt(norm2(p));
 | 
			
		||||
        RealD true_residual = resnorm / srcnorm;
 | 
			
		||||
 | 
			
		||||
        std::cout << GridLogMessage
 | 
			
		||||
                  << "ConjugateGradient: Converged on iteration " << k << std::endl;
 | 
			
		||||
        std::cout << GridLogMessage << "Computed residual " << sqrt(cp / ssq)
 | 
			
		||||
                  << " true residual " << true_residual << " target "
 | 
			
		||||
                  << Tolerance << std::endl;
 | 
			
		||||
        std::cout << GridLogMessage << "Time elapsed: Iterations "
 | 
			
		||||
                  << SolverTimer.Elapsed() << " Matrix  "
 | 
			
		||||
                  << MatrixTimer.Elapsed() << " Linalg "
 | 
			
		||||
                  << LinalgTimer.Elapsed();
 | 
			
		||||
        std::cout << std::endl;
 | 
			
		||||
        std::cout << GridLogMessage << "ConjugateGradient Converged on iteration " << k << std::endl;
 | 
			
		||||
        std::cout << GridLogMessage << "\tComputed residual " << sqrt(cp / ssq)<<std::endl;
 | 
			
		||||
	std::cout << GridLogMessage << "\tTrue residual " << true_residual<<std::endl;
 | 
			
		||||
	std::cout << GridLogMessage << "\tTarget " << Tolerance << std::endl;
 | 
			
		||||
 | 
			
		||||
        std::cout << GridLogMessage << "Time breakdown "<<std::endl;
 | 
			
		||||
	std::cout << GridLogMessage << "\tElapsed    " << SolverTimer.Elapsed() <<std::endl;
 | 
			
		||||
	std::cout << GridLogMessage << "\tMatrix     " << MatrixTimer.Elapsed() <<std::endl;
 | 
			
		||||
	std::cout << GridLogMessage << "\tLinalg     " << LinalgTimer.Elapsed() <<std::endl;
 | 
			
		||||
 | 
			
		||||
        if (ErrorOnNoConverge) assert(true_residual / Tolerance < 10000.0);
 | 
			
		||||
 | 
			
		||||
	IterationsToComplete = k;	
 | 
			
		||||
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    std::cout << GridLogMessage << "ConjugateGradient did NOT converge"
 | 
			
		||||
              << std::endl;
 | 
			
		||||
 | 
			
		||||
    if (ErrorOnNoConverge) assert(0);
 | 
			
		||||
    IterationsToComplete = k;
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -35,6 +35,7 @@ namespace Grid {
 | 
			
		||||
  class MixedPrecisionConjugateGradient : public LinearFunction<FieldD> {
 | 
			
		||||
  public:                                                
 | 
			
		||||
    RealD   Tolerance;
 | 
			
		||||
    RealD   InnerTolerance; //Initial tolerance for inner CG. Defaults to Tolerance but can be changed
 | 
			
		||||
    Integer MaxInnerIterations;
 | 
			
		||||
    Integer MaxOuterIterations;
 | 
			
		||||
    GridBase* SinglePrecGrid; //Grid for single-precision fields
 | 
			
		||||
@@ -42,12 +43,16 @@ namespace Grid {
 | 
			
		||||
    LinearOperatorBase<FieldF> &Linop_f;
 | 
			
		||||
    LinearOperatorBase<FieldD> &Linop_d;
 | 
			
		||||
 | 
			
		||||
    Integer TotalInnerIterations; //Number of inner CG iterations
 | 
			
		||||
    Integer TotalOuterIterations; //Number of restarts
 | 
			
		||||
    Integer TotalFinalStepIterations; //Number of CG iterations in final patch-up step
 | 
			
		||||
 | 
			
		||||
    //Option to speed up *inner single precision* solves using a LinearFunction that produces a guess
 | 
			
		||||
    LinearFunction<FieldF> *guesser;
 | 
			
		||||
    
 | 
			
		||||
    MixedPrecisionConjugateGradient(RealD tol, Integer maxinnerit, Integer maxouterit, GridBase* _sp_grid, LinearOperatorBase<FieldF> &_Linop_f, LinearOperatorBase<FieldD> &_Linop_d) :
 | 
			
		||||
      Linop_f(_Linop_f), Linop_d(_Linop_d),
 | 
			
		||||
      Tolerance(tol), MaxInnerIterations(maxinnerit), MaxOuterIterations(maxouterit), SinglePrecGrid(_sp_grid),
 | 
			
		||||
      Tolerance(tol), InnerTolerance(tol), MaxInnerIterations(maxinnerit), MaxOuterIterations(maxouterit), SinglePrecGrid(_sp_grid),
 | 
			
		||||
      OuterLoopNormMult(100.), guesser(NULL){ };
 | 
			
		||||
 | 
			
		||||
    void useGuesser(LinearFunction<FieldF> &g){
 | 
			
		||||
@@ -55,6 +60,8 @@ namespace Grid {
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
    void operator() (const FieldD &src_d_in, FieldD &sol_d){
 | 
			
		||||
      TotalInnerIterations = 0;
 | 
			
		||||
	
 | 
			
		||||
      GridStopWatch TotalTimer;
 | 
			
		||||
      TotalTimer.Start();
 | 
			
		||||
    
 | 
			
		||||
@@ -74,7 +81,7 @@ namespace Grid {
 | 
			
		||||
      FieldD src_d(DoublePrecGrid);
 | 
			
		||||
      src_d = src_d_in; //source for next inner iteration, computed from residual during operation
 | 
			
		||||
    
 | 
			
		||||
      RealD inner_tol = Tolerance;
 | 
			
		||||
      RealD inner_tol = InnerTolerance;
 | 
			
		||||
    
 | 
			
		||||
      FieldF src_f(SinglePrecGrid);
 | 
			
		||||
      src_f.checkerboard = cb;
 | 
			
		||||
@@ -89,7 +96,9 @@ namespace Grid {
 | 
			
		||||
 | 
			
		||||
      GridStopWatch PrecChangeTimer;
 | 
			
		||||
    
 | 
			
		||||
      for(Integer outer_iter = 0; outer_iter < MaxOuterIterations; outer_iter++){
 | 
			
		||||
      Integer &outer_iter = TotalOuterIterations; //so it will be equal to the final iteration count
 | 
			
		||||
      
 | 
			
		||||
      for(outer_iter = 0; outer_iter < MaxOuterIterations; outer_iter++){
 | 
			
		||||
	//Compute double precision rsd and also new RHS vector.
 | 
			
		||||
	Linop_d.HermOp(sol_d, tmp_d);
 | 
			
		||||
	RealD norm = axpy_norm(src_d, -1., tmp_d, src_d_in); //src_d is residual vector
 | 
			
		||||
@@ -117,6 +126,7 @@ namespace Grid {
 | 
			
		||||
	InnerCGtimer.Start();
 | 
			
		||||
	CG_f(Linop_f, src_f, sol_f);
 | 
			
		||||
	InnerCGtimer.Stop();
 | 
			
		||||
	TotalInnerIterations += CG_f.IterationsToComplete;
 | 
			
		||||
      
 | 
			
		||||
	//Convert sol back to double and add to double prec solution
 | 
			
		||||
	PrecChangeTimer.Start();
 | 
			
		||||
@@ -131,9 +141,11 @@ namespace Grid {
 | 
			
		||||
    
 | 
			
		||||
      ConjugateGradient<FieldD> CG_d(Tolerance, MaxInnerIterations);
 | 
			
		||||
      CG_d(Linop_d, src_d_in, sol_d);
 | 
			
		||||
      TotalFinalStepIterations = CG_d.IterationsToComplete;
 | 
			
		||||
 | 
			
		||||
      TotalTimer.Stop();
 | 
			
		||||
      std::cout<<GridLogMessage<<"MixedPrecisionConjugateGradient: Total " << TotalTimer.Elapsed() << " Precision change " << PrecChangeTimer.Elapsed() << " Inner CG total " << InnerCGtimer.Elapsed() << std::endl;
 | 
			
		||||
      std::cout<<GridLogMessage<<"MixedPrecisionConjugateGradient: Inner CG iterations " << TotalInnerIterations << " Restarts " << TotalOuterIterations << " Final CG iterations " << TotalFinalStepIterations << std::endl;
 | 
			
		||||
      std::cout<<GridLogMessage<<"MixedPrecisionConjugateGradient: Total time " << TotalTimer.Elapsed() << " Precision change " << PrecChangeTimer.Elapsed() << " Inner CG total " << InnerCGtimer.Elapsed() << std::endl;
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,137 +0,0 @@
 | 
			
		||||
    /*************************************************************************************
 | 
			
		||||
 | 
			
		||||
    Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
    Source file: ./lib/algorithms/iterative/DenseMatrix.h
 | 
			
		||||
 | 
			
		||||
    Copyright (C) 2015
 | 
			
		||||
 | 
			
		||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
Author: paboyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
 | 
			
		||||
    This program is free software; you can redistribute it and/or modify
 | 
			
		||||
    it under the terms of the GNU General Public License as published by
 | 
			
		||||
    the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
    (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
    This program is distributed in the hope that it will be useful,
 | 
			
		||||
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
    GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
    You should have received a copy of the GNU General Public License along
 | 
			
		||||
    with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
    See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
    *************************************************************************************/
 | 
			
		||||
    /*  END LEGAL */
 | 
			
		||||
#ifndef GRID_DENSE_MATRIX_H
 | 
			
		||||
#define GRID_DENSE_MATRIX_H
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
    /////////////////////////////////////////////////////////////
 | 
			
		||||
    // Matrix untils
 | 
			
		||||
    /////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
template<class T> using DenseVector = std::vector<T>;
 | 
			
		||||
template<class T> using DenseMatrix = DenseVector<DenseVector<T> >;
 | 
			
		||||
 | 
			
		||||
template<class T> void Size(DenseVector<T> & vec, int &N) 
 | 
			
		||||
{ 
 | 
			
		||||
  N= vec.size();
 | 
			
		||||
}
 | 
			
		||||
template<class T> void Size(DenseMatrix<T> & mat, int &N,int &M) 
 | 
			
		||||
{ 
 | 
			
		||||
  N= mat.size();
 | 
			
		||||
  M= mat[0].size();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> void SizeSquare(DenseMatrix<T> & mat, int &N) 
 | 
			
		||||
{ 
 | 
			
		||||
  int M; Size(mat,N,M);
 | 
			
		||||
  assert(N==M);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<class T> void Resize(DenseVector<T > & mat, int N) { 
 | 
			
		||||
  mat.resize(N);
 | 
			
		||||
}
 | 
			
		||||
template<class T> void Resize(DenseMatrix<T > & mat, int N, int M) { 
 | 
			
		||||
  mat.resize(N);
 | 
			
		||||
  for(int i=0;i<N;i++){
 | 
			
		||||
    mat[i].resize(M);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
template<class T> void Fill(DenseMatrix<T> & mat, T&val) { 
 | 
			
		||||
  int N,M;
 | 
			
		||||
  Size(mat,N,M);
 | 
			
		||||
  for(int i=0;i<N;i++){
 | 
			
		||||
  for(int j=0;j<M;j++){
 | 
			
		||||
    mat[i][j] = val;
 | 
			
		||||
  }}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Transpose of a matrix **/
 | 
			
		||||
template<class T> DenseMatrix<T> Transpose(DenseMatrix<T> & mat){
 | 
			
		||||
  int N,M;
 | 
			
		||||
  Size(mat,N,M);
 | 
			
		||||
  DenseMatrix<T> C; Resize(C,M,N);
 | 
			
		||||
  for(int i=0;i<M;i++){
 | 
			
		||||
  for(int j=0;j<N;j++){
 | 
			
		||||
    C[i][j] = mat[j][i];
 | 
			
		||||
  }} 
 | 
			
		||||
  return C;
 | 
			
		||||
}
 | 
			
		||||
/** Set DenseMatrix to unit matrix **/
 | 
			
		||||
template<class T> void Unity(DenseMatrix<T> &A){
 | 
			
		||||
  int N;  SizeSquare(A,N);
 | 
			
		||||
  for(int i=0;i<N;i++){
 | 
			
		||||
    for(int j=0;j<N;j++){
 | 
			
		||||
      if ( i==j ) A[i][j] = 1;
 | 
			
		||||
      else        A[i][j] = 0;
 | 
			
		||||
    } 
 | 
			
		||||
  } 
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Add C * I to matrix **/
 | 
			
		||||
template<class T>
 | 
			
		||||
void PlusUnit(DenseMatrix<T> & A,T c){
 | 
			
		||||
  int dim;  SizeSquare(A,dim);
 | 
			
		||||
  for(int i=0;i<dim;i++){A[i][i] = A[i][i] + c;} 
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** return the Hermitian conjugate of matrix **/
 | 
			
		||||
template<class T>
 | 
			
		||||
DenseMatrix<T> HermitianConj(DenseMatrix<T> &mat){
 | 
			
		||||
 | 
			
		||||
  int dim; SizeSquare(mat,dim);
 | 
			
		||||
 | 
			
		||||
  DenseMatrix<T> C; Resize(C,dim,dim);
 | 
			
		||||
 | 
			
		||||
  for(int i=0;i<dim;i++){
 | 
			
		||||
    for(int j=0;j<dim;j++){
 | 
			
		||||
      C[i][j] = conj(mat[j][i]);
 | 
			
		||||
    } 
 | 
			
		||||
  } 
 | 
			
		||||
  return C;
 | 
			
		||||
}
 | 
			
		||||
/**Get a square submatrix**/
 | 
			
		||||
template <class T>
 | 
			
		||||
DenseMatrix<T> GetSubMtx(DenseMatrix<T> &A,int row_st, int row_end, int col_st, int col_end)
 | 
			
		||||
{
 | 
			
		||||
  DenseMatrix<T> H; Resize(H,row_end - row_st,col_end-col_st);
 | 
			
		||||
 | 
			
		||||
  for(int i = row_st; i<row_end; i++){
 | 
			
		||||
  for(int j = col_st; j<col_end; j++){
 | 
			
		||||
    H[i-row_st][j-col_st]=A[i][j];
 | 
			
		||||
  }}
 | 
			
		||||
  return H;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#include "Householder.h"
 | 
			
		||||
#include "Francis.h"
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@@ -1,81 +0,0 @@
 | 
			
		||||
    /*************************************************************************************
 | 
			
		||||
 | 
			
		||||
    Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
    Source file: ./lib/algorithms/iterative/EigenSort.h
 | 
			
		||||
 | 
			
		||||
    Copyright (C) 2015
 | 
			
		||||
 | 
			
		||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
 | 
			
		||||
    This program is free software; you can redistribute it and/or modify
 | 
			
		||||
    it under the terms of the GNU General Public License as published by
 | 
			
		||||
    the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
    (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
    This program is distributed in the hope that it will be useful,
 | 
			
		||||
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
    GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
    You should have received a copy of the GNU General Public License along
 | 
			
		||||
    with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
    See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
    *************************************************************************************/
 | 
			
		||||
    /*  END LEGAL */
 | 
			
		||||
#ifndef GRID_EIGENSORT_H
 | 
			
		||||
#define GRID_EIGENSORT_H
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
    /////////////////////////////////////////////////////////////
 | 
			
		||||
    // Eigen sorter to begin with
 | 
			
		||||
    /////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
template<class Field>
 | 
			
		||||
class SortEigen {
 | 
			
		||||
 private:
 | 
			
		||||
  
 | 
			
		||||
//hacking for testing for now
 | 
			
		||||
 private:
 | 
			
		||||
  static bool less_lmd(RealD left,RealD right){
 | 
			
		||||
    return left > right;
 | 
			
		||||
  }  
 | 
			
		||||
  static bool less_pair(std::pair<RealD,Field const*>& left,
 | 
			
		||||
                        std::pair<RealD,Field const*>& right){
 | 
			
		||||
    return left.first > (right.first);
 | 
			
		||||
  }  
 | 
			
		||||
  
 | 
			
		||||
  
 | 
			
		||||
 public:
 | 
			
		||||
 | 
			
		||||
  void push(DenseVector<RealD>& lmd,
 | 
			
		||||
            DenseVector<Field>& evec,int N) {
 | 
			
		||||
    DenseVector<Field> cpy(lmd.size(),evec[0]._grid);
 | 
			
		||||
    for(int i=0;i<lmd.size();i++) cpy[i] = evec[i];
 | 
			
		||||
    
 | 
			
		||||
    DenseVector<std::pair<RealD, Field const*> > emod(lmd.size());    
 | 
			
		||||
    for(int i=0;i<lmd.size();++i)
 | 
			
		||||
      emod[i] = std::pair<RealD,Field const*>(lmd[i],&cpy[i]);
 | 
			
		||||
 | 
			
		||||
    partial_sort(emod.begin(),emod.begin()+N,emod.end(),less_pair);
 | 
			
		||||
 | 
			
		||||
    typename DenseVector<std::pair<RealD, Field const*> >::iterator it = emod.begin();
 | 
			
		||||
    for(int i=0;i<N;++i){
 | 
			
		||||
      lmd[i]=it->first;
 | 
			
		||||
      evec[i]=*(it->second);
 | 
			
		||||
      ++it;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  void push(DenseVector<RealD>& lmd,int N) {
 | 
			
		||||
    std::partial_sort(lmd.begin(),lmd.begin()+N,lmd.end(),less_lmd);
 | 
			
		||||
  }
 | 
			
		||||
  bool saturated(RealD lmd, RealD thrs) {
 | 
			
		||||
    return fabs(lmd) > fabs(thrs);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,525 +0,0 @@
 | 
			
		||||
    /*************************************************************************************
 | 
			
		||||
 | 
			
		||||
    Grid physics library, www.github.com/paboyle/Grid 
 | 
			
		||||
 | 
			
		||||
    Source file: ./lib/algorithms/iterative/Francis.h
 | 
			
		||||
 | 
			
		||||
    Copyright (C) 2015
 | 
			
		||||
 | 
			
		||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
 | 
			
		||||
 | 
			
		||||
    This program is free software; you can redistribute it and/or modify
 | 
			
		||||
    it under the terms of the GNU General Public License as published by
 | 
			
		||||
    the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
    (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
    This program is distributed in the hope that it will be useful,
 | 
			
		||||
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
    GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
    You should have received a copy of the GNU General Public License along
 | 
			
		||||
    with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
    See the full license in the file "LICENSE" in the top level distribution directory
 | 
			
		||||
    *************************************************************************************/
 | 
			
		||||
    /*  END LEGAL */
 | 
			
		||||
#ifndef FRANCIS_H
 | 
			
		||||
#define FRANCIS_H
 | 
			
		||||
 | 
			
		||||
#include <cstdlib>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <cmath>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <sstream>
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
#include <fstream>
 | 
			
		||||
#include <complex>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
 | 
			
		||||
//#include <timer.h>
 | 
			
		||||
//#include <lapacke.h>
 | 
			
		||||
//#include <Eigen/Dense>
 | 
			
		||||
 | 
			
		||||
namespace Grid {
 | 
			
		||||
 | 
			
		||||
template <class T> int SymmEigensystem(DenseMatrix<T > &Ain, DenseVector<T> &evals, DenseMatrix<T> &evecs, RealD small);
 | 
			
		||||
template <class T> int     Eigensystem(DenseMatrix<T > &Ain, DenseVector<T> &evals, DenseMatrix<T> &evecs, RealD small);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  Find the eigenvalues of an upper hessenberg matrix using the Francis QR algorithm.
 | 
			
		||||
H =
 | 
			
		||||
      x  x  x  x  x  x  x  x  x
 | 
			
		||||
      x  x  x  x  x  x  x  x  x
 | 
			
		||||
      0  x  x  x  x  x  x  x  x
 | 
			
		||||
      0  0  x  x  x  x  x  x  x
 | 
			
		||||
      0  0  0  x  x  x  x  x  x
 | 
			
		||||
      0  0  0  0  x  x  x  x  x
 | 
			
		||||
      0  0  0  0  0  x  x  x  x
 | 
			
		||||
      0  0  0  0  0  0  x  x  x
 | 
			
		||||
      0  0  0  0  0  0  0  x  x
 | 
			
		||||
Factorization is P T P^H where T is upper triangular (mod cc blocks) and P is orthagonal/unitary.
 | 
			
		||||
**/
 | 
			
		||||
template <class T>
 | 
			
		||||
int QReigensystem(DenseMatrix<T> &Hin, DenseVector<T> &evals, DenseMatrix<T> &evecs, RealD small)
 | 
			
		||||
{
 | 
			
		||||
  DenseMatrix<T> H = Hin; 
 | 
			
		||||
 | 
			
		||||
  int N ; SizeSquare(H,N);
 | 
			
		||||
  int M = N;
 | 
			
		||||
 | 
			
		||||
  Fill(evals,0);
 | 
			
		||||
  Fill(evecs,0);
 | 
			
		||||
 | 
			
		||||
  T s,t,x=0,y=0,z=0;
 | 
			
		||||
  T u,d;
 | 
			
		||||
  T apd,amd,bc;
 | 
			
		||||
  DenseVector<T> p(N,0);
 | 
			
		||||
  T nrm = Norm(H);    ///DenseMatrix Norm
 | 
			
		||||
  int n, m;
 | 
			
		||||
  int e = 0;
 | 
			
		||||
  int it = 0;
 | 
			
		||||
  int tot_it = 0;
 | 
			
		||||
  int l = 0;
 | 
			
		||||
  int r = 0;
 | 
			
		||||
  DenseMatrix<T> P; Resize(P,N,N); Unity(P);
 | 
			
		||||
  DenseVector<int> trows(N,0);
 | 
			
		||||
 | 
			
		||||
  /// Check if the matrix is really hessenberg, if not abort
 | 
			
		||||
  RealD sth = 0;
 | 
			
		||||
  for(int j=0;j<N;j++){
 | 
			
		||||
    for(int i=j+2;i<N;i++){
 | 
			
		||||
      sth = abs(H[i][j]);
 | 
			
		||||
      if(sth > small){
 | 
			
		||||
	std::cout << "Non hessenberg H = " << sth << " > " << small << std::endl;
 | 
			
		||||
	exit(1);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  do{
 | 
			
		||||
    std::cout << "Francis QR Step N = " << N << std::endl;
 | 
			
		||||
    /** Check for convergence
 | 
			
		||||
      x  x  x  x  x
 | 
			
		||||
      0  x  x  x  x
 | 
			
		||||
      0  0  x  x  x
 | 
			
		||||
      0  0  x  x  x
 | 
			
		||||
      0  0  0  0  x
 | 
			
		||||
      for this matrix l = 4
 | 
			
		||||
     **/
 | 
			
		||||
    do{
 | 
			
		||||
      l = Chop_subdiag(H,nrm,e,small);
 | 
			
		||||
      r = 0;    ///May have converged on more than one eval
 | 
			
		||||
      ///Single eval
 | 
			
		||||
      if(l == N-1){
 | 
			
		||||
        evals[e] = H[l][l];
 | 
			
		||||
        N--; e++; r++; it = 0;
 | 
			
		||||
      }
 | 
			
		||||
      ///RealD eval
 | 
			
		||||
      if(l == N-2){
 | 
			
		||||
        trows[l+1] = 1;    ///Needed for UTSolve
 | 
			
		||||
        apd = H[l][l] + H[l+1][l+1];
 | 
			
		||||
        amd = H[l][l] - H[l+1][l+1];
 | 
			
		||||
        bc =  (T)4.0*H[l+1][l]*H[l][l+1];
 | 
			
		||||
        evals[e]   = (T)0.5*( apd + sqrt(amd*amd + bc) );
 | 
			
		||||
        evals[e+1] = (T)0.5*( apd - sqrt(amd*amd + bc) );
 | 
			
		||||
        N-=2; e+=2; r++; it = 0;
 | 
			
		||||
      }
 | 
			
		||||
    } while(r>0);
 | 
			
		||||
 | 
			
		||||
    if(N ==0) break;
 | 
			
		||||
 | 
			
		||||
    DenseVector<T > ck; Resize(ck,3);
 | 
			
		||||
    DenseVector<T> v;   Resize(v,3);
 | 
			
		||||
 | 
			
		||||
    for(int m = N-3; m >= l; m--){
 | 
			
		||||
      ///Starting vector essentially random shift.
 | 
			
		||||
      if(it%10 == 0 && N >= 3 && it > 0){
 | 
			
		||||
        s = (T)1.618033989*( abs( H[N-1][N-2] ) + abs( H[N-2][N-3] ) );
 | 
			
		||||
        t = (T)0.618033989*( abs( H[N-1][N-2] ) + abs( H[N-2][N-3] ) );
 | 
			
		||||
        x = H[m][m]*H[m][m] + H[m][m+1]*H[m+1][m] - s*H[m][m] + t;
 | 
			
		||||
        y = H[m+1][m]*(H[m][m] + H[m+1][m+1] - s);
 | 
			
		||||
        z = H[m+1][m]*H[m+2][m+1];
 | 
			
		||||
      }
 | 
			
		||||
      ///Starting vector implicit Q theorem
 | 
			
		||||
      else{
 | 
			
		||||
        s = (H[N-2][N-2] + H[N-1][N-1]);
 | 
			
		||||
        t = (H[N-2][N-2]*H[N-1][N-1] - H[N-2][N-1]*H[N-1][N-2]);
 | 
			
		||||
        x = H[m][m]*H[m][m] + H[m][m+1]*H[m+1][m] - s*H[m][m] + t;
 | 
			
		||||
        y = H[m+1][m]*(H[m][m] + H[m+1][m+1] - s);
 | 
			
		||||
        z = H[m+1][m]*H[m+2][m+1];
 | 
			
		||||
      }
 | 
			
		||||
      ck[0] = x; ck[1] = y; ck[2] = z;
 | 
			
		||||
 | 
			
		||||
      if(m == l) break;
 | 
			
		||||
 | 
			
		||||
      /** Some stupid thing from numerical recipies, seems to work**/
 | 
			
		||||
      // PAB.. for heaven's sake quote page, purpose, evidence it works.
 | 
			
		||||
      //       what sort of comment is that!?!?!?
 | 
			
		||||
      u=abs(H[m][m-1])*(abs(y)+abs(z));
 | 
			
		||||
      d=abs(x)*(abs(H[m-1][m-1])+abs(H[m][m])+abs(H[m+1][m+1]));
 | 
			
		||||
      if ((T)abs(u+d) == (T)abs(d) ){
 | 
			
		||||
	l = m; break;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      //if (u < small){l = m; break;}
 | 
			
		||||
    }
 | 
			
		||||
    if(it > 100000){
 | 
			
		||||
     std::cout << "QReigensystem: bugger it got stuck after 100000 iterations" << std::endl;
 | 
			
		||||
     std::cout << "got " << e << " evals " << l << " " << N << std::endl;
 | 
			
		||||
      exit(1);
 | 
			
		||||
    }
 | 
			
		||||
    normalize(ck);    ///Normalization cancels in PHP anyway
 | 
			
		||||
    T beta;
 | 
			
		||||
    Householder_vector<T >(ck, 0, 2, v, beta);
 | 
			
		||||
    Householder_mult<T >(H,v,beta,0,l,l+2,0);
 | 
			
		||||
    Householder_mult<T >(H,v,beta,0,l,l+2,1);
 | 
			
		||||
    ///Accumulate eigenvector
 | 
			
		||||
    Householder_mult<T >(P,v,beta,0,l,l+2,1);
 | 
			
		||||
    int sw = 0;      ///Are we on the last row?
 | 
			
		||||
    for(int k=l;k<N-2;k++){
 | 
			
		||||
      x = H[k+1][k];
 | 
			
		||||
      y = H[k+2][k];
 | 
			
		||||
      z = (T)0.0;
 | 
			
		||||
      if(k+3 <= N-1){
 | 
			
		||||
	z = H[k+3][k];
 | 
			
		||||
      } else{
 | 
			
		||||
	sw = 1; 
 | 
			
		||||
	v[2] = (T)0.0;
 | 
			
		||||
      }
 | 
			
		||||
      ck[0] = x; ck[1] = y; ck[2] = z;
 | 
			
		||||
      normalize(ck);
 | 
			
		||||
      Householder_vector<T >(ck, 0, 2-sw, v, beta);
 | 
			
		||||
      Householder_mult<T >(H,v, beta,0,k+1,k+3-sw,0);
 | 
			
		||||
      Householder_mult<T >(H,v, beta,0,k+1,k+3-sw,1);
 | 
			
		||||
      ///Accumulate eigenvector
 | 
			
		||||
      Householder_mult<T >(P,v, beta,0,k+1,k+3-sw,1);
 | 
			
		||||
    }
 | 
			
		||||
    it++;
 | 
			
		||||
    tot_it++;
 | 
			
		||||
  }while(N > 1);
 | 
			
		||||
  N = evals.size();
 | 
			
		||||
  ///Annoying - UT solves in reverse order;
 | 
			
		||||
  DenseVector<T> tmp; Resize(tmp,N);
 | 
			
		||||
  for(int i=0;i<N;i++){
 | 
			
		||||
    tmp[i] = evals[N-i-1];
 | 
			
		||||
  } 
 | 
			
		||||
  evals = tmp;
 | 
			
		||||
  UTeigenvectors(H, trows, evals, evecs);
 | 
			
		||||
  for(int i=0;i<evals.size();i++){evecs[i] = P*evecs[i]; normalize(evecs[i]);}
 | 
			
		||||
  return tot_it;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class T>
 | 
			
		||||
int my_Wilkinson(DenseMatrix<T> &Hin, DenseVector<T> &evals, DenseMatrix<T> &evecs, RealD small)
 | 
			
		||||
{
 | 
			
		||||
  /**
 | 
			
		||||
  Find the eigenvalues of an upper Hessenberg matrix using the Wilkinson QR algorithm.
 | 
			
		||||
  H =
 | 
			
		||||
  x  x  0  0  0  0
 | 
			
		||||
  x  x  x  0  0  0
 | 
			
		||||
  0  x  x  x  0  0
 | 
			
		||||
  0  0  x  x  x  0
 | 
			
		||||
  0  0  0  x  x  x
 | 
			
		||||
  0  0  0  0  x  x
 | 
			
		||||
  Factorization is P T P^H where T is upper triangular (mod cc blocks) and P is orthagonal/unitary.  **/
 | 
			
		||||
  return my_Wilkinson(Hin, evals, evecs, small, small);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class T>
 | 
			
		||||
int my_Wilkinson(DenseMatrix<T> &Hin, DenseVector<T> &evals, DenseMatrix<T> &evecs, RealD small, RealD tol)
 | 
			
		||||
{
 | 
			
		||||
  int N; SizeSquare(Hin,N);
 | 
			
		||||
  int M = N;
 | 
			
		||||
 | 
			
		||||
  ///I don't want to modify the input but matricies must be passed by reference
 | 
			
		||||
  //Scale a matrix by its "norm"
 | 
			
		||||
  //RealD Hnorm = abs( Hin.LargestDiag() ); H =  H*(1.0/Hnorm);
 | 
			
		||||
  DenseMatrix<T> H;  H = Hin;
 | 
			
		||||
  
 | 
			
		||||
  RealD Hnorm = abs(Norm(Hin));
 | 
			
		||||
  H = H * (1.0 / Hnorm);
 | 
			
		||||
 | 
			
		||||
  // TODO use openmp and memset
 | 
			
		||||
  Fill(evals,0);
 | 
			
		||||
  Fill(evecs,0);
 | 
			
		||||
 | 
			
		||||
  T s, t, x = 0, y = 0, z = 0;
 | 
			
		||||
  T u, d;
 | 
			
		||||
  T apd, amd, bc;
 | 
			
		||||
  DenseVector<T> p; Resize(p,N); Fill(p,0);
 | 
			
		||||
 | 
			
		||||
  T nrm = Norm(H);    ///DenseMatrix Norm
 | 
			
		||||
  int n, m;
 | 
			
		||||
  int e = 0;
 | 
			
		||||
  int it = 0;
 | 
			
		||||
  int tot_it = 0;
 | 
			
		||||
  int l = 0;
 | 
			
		||||
  int r = 0;
 | 
			
		||||
  DenseMatrix<T> P; Resize(P,N,N);
 | 
			
		||||
  Unity(P);
 | 
			
		||||
  DenseVector<int> trows(N, 0);
 | 
			
		||||
  /// Check if the matrix is really symm tridiag
 | 
			
		||||
  RealD sth = 0;
 | 
			
		||||
  for(int j = 0; j < N; ++j)
 | 
			
		||||
  {
 | 
			
		||||
    for(int i = j + 2; i < N; ++i)
 | 
			
		||||
    {
 | 
			
		||||
      if(abs(H[i][j]) > tol || abs(H[j][i]) > tol)
 | 
			
		||||
      {
 | 
			
		||||
	std::cout << "Non Tridiagonal H(" << i << ","<< j << ") = |" << Real( real( H[j][i] ) ) << "| > " << tol << std::endl;
 | 
			
		||||
	std::cout << "Warning tridiagonalize and call again" << std::endl;
 | 
			
		||||
        // exit(1); // see what is going on
 | 
			
		||||
        //return;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  do{
 | 
			
		||||
    do{
 | 
			
		||||
      //Jasper
 | 
			
		||||
      //Check if the subdiagonal term is small enough (<small)
 | 
			
		||||
      //if true then it is converged.
 | 
			
		||||
      //check start from H.dim - e - 1
 | 
			
		||||
      //How to deal with more than 2 are converged?
 | 
			
		||||
      //What if Chop_symm_subdiag return something int the middle?
 | 
			
		||||
      //--------------
 | 
			
		||||
      l = Chop_symm_subdiag(H,nrm, e, small);
 | 
			
		||||
      r = 0;    ///May have converged on more than one eval
 | 
			
		||||
      //Jasper
 | 
			
		||||
      //In this case
 | 
			
		||||
      // x  x  0  0  0  0
 | 
			
		||||
      // x  x  x  0  0  0
 | 
			
		||||
      // 0  x  x  x  0  0
 | 
			
		||||
      // 0  0  x  x  x  0
 | 
			
		||||
      // 0  0  0  x  x  0
 | 
			
		||||
      // 0  0  0  0  0  x  <- l
 | 
			
		||||
      //--------------
 | 
			
		||||
      ///Single eval
 | 
			
		||||
      if(l == N - 1)
 | 
			
		||||
      {
 | 
			
		||||
        evals[e] = H[l][l];
 | 
			
		||||
        N--;
 | 
			
		||||
        e++;
 | 
			
		||||
        r++;
 | 
			
		||||
        it = 0;
 | 
			
		||||
      }
 | 
			
		||||
      //Jasper
 | 
			
		||||
      // x  x  0  0  0  0
 | 
			
		||||
      // x  x  x  0  0  0
 | 
			
		||||
      // 0  x  x  x  0  0
 | 
			
		||||
      // 0  0  x  x  0  0
 | 
			
		||||
      // 0  0  0  0  x  x  <- l
 | 
			
		||||
      // 0  0  0  0  x  x
 | 
			
		||||
      //--------------
 | 
			
		||||
      ///RealD eval
 | 
			
		||||
      if(l == N - 2)
 | 
			
		||||
      {
 | 
			
		||||
        trows[l + 1] = 1;    ///Needed for UTSolve
 | 
			
		||||
        apd = H[l][l] + H[l + 1][ l + 1];
 | 
			
		||||
        amd = H[l][l] - H[l + 1][l + 1];
 | 
			
		||||
        bc =  (T) 4.0 * H[l + 1][l] * H[l][l + 1];
 | 
			
		||||
        evals[e] = (T) 0.5 * (apd + sqrt(amd * amd + bc));
 | 
			
		||||
        evals[e + 1] = (T) 0.5 * (apd - sqrt(amd * amd + bc));
 | 
			
		||||
        N -= 2;
 | 
			
		||||
        e += 2;
 | 
			
		||||
        r++;
 | 
			
		||||
        it = 0;
 | 
			
		||||
      }
 | 
			
		||||
    }while(r > 0);
 | 
			
		||||
    //Jasper
 | 
			
		||||
    //Already converged
 | 
			
		||||
    //--------------
 | 
			
		||||
    if(N == 0) break;
 | 
			
		||||
 | 
			
		||||
    DenseVector<T> ck,v; Resize(ck,2); Resize(v,2);
 | 
			
		||||
 | 
			
		||||
    for(int m = N - 3; m >= l; m--)
 | 
			
		||||
    {
 | 
			
		||||
      ///Starting vector essentially random shift.
 | 
			
		||||
      if(it%10 == 0 && N >= 3 && it > 0)
 | 
			
		||||
      {
 | 
			
		||||
        t = abs(H[N - 1][N - 2]) + abs(H[N - 2][N - 3]);
 | 
			
		||||
        x = H[m][m] - t;
 | 
			
		||||
        z = H[m + 1][m];
 | 
			
		||||
      } else {
 | 
			
		||||
      ///Starting vector implicit Q theorem
 | 
			
		||||
        d = (H[N - 2][N - 2] - H[N - 1][N - 1]) * (T) 0.5;
 | 
			
		||||
        t =  H[N - 1][N - 1] - H[N - 1][N - 2] * H[N - 1][N - 2] 
 | 
			
		||||
	  / (d + sign(d) * sqrt(d * d + H[N - 1][N - 2] * H[N - 1][N - 2]));
 | 
			
		||||
        x = H[m][m] - t;
 | 
			
		||||
        z = H[m + 1][m];
 | 
			
		||||
      }
 | 
			
		||||
      //Jasper
 | 
			
		||||
      //why it is here????
 | 
			
		||||
      //-----------------------
 | 
			
		||||
      if(m == l)
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
      u = abs(H[m][m - 1]) * (abs(y) + abs(z));
 | 
			
		||||
      d = abs(x) * (abs(H[m - 1][m - 1]) + abs(H[m][m]) + abs(H[m + 1][m + 1]));
 | 
			
		||||
      if ((T)abs(u + d) == (T)abs(d))
 | 
			
		||||
      {
 | 
			
		||||
        l = m;
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    //Jasper
 | 
			
		||||
    if(it > 1000000)
 | 
			
		||||
    {
 | 
			
		||||
      std::cout << "Wilkinson: bugger it got stuck after 100000 iterations" << std::endl;
 | 
			
		||||
      std::cout << "got " << e << " evals " << l << " " << N << std::endl;
 | 
			
		||||
      exit(1);
 | 
			
		||||
    }
 | 
			
		||||
    //
 | 
			
		||||
    T s, c;
 | 
			
		||||
    Givens_calc<T>(x, z, c, s);
 | 
			
		||||
    Givens_mult<T>(H, l, l + 1, c, -s, 0);
 | 
			
		||||
    Givens_mult<T>(H, l, l + 1, c,  s, 1);
 | 
			
		||||
    Givens_mult<T>(P, l, l + 1, c,  s, 1);
 | 
			
		||||
    //
 | 
			
		||||
    for(int k = l; k < N - 2; ++k)
 | 
			
		||||
    {
 | 
			
		||||
      x = H.A[k + 1][k];
 | 
			
		||||
      z = H.A[k + 2][k];
 | 
			
		||||
      Givens_calc<T>(x, z, c, s);
 | 
			
		||||
      Givens_mult<T>(H, k + 1, k + 2, c, -s, 0);
 | 
			
		||||
      Givens_mult<T>(H, k + 1, k + 2, c,  s, 1);
 | 
			
		||||
      Givens_mult<T>(P, k + 1, k + 2, c,  s, 1);
 | 
			
		||||
    }
 | 
			
		||||
    it++;
 | 
			
		||||
    tot_it++;
 | 
			
		||||
  }while(N > 1);
 | 
			
		||||
 | 
			
		||||
  N = evals.size();
 | 
			
		||||
  ///Annoying - UT solves in reverse order;
 | 
			
		||||
  DenseVector<T> tmp(N);
 | 
			
		||||
  for(int i = 0; i < N; ++i)
 | 
			
		||||
    tmp[i] = evals[N-i-1];
 | 
			
		||||
  evals = tmp;
 | 
			
		||||
  //
 | 
			
		||||
  UTeigenvectors(H, trows, evals, evecs);
 | 
			
		||||
  //UTSymmEigenvectors(H, trows, evals, evecs);
 | 
			
		||||
  for(int i = 0; i < evals.size(); ++i)
 | 
			
		||||
  {
 | 
			
		||||
    evecs[i] = P * evecs[i];
 | 
			
		||||
    normalize(evecs[i]);
 | 
			
		||||
    evals[i] = evals[i] * Hnorm;
 | 
			
		||||
  }
 | 
			
		||||
  // // FIXME this is to test
 | 
			
		||||
  // Hin.write("evecs3", evecs);
 | 
			
		||||
  // Hin.write("evals3", evals);
 | 
			
		||||
  // // check rsd
 | 
			
		||||
  // for(int i = 0; i < M; i++) {
 | 
			
		||||
  //   vector<T> Aevec = Hin * evecs[i];
 | 
			
		||||
  //   RealD norm2(0.);
 | 
			
		||||
  //   for(int j = 0; j < M; j++) {
 | 
			
		||||
  //     norm2 += (Aevec[j] - evals[i] * evecs[i][j]) * (Aevec[j] - evals[i] * evecs[i][j]);
 | 
			
		||||
  //   }
 | 
			
		||||
  // }
 | 
			
		||||
  return tot_it;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class T>
 | 
			
		||||
void Hess(DenseMatrix<T > &A, DenseMatrix<T> &Q, int start){
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
  turn a matrix A =
 | 
			
		||||
  x  x  x  x  x
 | 
			
		||||
  x  x  x  x  x
 | 
			
		||||
  x  x  x  x  x
 | 
			
		||||
  x  x  x  x  x
 | 
			
		||||
  x  x  x  x  x
 | 
			
		||||
  into
 | 
			
		||||
  x  x  x  x  x
 | 
			
		||||
  x  x  x  x  x
 | 
			
		||||
  0  x  x  x  x
 | 
			
		||||
  0  0  x  x  x
 | 
			
		||||
  0  0  0  x  x
 | 
			
		||||
  with householder rotations
 | 
			
		||||
  Slow.
 | 
			
		||||
  */
 | 
			
		||||
  int N ; SizeSquare(A,N);
 | 
			
		||||
  DenseVector<T > p; Resize(p,N); Fill(p,0);
 | 
			
		||||
 | 
			
		||||
  for(int k=start;k<N-2;k++){
 | 
			
		||||
    //cerr << "hess" << k << std::endl;
 | 
			
		||||
    DenseVector<T > ck,v; Resize(ck,N-k-1); Resize(v,N-k-1);
 | 
			
		||||
    for(int i=k+1;i<N;i++){ck[i-k-1] = A(i,k);}  ///kth column
 | 
			
		||||
    normalize(ck);    ///Normalization cancels in PHP anyway
 | 
			
		||||
    T beta;
 | 
			
		||||
    Householder_vector<T >(ck, 0, ck.size()-1, v, beta);  ///Householder vector
 | 
			
		||||
    Householder_mult<T>(A,v,beta,start,k+1,N-1,0);  ///A -> PA
 | 
			
		||||
    Householder_mult<T >(A,v,beta,start,k+1,N-1,1);  ///PA -> PAP^H
 | 
			
		||||
    ///Accumulate eigenvector
 | 
			
		||||
    Householder_mult<T >(Q,v,beta,start,k+1,N-1,1);  ///Q -> QP^H
 | 
			
		||||
  }
 | 
			
		||||
  /*for(int l=0;l<N-2;l++){
 | 
			
		||||
    for(int k=l+2;k<N;k++){
 | 
			
		||||
    A(0,k,l);
 | 
			
		||||
    }
 | 
			
		||||
    }*/
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class T>
 | 
			
		||||
void Tri(DenseMatrix<T > &A, DenseMatrix<T> &Q, int start){
 | 
			
		||||
///Tridiagonalize a matrix
 | 
			
		||||
  int N; SizeSquare(A,N);
 | 
			
		||||
  Hess(A,Q,start);
 | 
			
		||||
  /*for(int l=0;l<N-2;l++){
 | 
			
		||||
    for(int k=l+2;k<N;k++){
 | 
			
		||||
    A(0,l,k);
 | 
			
		||||
    }
 | 
			
		||||
    }*/
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class T>
 | 
			
		||||
void ForceTridiagonal(DenseMatrix<T> &A){
 | 
			
		||||
///Tridiagonalize a matrix
 | 
			
		||||
  int N ; SizeSquare(A,N);
 | 
			
		||||
  for(int l=0;l<N-2;l++){
 | 
			
		||||
    for(int k=l+2;k<N;k++){
 | 
			
		||||
      A[l][k]=0;
 | 
			
		||||
      A[k][l]=0;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class T>
 | 
			
		||||
int my_SymmEigensystem(DenseMatrix<T > &Ain, DenseVector<T> &evals, DenseVector<DenseVector<T> > &evecs, RealD small){
 | 
			
		||||
  ///Solve a symmetric eigensystem, not necessarily in tridiagonal form
 | 
			
		||||
  int N; SizeSquare(Ain,N);
 | 
			
		||||
  DenseMatrix<T > A; A = Ain;
 | 
			
		||||
  DenseMatrix<T > Q; Resize(Q,N,N); Unity(Q);
 | 
			
		||||
  Tri(A,Q,0);
 | 
			
		||||
  int it = my_Wilkinson<T>(A, evals, evecs, small);
 | 
			
		||||
  for(int k=0;k<N;k++){evecs[k] = Q*evecs[k];}
 | 
			
		||||
  return it;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template <class T>
 | 
			
		||||
int Wilkinson(DenseMatrix<T> &Ain, DenseVector<T> &evals, DenseVector<DenseVector<T> > &evecs, RealD small){
 | 
			
		||||
  return my_Wilkinson(Ain, evals, evecs, small);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class T>
 | 
			
		||||
int SymmEigensystem(DenseMatrix<T> &Ain, DenseVector<T> &evals, DenseVector<DenseVector<T> > &evecs, RealD small){
 | 
			
		||||
  return my_SymmEigensystem(Ain, evals, evecs, small);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class T>
 | 
			
		||||
int Eigensystem(DenseMatrix<T > &Ain, DenseVector<T> &evals, DenseVector<DenseVector<T> > &evecs, RealD small){
 | 
			
		||||
///Solve a general eigensystem, not necessarily in tridiagonal form
 | 
			
		||||
  int N = Ain.dim;
 | 
			
		||||
  DenseMatrix<T > A(N); A = Ain;
 | 
			
		||||
  DenseMatrix<T > Q(N);Q.Unity();
 | 
			
		||||
  Hess(A,Q,0);
 | 
			
		||||
  int it = QReigensystem<T>(A, evals, evecs, small);
 | 
			
		||||
  for(int k=0;k<N;k++){evecs[k] = Q*evecs[k];}
 | 
			
		||||
  return it;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user