mirror of
				https://github.com/paboyle/Grid.git
				synced 2025-10-30 19:44:32 +00:00 
			
		
		
		
	Compare commits
	
		
			767 Commits
		
	
	
		
			chulwoo-de
			...
			feature/si
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 561426f6eb | ||
|  | 83f6fab8fa | ||
|  | 0fade84ab2 | ||
|  | 9dc7ca4c3b | ||
|  | 935d82f5b1 | ||
|  | 9cbcdd65d7 | ||
|  | f18f5ed926 | ||
|  | d1d63a4f2d | ||
|  | 7e5faa0f34 | ||
|  | 6af459cae4 | ||
|  | 1c4bc7ed38 | ||
|  | 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 | ||
|  | fc93f0b2ec | ||
|  | 8c8473998d | ||
|  | e7c36771ed | ||
|  | 8dc57a1e25 | ||
|  | f57bd770b0 | ||
|  | 4ed10a3d06 | ||
|  | dfefc70b57 | ||
|  | 0b61f75c9e | ||
|  | 33edde245d | ||
|  | b64e004555 | ||
|  | 447c5e6cd7 | ||
|  | 8b99d80d8c | ||
|  | 3901b17ade | ||
|  | af230a1fb8 | ||
|  | 06a132e3f9 | ||
|  | 96d44d5c55 | ||
|  | 7fe797daf8 | ||
|  | 486a01294a | ||
|  | 586a7c90b7 | ||
|  | e099dcdae7 | ||
|  | 4e7ab3166f | ||
|  | aac80cbb44 | ||
|  | c80948411b | ||
|  | 95625a7bd1 | ||
|  | 0796696733 | ||
|  | cc773ae70c | ||
|  | d21c51b9be | ||
|  | 597a7b4b3a | ||
|  | 1c30e9a961 | ||
|  | 041884acf0 | ||
|  | 15e668eef1 | ||
|  | bf7e3f20d4 | ||
|  | 3ae92fa2e6 | ||
|  | 3906cd2149 | ||
|  | 5a1fb29db7 | ||
|  | 661fc4d3d1 | ||
|  | 41009cc142 | ||
|  | 37720c4db7 | ||
|  | 1a30455a10 | ||
|  | cd0da81196 | ||
|  | f246fe3304 | ||
|  | 8a29c16bde | ||
|  | d68907fc3e | ||
|  | 5c0adf7bf2 | ||
|  | be3a8249c6 | ||
|  | bd600702cf | ||
|  | aca7a3ef0a | ||
|  | 2c246551d0 | ||
|  | 71ac2e7940 | ||
|  | 2bf4688e83 | ||
|  | a48ee6f0f2 | ||
|  | 73547cca66 | ||
|  | 123c673db7 | ||
|  | 61f82216e2 | ||
|  | 8e7ca92278 | ||
|  | 485ad6fde0 | ||
|  | 6ea2184e18 | ||
|  | fdc170b8a3 | ||
|  | 060da786e9 | ||
|  | 85c7bc4321 | ||
|  | 0883d6a7ce | ||
|  | 9ff97b4711 | ||
|  | b5e9c900a4 | ||
|  | 4bbdfb434c | ||
|  | c94133af49 | ||
| e7d8030a64 | |||
| d775fbb2f9 | |||
| 863855f46f | |||
| 419af7610d | |||
| 7da7d263c4 | |||
| 1140573027 | |||
| a0cfbb6e88 | |||
| 515a26b3c6 | |||
| c946d3bf3f | |||
| 1c68098780 | |||
|  | 899e685627 | ||
| 3bf993d81a | |||
| fad743fbb1 | |||
|  | ef8d3831eb | ||
|  | 70ed9fc40c | ||
| 4d3787db65 | |||
|  | 677757cfeb | ||
| 05cb6d318a | |||
| 0432e30256 | |||
| 2c3ebc1e07 | |||
| 068b28af2d | |||
| f7db342f49 | |||
| d65e81518f | |||
| a37e71f362 | |||
|  | 05c1924819 | ||
| b7da264b0a | |||
| 74ac2aa676 | |||
| 4c75095c61 | |||
| afa095d33d | |||
| 6b5259cc10 | |||
| 7423a352c5 | |||
| 81e66d6631 | |||
| ade1058e5f | |||
| 6eea9e4da7 | |||
| 2c673666da | |||
| d6401e6d2c | |||
| 24d3d31b01 | |||
| 5405526424 | |||
| f3f0b6fef9 | |||
| 654e0b0fd0 | |||
| 4be08ebccc | |||
| f599cb5b17 | |||
| a4a509497a | |||
| 5803933aea | |||
|  | 7cf833dfe9 | ||
| 91a3534054 | |||
| 16a8e3d0d4 | |||
| 41df1db811 | |||
|  | c3b6d573b9 | ||
|  | 1e179c903d | ||
|  | 669cfca9b7 | ||
|  | ff2f559a57 | ||
|  | 03c81bd902 | ||
|  | a869addef1 | ||
|  | 1caa3fbc2d | ||
|  | 3d21297bbb | ||
|  | 25efefc5b4 | ||
|  | eabf316ed9 | ||
|  | 04ae7929a3 | ||
|  | caba0d42a5 | ||
|  | 9ae81c06d2 | ||
|  | 0903c48caa | ||
|  | 7dc36628a1 | ||
|  | b8cdb3e90a | ||
|  | 5241245534 | ||
|  | 960316e207 | ||
| 3215ae6b7e | |||
| 7a85fddc7e | |||
| 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 | |||
| c22c3db9ad | |||
| 013e710c7d | |||
| 16693bd69d | |||
| de8f80cf94 | |||
|  | 426197e446 | ||
|  | 99e2c1e666 | ||
|  | 1440565a10 | ||
|  | e9f0c0ea39 | ||
| 4a87486365 | |||
|  | fe187e9ed3 | ||
|  | 0091b50f49 | ||
|  | fb8d4b2357 | ||
|  | ff71a8e847 | ||
|  | 83fa038bdf | ||
|  | 7a61feb6d3 | ||
|  | 69ae817d1c | ||
| 51322da6f8 | |||
| 49c3eeb378 | |||
| c56707e003 | |||
| 5b3edf08a4 | |||
| bd1d1cca34 | |||
| 646b11f5c2 | |||
| a683a0f55a | |||
| e6effcfd95 | |||
| aa016f61b9 | |||
| d42a1b73c4 | |||
| d292657ef7 | |||
| d1f7c6b94e | |||
| 7ae734103e | |||
| 7a1ac45679 | |||
| 320268fe93 | |||
| dd6fb140c5 | |||
| 0b4f680d28 | |||
| a69086ba1f | |||
| 7433eed274 | |||
| ee5b1fe043 | |||
| 1540616b22 | |||
| 8190523e4c | |||
| b5555d85a7 | |||
|  | e27c6b217c | ||
| 9ad3d3453e | |||
|  | f7a6b8e5ed | ||
|  | 6adf35da54 | ||
| d8b716d2cd | |||
|  | cd01c1dbe9 | ||
|  | bd0430b34f | ||
|  | c097fd041a | ||
|  | 77fb25fb29 | ||
|  | 389e0a77bd | ||
|  | 2f92b4860b | ||
|  | 4704f2d009 | ||
|  | ae9688e343 | ||
| 43928846f2 | |||
| fabcd4179d | |||
| a8843c9af6 | |||
| 7a1a7a685e | |||
|  | 1e44fd3094 | ||
|  | d8258f0758 | ||
|  | 6c0cc5676b | ||
| 11dc0b398b | |||
|  | b18950f776 | ||
|  | 0acbf77bc6 | ||
| 3cdf945d84 | |||
| 5833f247fa | |||
|  | 95f43d27ae | ||
|  | 668ca57702 | ||
| a2cffb0304 | |||
| bafbac6ac4 | |||
| 595f1ce371 | |||
| 6d7cde4eb4 | |||
| 97cddda49e | |||
| 433afd36f5 | |||
| b873504b90 | |||
| 042ae5b87c | |||
| 1aa695cd78 | |||
|  | 58f4950652 | ||
|  | 604f0ea2f6 | ||
|  | 42c912f608 | ||
|  | 33dc1f51b5 | ||
| 13a8997789 | |||
| 9576f0903d | |||
| 34cf702b24 | |||
| 8a5e3a917c | |||
| 65bcf281d0 | |||
| cd0be8cb24 | |||
| 3d2a22a14d | |||
| a26adfb090 | |||
| f6e1a5b348 | |||
| c5a025d421 | |||
|  | 50d277d8d9 | ||
|  | 343f3e829f | ||
|  | f85b35314d | ||
|  | 3dc2e05d6e | ||
|  | 0cff8754d1 | ||
|  | afc8d3e524 | ||
|  | 692b44dac1 | ||
|  | 96ba42a297 | ||
| 7df940dc3e | |||
|  | f7b60004f3 | ||
| 8af8b047fd | |||
| 6592078fef | |||
| ad971ca07b | |||
| f2f16eb972 | |||
|  | b7d55f7dfb | ||
|  | 6e548a8ad5 | ||
|  | ee686a7d85 | ||
|  | 1c5b7a6be5 | ||
| a5dd4a9bab | |||
| ec232af851 | |||
| 17e30281e9 | |||
| 2854e601e6 | |||
| aee44dc694 | |||
| 75bbf6a0af | |||
| c65d23935a | |||
| 92cd797636 | |||
|  | 111bfbc6bc | ||
|  | f41a230b32 | ||
|  | c067051d5f | ||
|  | afdeb2b13c | ||
|  | 9e2ec2719b | ||
|  | 757a928f9a | ||
|  | bc248b6948 | ||
|  | ae8561892e | ||
|  | 32375aca65 | ||
|  | bb94ddd0eb | ||
| c2d78493c8 | |||
|  | 7f0fc0eff5 | ||
|  | 164d3691db | ||
|  | 791cb050c8 | ||
| d5e95bc350 | |||
| 6efac3a252 | |||
| 7a84906b5f | |||
| 07416e4567 | |||
| 66d832c733 | |||
| e74417ca12 | |||
| 7bd0084b5d | |||
|  | e8c3174ae2 | ||
|  | 9b066e94d0 | ||
|  | 618abdf302 | ||
|  | e1042aef77 | ||
|  | aa6a839c60 | ||
| ac99a56237 | |||
| b4d2af8c89 | |||
| 434af6aeaa | |||
| e90f8ac841 | |||
| a1705a8d53 | |||
| ca21003f01 | |||
| 14ddf2c234 | |||
|  | bca861e112 | ||
| 33d199a0ad | |||
|  | 93896ce59e | ||
|  | b1508e4124 | ||
|  | b820076b91 | ||
|  | 09f66100d3 | ||
|  | d7d92af09d | ||
|  | 460d0753a1 | ||
|  | 8f8058f8a5 | ||
|  | d97a27f483 | ||
|  | 7c3363b91e | ||
|  | b94478fa51 | ||
| 13bf0482e3 | |||
| a795b5705e | |||
| 392e064513 | |||
|  | b6a65059a2 | ||
|  | ea25a4d9ac | ||
|  | c190221fd3 | ||
|  | 0fcd2e7188 | ||
|  | 910b8dd6a1 | ||
|  | 75ebd3a0d1 | ||
| 7c8f79b147 | |||
|  | 09fd5c43a7 | ||
| 462921e549 | |||
|  | f22317748f | ||
|  | 6a9eae6b6b | ||
|  | fad96cf250 | ||
|  | f331809c27 | ||
| bd6a228af6 | |||
| 63d219498b | |||
|  | 2c54a53d0a | ||
|  | 306160ad9a | ||
|  | 20a091c3ed | ||
|  | 202078eb1b | ||
|  | a762b1fb71 | ||
|  | 5b5925b8e5 | ||
|  | b58adc6a4b | ||
|  | f9d5e95d72 | ||
|  | 4f8e636a43 | ||
|  | 9b39f35ae6 | ||
|  | 5fe2b85cbd | ||
|  | c7cccaaa69 | ||
|  | cbcfea466f | ||
|  | 4955672fc3 | ||
|  | 39f1c880b8 | ||
|  | 8c043da5b7 | ||
|  | 3cbe974eb4 | ||
| 997fd882ff | |||
|  | 7af9b87318 | ||
|  | 811ca45473 | ||
|  | bc1a4d40ba | ||
|  | c8079e6621 | ||
|  | 8b0d171c9a | ||
|  | 1f293b76b4 | ||
|  | 8bbd9ebc27 | ||
|  | 6472b431f0 | ||
|  | bd205a3293 | ||
|  | 496beffa88 | ||
|  | 9b63e97108 | ||
|  | 81f2aeaece | ||
|  | 2d4a45c758 | ||
|  | a123dcd7e9 | ||
|  | 6b27c42dfe | ||
|  | f7c2aa3ba5 | ||
|  | 0f182f033b | ||
|  | 7240d73184 | ||
|  | 42cd148f5e | ||
|  | 6e01264bb7 | ||
|  | 6f408256bc | ||
|  | 8d11681aac | ||
|  | 3d5c9a1ee9 | ||
|  | db749f103f | ||
|  | dc389e467c | ||
|  | 3619167d62 | ||
|  | 96f1d1b828 | ||
|  | 657e0a8f4d | ||
|  | 616e7cd83e | ||
|  | 6f26d2e8d4 | ||
|  | c014574504 | ||
|  | d7ce164e6e | ||
|  | c0d5b99016 | ||
|  | 09ca32d678 | ||
|  | 082ae350c6 | ||
|  | 611b5d74ba | ||
|  | b56c9ffa52 | ||
| cb02b7088f | |||
| 70c32fa49b | |||
| 77c8a94dae | |||
|  | 2e453dfbf5 | ||
|  | 4089984431 | ||
| 98439847cf | |||
|  | c78bbd0f8c | ||
| 7ea4b959a4 | |||
| 536e2ff073 | |||
| 798ff34d7e | |||
|  | 87acd06990 | ||
|  | 9353b6edfe | ||
|  | 167cc2650e | ||
|  | 34f887ca1c | ||
|  | 7089b6d5a5 | ||
|  | 2ba7d43ddd | ||
|  | 836e929565 | ||
|  | b6713ecb60 | ||
|  | 52a39f0fcd | ||
|  | 81a7a03076 | ||
|  | 16b37b956c | ||
|  | 567b6cf23f | ||
|  | 296396646d | ||
|  | 04a437c92c | ||
|  | 5c190a1b8c | ||
|  | 15d8f5c88c | ||
|  | c4ac6e7e8f | ||
|  | 510e340e16 | ||
|  | 6ffadca153 | ||
|  | b6597b74e7 | ||
| a034e9901b | |||
| d2573189d8 | |||
| 65ca174dbb | |||
|  | 0724f7af75 | ||
| 2e74520821 | |||
|  | 6dd75ad9e5 | ||
|  | fda408ee6f | ||
|  | b9c80318a2 | ||
|  | 5df5d52d41 | ||
|  | f76f281e58 | ||
|  | aa20cc8b52 | ||
|  | 0fd179fb33 | ||
|  | f45ef8d114 | ||
|  | 7422953e36 | ||
|  | 8535d433a7 | ||
|  | b573d1f35a | ||
|  | 0c1d7e4daf | ||
|  | 02e983a0cd | ||
|  | d15ab66aae | ||
|  | 9005b82c6d | ||
|  | 3475f45ce7 | ||
|  | 0744f38866 | ||
|  | 62febd2823 | ||
|  | fd5614738d | ||
|  | 005dcc51aa | ||
|  | 655c893f86 | ||
|  | 843f5783b4 | ||
|  | 8986c9fedd | ||
|  | c80a1d427c | ||
|  | ae57032500 | ||
|  | f75468728f | ||
|  | 5acd856663 | ||
|  | b0d3e4bb2c | ||
|  | b512ccbee6 | ||
|  | 8c89391c02 | ||
|  | bfac5195b8 | ||
|  | a782ca3238 | ||
|  | 744691097f | ||
|  | ff6da364e8 | ||
| 4d11a6f5f2 | |||
|  | 88be3b39bb | ||
|  | 8a02824e08 | ||
|  | 356e7940fd | ||
|  | 73ce476890 | ||
|  | 29c4ef41de | ||
|  | e423a09974 | ||
|  | 17097a93ec | ||
|  | 94a6373a7f | ||
|  | 4ab7dbfd57 | ||
|  | 90e70790f3 | ||
|  | 9c2e8d5e28 | ||
|  | 147e2025b9 | ||
| 573b8c6020 | |||
| 15218ec57f | |||
| ec68e08dd2 | |||
|  | fc25d2295c | ||
|  | 8dc2cfcedb | ||
| 17c843700e | |||
| 7b56f63a5c | |||
| b1cfb4d661 | |||
| 836f93780c | |||
|  | 5a68715be3 | ||
|  | 32bc7a6ab8 | ||
| b65e72e521 | |||
| d1aaff65e8 | |||
| 7ff7c7d90d | |||
| 93d29bb699 | |||
| a2e9430abe | |||
| 2485ef9c9c | |||
| 3b376ed54e | |||
| d5c1f614ba | |||
| 2edc24225d | |||
| 629283726b | |||
| 6adb66dd08 | |||
| 5be92bb708 | |||
| f4c049ea6d | |||
| bc092ad30f | |||
| dad642ed1b | |||
| 63ae39abc7 | |||
| 9e5b934d21 | |||
| a7b483d67a | |||
| bb99ce0680 | |||
| 83307df1af | |||
|  | 49b5c49851 | ||
| e9f30cab2c | |||
|  | 089f0ab582 | ||
|  | df6c9f55d1 | ||
|  | b93e18ed50 | ||
|  | 9c77bb69a5 | ||
|  | 27f3ecc833 | ||
|  | f9e90eeb1f | ||
|  | fad5c675eb | ||
|  | 4908b77d46 | ||
|  | f4dd5062d7 | ||
|  | da34d75841 | ||
|  | 980ff18956 | ||
|  | 7edf4c6c04 | ||
|  | 1a6c7204ac | ||
|  | 49310fbab3 | ||
|  | 6049d5ac47 | ||
|  | 35d0d35238 | ||
|  | c0e878705e | ||
|  | 5c0c8efb9e | ||
|  | dfd714e1ef | ||
|  | 79a8ca1a62 | ||
|  | fb45eb2eb2 | ||
|  | a307274c96 | ||
|  | 3f2c44a5fe | ||
|  | 48fb1cdc11 | ||
|  | 8a79e93cc2 | ||
|  | 3493b51879 | ||
|  | de3e79d300 | ||
|  | dd62a61c5c | ||
|  | 8f47d0b5ab | ||
|  | 42af132dab | ||
|  | 9db2c6525d | ||
|  | adbc7c1188 | ||
|  | 9dc345e8e8 | ||
|  | 8b9301a74c | ||
|  | 6f47fbb1e2 | ||
|  | a9ae30f868 | ||
|  | a3c0fb79b6 | ||
|  | 62601bb649 | ||
|  | ef97e32152 | ||
|  | daea5297ee | ||
|  | 5028969d4b | ||
|  | c667d9fdcc | ||
|  | 7dbb94bab2 | ||
|  | 236dcc820b | ||
|  | a42a441a6a | ||
|  | a0676beeb1 | ||
|  | c5106d0c03 | ||
|  | fbf96b1bbb | ||
|  | 3c49ddfaa4 | ||
|  | ffb8b3116c | ||
|  | 290493e162 | ||
|  | dd8cfff111 | ||
|  | 184642adb0 | ||
|  | 4774a3bcd2 | ||
|  | 25fafa9a89 | ||
|  | 713520d3d2 | ||
|  | 85ed8175cb | ||
|  | df5c788ef2 | ||
|  | 15f22425c8 | ||
|  | e87182cf98 | ||
|  | e3d5319470 | ||
|  | ffedeb1c58 | ||
|  | 3e3b367aa9 | ||
|  | 3e80947c2b | ||
|  | fdfbf11c6d | ||
|  | 9cb90f714e | ||
|  | 6ce174cd60 | ||
|  | 17ca5240f7 | ||
|  | 2daffdf95d | ||
|  | 149f826601 | ||
|  | cd8ee27080 | ||
|  | 0fa66e8f3c | ||
|  | 8dd099267d | ||
|  | 1a6d65c6a4 | ||
|  | fc4a043663 | ||
|  | 61ba50665e | ||
|  | bfe14000a9 | ||
|  | 092fa0d8da | ||
| e0b7004f96 | |||
|  | 1ceff48133 | ||
|  | 680645f849 | ||
|  | 3fc6e03ad1 | ||
|  | 2d6614f3a1 | ||
|  | 4e041b5103 | ||
|  | 712b9a3489 | ||
|  | bdaa5b1767 | ||
|  | 8fcefc021a | ||
|  | 1445189361 | ||
|  | 05c884a62a | ||
|  | a25bec87d9 | ||
|  | 2d8bb4c594 | ||
|  | 51cb2d4328 | ||
|  | 6d58cb2a68 | ||
|  | c8b35d960c | ||
|  | 532f41dd61 | ||
|  | 661b0ab45d | ||
|  | 565e9329ba | ||
|  | 4bc08ed995 | ||
|  | b2933a0557 | ||
|  | db057cc276 | ||
|  | 22e88eaf54 | ||
|  | 09fe3caebd | ||
|  | 5e02392f9c | ||
|  | 17a8f51a9b | ||
|  | 1b7f88dd00 | ||
| d6737e4bd8 | |||
| 75fc295f6e | |||
| d539888e57 | |||
|  | 86187d7cca | ||
|  | 87418e7df1 | ||
|  | 55f65b81b5 | ||
|  | d9408893b3 | ||
|  | 05acc22920 | ||
|  | 8ac021de73 | ||
|  | e503ef5590 | ||
|  | a7682b0060 | ||
| 0b731b5d80 | |||
| 8e2078be71 | |||
|  | d4c9d71fc8 | ||
|  | 786ca52c43 | ||
|  | 048ac04abc | ||
|  | f78d89bcbe | ||
|  | 53d06046b0 | ||
|  | 5d3a1a025d | ||
|  | 139cc5f1ae | ||
| 1826ed06a3 | |||
| 1c0e922585 | |||
| 9d5f693cbe | |||
| 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 | |||
|  | 339be37dba | ||
|  | a87b744621 | ||
| 97d0d56bcb | |||
| 7c7ea35ffb | |||
| 4b1cf580e0 | |||
| 179e82b5ca | |||
| f2c59c8730 | |||
| fdd0848593 | |||
| 92f666905f | |||
| 5980fa8640 | |||
| 2d8bb356e3 | |||
| a7251f28c7 | |||
| a0d8eb2c24 | |||
| 1e10b4571d | |||
| 02f8b84ac9 | |||
| cfd368596d | |||
|  | c1b1b89d17 | ||
|  | 771235017d | ||
| ae682674e0 | |||
| 17c43f49ac | |||
| 30146e977c | |||
| 54eacec261 | |||
| 76c78f04e2 | |||
| 379580cd89 | |||
| 14a80733f9 | |||
| d4db009a58 | |||
| 20ce7e0270 | |||
| bb195607ab | |||
| 6f090e22c0 | |||
| 339e983172 | |||
| 4a7f3d1b7b | |||
| c4e2202550 | |||
| 538b16610b | 
							
								
								
									
										45
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										45
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -5,11 +5,11 @@ | ||||
| *.o | ||||
| *.obj | ||||
|  | ||||
|  | ||||
| # Editor files # | ||||
| ################ | ||||
| *~ | ||||
| *# | ||||
| *.sublime-* | ||||
|  | ||||
| # Precompiled Headers # | ||||
| ####################### | ||||
| @@ -48,6 +48,9 @@ Config.h.in | ||||
| config.log | ||||
| config.status | ||||
| .deps | ||||
| Make.inc | ||||
| eigen.inc | ||||
| Eigen.inc | ||||
|  | ||||
| # http://www.gnu.org/software/autoconf # | ||||
| ######################################## | ||||
| @@ -62,19 +65,8 @@ stamp-h1 | ||||
| config.sub | ||||
| config.guess | ||||
| INSTALL | ||||
|  | ||||
| # Packages # | ||||
| ############ | ||||
| # it's better to unpack these files and commit the raw source | ||||
| # git has its own built in compression methods | ||||
| *.7z | ||||
| *.dmg | ||||
| *.gz | ||||
| *.iso | ||||
| *.jar | ||||
| *.rar | ||||
| *.tar | ||||
| *.zip | ||||
| .dirstamp | ||||
| ltmain.sh | ||||
|   | ||||
| # Logs and databases # | ||||
| ###################### | ||||
| @@ -100,3 +92,28 @@ build*/* | ||||
| ##################### | ||||
| *.xcodeproj/* | ||||
| build.sh | ||||
|  | ||||
| # Eigen source # | ||||
| ################ | ||||
| lib/Eigen/* | ||||
|  | ||||
| # FFTW source # | ||||
| ################ | ||||
| lib/fftw/* | ||||
|  | ||||
| # libtool macros # | ||||
| ################## | ||||
| m4/lt* | ||||
| m4/libtool.m4 | ||||
|  | ||||
| # Buck files # | ||||
| ############## | ||||
| .buck* | ||||
| buck-out | ||||
| BUCK | ||||
| make-bin-BUCK.sh | ||||
|  | ||||
| # generated sources # | ||||
| ##################### | ||||
| lib/qcd/spin/gamma-gen/*.h | ||||
| lib/qcd/spin/gamma-gen/*.cc | ||||
							
								
								
									
										51
									
								
								.travis.yml
									
									
									
									
									
								
							
							
						
						
									
										51
									
								
								.travis.yml
									
									
									
									
									
								
							| @@ -1,14 +1,14 @@ | ||||
| language: cpp | ||||
|  | ||||
| cache: | ||||
|   directories: | ||||
|     - clang | ||||
|  | ||||
| matrix: | ||||
|   include: | ||||
|     - os:        osx | ||||
|       osx_image: xcode7.2 | ||||
|       compiler: clang | ||||
|     - os:        osx | ||||
|       osx_image: xcode7.2 | ||||
|       compiler: gcc | ||||
|       env: VERSION=-5 | ||||
|     - compiler: gcc | ||||
|       addons: | ||||
|         apt: | ||||
| @@ -19,6 +19,8 @@ matrix: | ||||
|             - libmpfr-dev | ||||
|             - libgmp-dev | ||||
|             - libmpc-dev | ||||
|             - libopenmpi-dev | ||||
|             - openmpi-bin | ||||
|             - binutils-dev | ||||
|       env: VERSION=-4.9 | ||||
|     - compiler: gcc | ||||
| @@ -31,6 +33,8 @@ matrix: | ||||
|             - libmpfr-dev | ||||
|             - libgmp-dev | ||||
|             - libmpc-dev | ||||
|             - libopenmpi-dev | ||||
|             - openmpi-bin | ||||
|             - binutils-dev | ||||
|       env: VERSION=-5 | ||||
|     - compiler: clang | ||||
| @@ -38,42 +42,65 @@ matrix: | ||||
|         apt: | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-precise-3.7 | ||||
|           packages: | ||||
|             - clang-3.7 | ||||
|             - g++-4.8 | ||||
|             - libmpfr-dev | ||||
|             - libgmp-dev | ||||
|             - libmpc-dev | ||||
|             - libopenmpi-dev | ||||
|             - openmpi-bin | ||||
|             - binutils-dev | ||||
|       env: VERSION=-3.7 | ||||
|       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 | ||||
|       addons: | ||||
|         apt: | ||||
|           sources: | ||||
|             - ubuntu-toolchain-r-test | ||||
|             - llvm-toolchain-precise-3.8 | ||||
|           packages: | ||||
|             - clang-3.8 | ||||
|             - g++-4.8 | ||||
|             - libmpfr-dev | ||||
|             - libgmp-dev | ||||
|             - libmpc-dev | ||||
|             - libopenmpi-dev | ||||
|             - openmpi-bin | ||||
|             - binutils-dev | ||||
|       env: VERSION=-3.8 | ||||
|       env: CLANG_LINK=http://llvm.org/releases/3.7.0/clang+llvm-3.7.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz | ||||
|        | ||||
| before_install: | ||||
|     - export GRIDDIR=`pwd` | ||||
|     - if [[ "$TRAVIS_OS_NAME" == "linux" ]] && [[ "$CC" == "clang" ]] && [ ! -e clang/bin ]; then wget $CLANG_LINK; tar -xf `basename $CLANG_LINK`; mkdir clang; mv clang+*/* clang/; fi | ||||
|     - if [[ "$TRAVIS_OS_NAME" == "linux" ]] && [[ "$CC" == "clang" ]]; then export PATH="${GRIDDIR}/clang/bin:${PATH}"; fi | ||||
|     - 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 $CC | ||||
|     - $CC  --version | ||||
|     - which $CXX | ||||
|     - $CXX --version | ||||
|     - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then export LDFLAGS='-L/usr/local/lib'; fi | ||||
|      | ||||
| script: | ||||
|     - ./scripts/reconfigure_script | ||||
|     - ./bootstrap.sh | ||||
|     - mkdir build | ||||
|     - cd build | ||||
|     - ../configure CXXFLAGS="-msse4.2 -O3 -std=c++11" LIBS="-lmpfr -lgmp" --enable-precision=single --enable-simd=SSE4 --enable-comms=none | ||||
|     - ../configure --enable-precision=single --enable-simd=SSE4 --enable-comms=none | ||||
|     - make -j4  | ||||
|     - ./benchmarks/Benchmark_dwf --threads 1 | ||||
|     - echo make clean | ||||
|     - ../configure --enable-precision=double --enable-simd=SSE4 --enable-comms=none | ||||
|     - make -j4 | ||||
|     - ./benchmarks/Benchmark_dwf --threads 1 | ||||
|     - 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 | ||||
|  | ||||
|  | ||||
|   | ||||
							
								
								
									
										13
									
								
								Makefile.am
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								Makefile.am
									
									
									
									
									
								
							| @@ -1,5 +1,12 @@ | ||||
| # additional include paths necessary to compile the C++ library | ||||
| AM_CXXFLAGS = -I$(top_srcdir)/ | ||||
| SUBDIRS = lib tests benchmarks | ||||
| SUBDIRS = lib benchmarks tests extras | ||||
|  | ||||
| filelist: $(SUBDIRS) | ||||
| include $(top_srcdir)/doxygen.inc | ||||
|  | ||||
| tests: all | ||||
| 	$(MAKE) -C tests tests | ||||
|  | ||||
| .PHONY: tests doxygen-run doxygen-doc $(DX_PS_GOAL) $(DX_PDF_GOAL) | ||||
|  | ||||
| AM_CXXFLAGS += -I$(top_builddir)/include | ||||
| ACLOCAL_AMFLAGS = -I m4 | ||||
|   | ||||
							
								
								
									
										44
									
								
								README
									
									
									
									
									
								
							
							
						
						
									
										44
									
								
								README
									
									
									
									
									
								
							| @@ -1,44 +0,0 @@ | ||||
| This library provides data parallel C++ container classes with internal memory layout | ||||
| that is transformed to map efficiently to SIMD architectures. CSHIFT facilities | ||||
| are provided, similar to HPF and cmfortran, and user control is given over the mapping of | ||||
| array indices to both MPI tasks and SIMD processing elements. | ||||
|  | ||||
| * Identically shaped arrays then be processed with perfect data parallelisation. | ||||
| * Such identically shapped arrays are called conformable arrays. | ||||
|  | ||||
| The transformation is based on the observation that Cartesian array processing involves | ||||
| identical processing to be performed on different regions of the Cartesian array. | ||||
|  | ||||
| The library will (eventually) both geometrically decompose into MPI tasks and across SIMD lanes. | ||||
|  | ||||
| Data parallel array operations can then be specified with a SINGLE data parallel paradigm, but | ||||
| optimally use MPI, OpenMP and SIMD parallelism under the hood. This is a significant simplification | ||||
| for most programmers. | ||||
|  | ||||
| The layout transformations are parametrised by the SIMD vector length. This adapts according to the architecture. | ||||
| Presently SSE2 (128 bit) AVX, AVX2 (256 bit) and IMCI and AVX512 (512 bit) targets are supported. | ||||
|  | ||||
| These are presented as  | ||||
|  | ||||
|   vRealF, vRealD, vComplexF, vComplexD  | ||||
|  | ||||
| internal vector data types. These may be useful in themselves for other programmers. | ||||
| The corresponding scalar types are named | ||||
|  | ||||
|   RealF, RealD, ComplexF, ComplexD | ||||
|  | ||||
| MPI parallelism is UNIMPLEMENTED and for now only OpenMP and SIMD parallelism is present in the library. | ||||
|  | ||||
|    You can give `configure' initial values for configuration parameters | ||||
| by setting variables in the command line or in the environment.  Here | ||||
| is are examples: | ||||
|  | ||||
|      ./configure CXX=clang++ CXXFLAGS="-std=c++11 -O3 -msse4" --enable-simd=SSE4 | ||||
|  | ||||
|      ./configure CXX=clang++ CXXFLAGS="-std=c++11 -O3 -mavx" --enable-simd=AVX1 | ||||
|  | ||||
|      ./configure CXX=clang++ CXXFLAGS="-std=c++11 -O3 -mavx2" --enable-simd=AVX2 | ||||
|  | ||||
|      ./configure CXX=icpc CXXFLAGS="-std=c++11 -O3 -mmic" --enable-simd=AVX512 --host=none | ||||
|       | ||||
|       | ||||
							
								
								
									
										186
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										186
									
								
								README.md
									
									
									
									
									
								
							| @@ -1,15 +1,51 @@ | ||||
| # Grid [](https://travis-ci.org/paboyle/Grid) | ||||
| Data parallel C++ mathematical object library | ||||
| # Grid | ||||
| <table> | ||||
| <tr> | ||||
|     <td>Last stable release</td> | ||||
|     <td><a href="https://travis-ci.org/paboyle/Grid"> | ||||
|     <img src="https://travis-ci.org/paboyle/Grid.svg?branch=master"></a> | ||||
|     </td> | ||||
| </tr> | ||||
| <tr> | ||||
|     <td>Development branch</td> | ||||
|     <td><a href="https://travis-ci.org/paboyle/Grid"> | ||||
|     <img src="https://travis-ci.org/paboyle/Grid.svg?branch=develop"></a> | ||||
|     </td> | ||||
| </tr> | ||||
| </table> | ||||
|  | ||||
| Last update 2015/7/30 | ||||
| **Data parallel C++ mathematical object library.** | ||||
|  | ||||
| License: GPL v2. | ||||
|  | ||||
| Last update Nov 2016. | ||||
|  | ||||
| _Please do not send pull requests to the `master` branch which is reserved for releases._ | ||||
|  | ||||
| ### 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._ | ||||
|  | ||||
| When you file an issue, please go though the following checklist: | ||||
|  | ||||
| 1. Check that the code is pointing to the `HEAD` of `develop` or any commit in `master` which is tagged with a version number.  | ||||
| 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`. | ||||
| 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. | ||||
|  | ||||
|  | ||||
|  | ||||
| ### Description | ||||
| This library provides data parallel C++ container classes with internal memory layout | ||||
| that is transformed to map efficiently to SIMD architectures. CSHIFT facilities | ||||
| are provided, similar to HPF and cmfortran, and user control is given over the mapping of | ||||
| array indices to both MPI tasks and SIMD processing elements. | ||||
|  | ||||
| * Identically shaped arrays then be processed with perfect data parallelisation. | ||||
| * Such identically shapped arrays are called conformable arrays. | ||||
| * Such identically shaped arrays are called conformable arrays. | ||||
|  | ||||
| The transformation is based on the observation that Cartesian array processing involves | ||||
| identical processing to be performed on different regions of the Cartesian array. | ||||
| @@ -22,37 +58,139 @@ optimally use MPI, OpenMP and SIMD parallelism under the hood. This is a signifi | ||||
| for most programmers. | ||||
|  | ||||
| The layout transformations are parametrised by the SIMD vector length. This adapts according to the architecture. | ||||
| Presently SSE4 (128 bit) AVX, AVX2 (256 bit) and IMCI and AVX512 (512 bit) targets are supported (ARM NEON on the way). | ||||
| Presently SSE4 (128 bit) AVX, AVX2, QPX (256 bit), IMCI, and AVX512 (512 bit) targets are supported (ARM NEON on the way). | ||||
|  | ||||
| These are presented as  | ||||
|  | ||||
|      vRealF, vRealD, vComplexF, vComplexD  | ||||
|  | ||||
| internal vector data types. These may be useful in themselves for other programmers. | ||||
| The corresponding scalar types are named | ||||
|  | ||||
|      RealF, RealD, ComplexF, ComplexD | ||||
| These are presented as `vRealF`, `vRealD`, `vComplexF`, and `vComplexD` internal vector data types. These may be useful in themselves for other programmers. | ||||
| The corresponding scalar types are named `RealF`, `RealD`, `ComplexF` and `ComplexD`. | ||||
|  | ||||
| MPI, OpenMP, and SIMD parallelism are present in the library. | ||||
| Please see https://arxiv.org/abs/1512.03487 for more detail. | ||||
|  | ||||
|    You can give `configure' initial values for configuration parameters | ||||
| by setting variables in the command line or in the environment.  Here | ||||
| are examples: | ||||
| ### Quick start | ||||
| First, start by cloning the repository: | ||||
|  | ||||
|      ./configure CXX=clang++ CXXFLAGS="-std=c++11 -O3 -msse4" --enable-simd=SSE4 | ||||
| ``` bash | ||||
| git clone https://github.com/paboyle/Grid.git | ||||
| ``` | ||||
|  | ||||
|      ./configure CXX=clang++ CXXFLAGS="-std=c++11 -O3 -mavx" --enable-simd=AVX | ||||
| Then enter the cloned directory and set up the build system: | ||||
|  | ||||
|      ./configure CXX=clang++ CXXFLAGS="-std=c++11 -O3 -mavx2" --enable-simd=AVX2 | ||||
| ``` bash | ||||
| cd Grid | ||||
| ./bootstrap.sh | ||||
| ``` | ||||
|  | ||||
|      ./configure CXX=icpc CXXFLAGS="-std=c++11 -O3 -mmic" --enable-simd=AVX512 --host=none | ||||
| Now you can execute the `configure` script to generate makefiles (here from a build directory): | ||||
|  | ||||
| Note: Before running configure it could be necessary to execute the script  | ||||
| ``` bash | ||||
| mkdir build; cd build | ||||
| ../configure --enable-precision=double --enable-simd=AVX --enable-comms=mpi-auto --prefix=<path> | ||||
| ``` | ||||
|  | ||||
|        script/filelist | ||||
| where `--enable-precision=` set the default precision, | ||||
| `--enable-simd=` set the SIMD type, `--enable- | ||||
| comms=`, and `<path>` should be replaced by the prefix path where you want to | ||||
| install Grid. Other options are detailed in the next section, you can also use `configure | ||||
| --help` to display them. Like with any other program using GNU autotool, the | ||||
| `CXX`, `CXXFLAGS`, `LDFLAGS`, ... environment variables can be modified to | ||||
| customise the build. | ||||
|  | ||||
| Finally, you can build and install Grid: | ||||
|  | ||||
| ``` bash | ||||
| make; make install | ||||
| ``` | ||||
|  | ||||
| For developers: | ||||
| Use reconfigure_script in the scripts/ directory to create the autotools environment  | ||||
| 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: | ||||
|  | ||||
| ``` bash | ||||
| make -C tests/<subdir> tests | ||||
| ``` | ||||
| If you want to build all the tests at once just use `make tests`. | ||||
|  | ||||
| ### Build configuration options | ||||
|  | ||||
| - `--prefix=<path>`: installation prefix for Grid. | ||||
| - `--with-gmp=<path>`: look for GMP in the UNIX prefix `<path>` | ||||
| - `--with-mpfr=<path>`: look for MPFR in the UNIX prefix `<path>` | ||||
| - `--with-fftw=<path>`: look for FFTW in the UNIX prefix `<path>` | ||||
| - `--enable-lapack[=<path>]`: enable LAPACK support in Lanczos eigensolver. A UNIX prefix containing the library can be specified (optional). | ||||
| - `--enable-mkl[=<path>]`: use Intel MKL for FFT (and LAPACK if enabled) routines. A UNIX prefix containing the library can be specified (optional). | ||||
| - `--enable-numa`: enable NUMA first touch optimisation | ||||
| - `--enable-simd=<code>`: setup Grid for the SIMD target `<code>` (default: `GEN`). A list of possible SIMD targets is detailed in a section below. | ||||
| - `--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 `). | ||||
| - `--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`) | ||||
|  | ||||
| ### Possible communication interfaces | ||||
|  | ||||
| The following options can be use with the `--enable-comms=` option to target different communication interfaces: | ||||
|  | ||||
| | `<comm>`       | Description                                                   | | ||||
| | -------------- | ------------------------------------------------------------- | | ||||
| | `none`         | no communications                                             | | ||||
| | `mpi[-auto]`   | MPI communications                                            | | ||||
| | `mpi3[-auto]`  | MPI communications using MPI 3 shared memory                  | | ||||
| | `mpi3l[-auto]` | MPI communications using MPI 3 shared memory and leader model | | ||||
| | `shmem `       | Cray SHMEM communications                                     | | ||||
|  | ||||
| For the MPI interfaces the optional `-auto` suffix instructs the `configure` scripts to determine all the necessary compilation and linking flags. This is done by extracting the informations from the MPI wrapper specified in the environment variable `MPICXX` (if not specified `configure` will scan though a list of default names). The `-auto` suffix is not supported by the Cray environment wrapper scripts. Use the standard versions instead.   | ||||
|  | ||||
| ### Possible SIMD types | ||||
|  | ||||
| The following options can be use with the `--enable-simd=` option to target different SIMD instruction sets: | ||||
|  | ||||
| | `<code>`    | Description                            | | ||||
| | ----------- | -------------------------------------- | | ||||
| | `GEN`       | generic portable vector code           | | ||||
| | `SSE4`      | SSE 4.2 (128 bit)                      | | ||||
| | `AVX`       | AVX (256 bit)                          | | ||||
| | `AVXFMA`    | AVX (256 bit) + FMA                    | | ||||
| | `AVXFMA4`   | AVX (256 bit) + FMA4                   | | ||||
| | `AVX2`      | AVX 2 (256 bit)                        | | ||||
| | `AVX512`    | AVX 512 bit                            | | ||||
| | `QPX`       | QPX (256 bit)                          | | ||||
|  | ||||
| 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                            | | ||||
|  | ||||
| #### Notes: | ||||
| - We currently support AVX512 only for the Intel compiler. Support for GCC and clang will appear in future versions of Grid when the AVX512 support within GCC and clang will be more advanced. | ||||
| - For BG/Q only [bgclang](http://trac.alcf.anl.gov/projects/llvm-bgq) is supported. We do not presently plan to support more compilers for this platform. | ||||
| - BG/Q performances are currently rather poor. This is being investigated for future versions. | ||||
| - The vector size for the `GEN` target can be specified with the `configure` script option `--enable-gen-simd-width`. | ||||
|  | ||||
| ### Build setup for Intel Knights Landing platform | ||||
|  | ||||
| The following configuration is recommended for the Intel Knights Landing platform: | ||||
|  | ||||
| ``` bash | ||||
| ../configure --enable-precision=double\ | ||||
|              --enable-simd=KNL        \ | ||||
|              --enable-comms=mpi-auto \ | ||||
|              --with-gmp=<path>        \ | ||||
|              --with-mpfr=<path>       \ | ||||
|              --enable-mkl             \ | ||||
|              CXX=icpc MPICXX=mpiicpc | ||||
| ``` | ||||
|  | ||||
| where `<path>` is the UNIX prefix where GMP and MPFR are installed. If you are working on a Cray machine that does not use the `mpiicpc` wrapper, please use: | ||||
|  | ||||
| ``` bash | ||||
| ../configure --enable-precision=double\ | ||||
|              --enable-simd=KNL        \ | ||||
|              --enable-comms=mpi       \ | ||||
|              --with-gmp=<path>        \ | ||||
|              --with-mpfr=<path>       \ | ||||
|              --enable-mkl             \ | ||||
|              CXX=CC CC=cc | ||||
| ``` | ||||
							
								
								
									
										6
									
								
								VERSION
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								VERSION
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| Version : 0.6.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 | ||||
| @@ -25,7 +25,7 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk> | ||||
|     See the full license in the file "LICENSE" in the top level distribution directory | ||||
|     *************************************************************************************/ | ||||
|     /*  END LEGAL */ | ||||
| #include <Grid.h> | ||||
| #include <Grid/Grid.h> | ||||
|  | ||||
| using namespace std; | ||||
| using namespace Grid; | ||||
| @@ -42,16 +42,15 @@ int main (int argc, char ** argv) | ||||
|  | ||||
|   int Nloop=10; | ||||
|   int nmu=0; | ||||
|   for(int mu=0;mu<4;mu++) if (mpi_layout[mu]>1) nmu++; | ||||
|   for(int mu=0;mu<Nd;mu++) if (mpi_layout[mu]>1) nmu++; | ||||
|  | ||||
|   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; | ||||
|  | ||||
|  | ||||
|  | ||||
|   for(int lat=4;lat<=32;lat+=2){ | ||||
|     for(int Ls=1;Ls<=16;Ls*=2){ | ||||
|   int maxlat=24; | ||||
|   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], | ||||
| @@ -125,8 +124,8 @@ int main (int argc, char ** argv) | ||||
|   std::cout<<GridLogMessage << "  L  "<<"\t\t"<<" Ls  "<<"\t\t"<<"bytes"<<"\t\t"<<"MB/s uni"<<"\t\t"<<"MB/s bidi"<<std::endl; | ||||
|  | ||||
|  | ||||
|   for(int lat=4;lat<=32;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}); | ||||
|  | ||||
| @@ -195,6 +194,168 @@ int main (int argc, char ** argv) | ||||
|   }   | ||||
|  | ||||
|  | ||||
|   Nloop=10; | ||||
|   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; | ||||
|  | ||||
|   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], | ||||
|       				    lat*mpi_layout[2], | ||||
|       				    lat*mpi_layout[3]}); | ||||
|  | ||||
|       GridCartesian     Grid(latt_size,simd_layout,mpi_layout); | ||||
|  | ||||
|       std::vector<HalfSpinColourVectorD *> xbuf(8); | ||||
|       std::vector<HalfSpinColourVectorD *> rbuf(8); | ||||
|       Grid.ShmBufferFreeAll(); | ||||
|       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)); | ||||
|       } | ||||
|  | ||||
|       int ncomm; | ||||
|       int bytes=lat*lat*lat*Ls*sizeof(HalfSpinColourVectorD); | ||||
|  | ||||
|       double start=usecond(); | ||||
|       for(int i=0;i<Nloop;i++){ | ||||
|  | ||||
| 	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); | ||||
| 	 | ||||
| 	    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); | ||||
| 	   | ||||
| 	  } | ||||
| 	} | ||||
| 	Grid.StencilSendToRecvFromComplete(requests); | ||||
| 	Grid.Barrier(); | ||||
|  | ||||
|       } | ||||
|       double stop=usecond(); | ||||
|  | ||||
|       double dbytes    = bytes; | ||||
|       double xbytes    = Nloop*dbytes*2.0*ncomm; | ||||
|       double rbytes    = xbytes; | ||||
|       double bidibytes = xbytes+rbytes; | ||||
|  | ||||
|       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; | ||||
|  | ||||
|   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], | ||||
|       				    lat*mpi_layout[2], | ||||
|       				    lat*mpi_layout[3]}); | ||||
|  | ||||
|       GridCartesian     Grid(latt_size,simd_layout,mpi_layout); | ||||
|  | ||||
|       std::vector<HalfSpinColourVectorD *> xbuf(8); | ||||
|       std::vector<HalfSpinColourVectorD *> rbuf(8); | ||||
|       Grid.ShmBufferFreeAll(); | ||||
|       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)); | ||||
|       } | ||||
|  | ||||
|       int ncomm; | ||||
|       int bytes=lat*lat*lat*Ls*sizeof(HalfSpinColourVectorD); | ||||
|  | ||||
|       double start=usecond(); | ||||
|       for(int i=0;i<Nloop;i++){ | ||||
|  | ||||
| 	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); | ||||
| 	    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); | ||||
| 	    Grid.StencilSendToRecvFromComplete(requests); | ||||
| 	    requests.resize(0); | ||||
| 	   | ||||
| 	  } | ||||
| 	} | ||||
| 	Grid.Barrier(); | ||||
|  | ||||
|       } | ||||
|       double stop=usecond(); | ||||
|  | ||||
|       double dbytes    = bytes; | ||||
|       double xbytes    = Nloop*dbytes*2.0*ncomm; | ||||
|       double rbytes    = xbytes; | ||||
|       double bidibytes = xbytes+rbytes; | ||||
|  | ||||
|       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; | ||||
|     } | ||||
|   }     | ||||
|  | ||||
|   Grid_finalize(); | ||||
| } | ||||
|   | ||||
| @@ -26,7 +26,7 @@ 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> | ||||
| #include <Grid/Grid.h> | ||||
|  | ||||
| using namespace std; | ||||
| using namespace Grid; | ||||
| @@ -37,64 +37,100 @@ 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; | ||||
| typedef WilsonFermion5D<DomainWallVec5dImplR> WilsonFermion5DR; | ||||
| typedef WilsonFermion5D<DomainWallVec5dImplF> WilsonFermion5DF; | ||||
| typedef WilsonFermion5D<DomainWallVec5dImplD> WilsonFermion5DD; | ||||
|  | ||||
| int main (int argc, char ** argv) | ||||
| { | ||||
|   Grid_init(&argc,&argv); | ||||
|  | ||||
|   if( GridCmdOptionExists(argv,argv+argc,"--asynch") ){ | ||||
|     overlapComms = true; | ||||
|   } | ||||
|  | ||||
|   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); | ||||
|   GridRedBlackCartesian * FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls,UGrid); | ||||
|  | ||||
|   std::cout << GridLogMessage << "Making s innermost grids"<<std::endl; | ||||
|   GridCartesian         * sUGrid   = SpaceTimeGrid::makeFourDimDWFGrid(GridDefaultLatt(),GridDefaultMpi()); | ||||
|   GridRedBlackCartesian * sUrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(sUGrid); | ||||
|   GridCartesian         * sFGrid   = SpaceTimeGrid::makeFiveDimDWFGrid(Ls,UGrid); | ||||
|   GridRedBlackCartesian * sFrbGrid = SpaceTimeGrid::makeFiveDimDWFRedBlackGrid(Ls,UGrid); | ||||
|  | ||||
|   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); | ||||
|  | ||||
|   ColourMatrix cm = Complex(1.0,0.0); | ||||
|  | ||||
|   LatticeGaugeField Umu(UGrid); random(RNG4,Umu); | ||||
|   LatticeGaugeField Umu5d(FGrid);  | ||||
|   std::cout << GridLogMessage << "Drawing gauge field" << std::endl; | ||||
|   LatticeGaugeField Umu(UGrid);  | ||||
|   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) | ||||
|   { | ||||
| @@ -114,43 +150,208 @@ int main (int argc, char ** argv) | ||||
|   RealD mass=0.1; | ||||
|   RealD M5  =1.8; | ||||
|  | ||||
|   typename DomainWallFermionR::ImplParams params;  | ||||
|   params.overlapCommsCompute = overlapComms; | ||||
|    | ||||
|   RealD NP = UGrid->_Nprocessors; | ||||
|  | ||||
|   DomainWallFermionR Dw(Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5,params); | ||||
|   std::cout << GridLogMessage << "Creating action operator " << std::endl; | ||||
|   DomainWallFermionR Dw(Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5); | ||||
|  | ||||
|   std::cout<<GridLogMessage << "Calling Dw"<<std::endl; | ||||
|   int ncall=100; | ||||
|   { | ||||
|   std::cout << GridLogMessage<< "*****************************************************************" <<std::endl; | ||||
|   std::cout << GridLogMessage<< "* Kernel options --dslash-generic, --dslash-unroll, --dslash-asm" <<std::endl; | ||||
|   std::cout << GridLogMessage<< "*****************************************************************" <<std::endl; | ||||
|   std::cout << GridLogMessage<< "*****************************************************************" <<std::endl; | ||||
|   std::cout << GridLogMessage<< "* Benchmarking DomainWallFermionR::Dhop                  "<<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; | ||||
|   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 =1000; | ||||
|   if (1) { | ||||
|     FGrid->Barrier(); | ||||
|     Dw.ZeroCounters(); | ||||
|     Dw.Dhop(src,result,0); | ||||
|     double t0=usecond(); | ||||
|     for(int i=0;i<ncall;i++){ | ||||
|       __SSC_START; | ||||
|       Dw.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 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 node =  "<< flops/(t1-t0)/NP<<std::endl; | ||||
|     std::cout<<GridLogMessage << "mflop/s per rank =  "<< flops/(t1-t0)/NP<<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(); | ||||
|   } | ||||
|  | ||||
|   exit(0); | ||||
|   if (1) | ||||
|   { | ||||
|  | ||||
|     std::cout << GridLogMessage<< "*********************************************************" <<std::endl; | ||||
|     std::cout << GridLogMessage<< "* Benchmarking WilsonFermion5D<DomainWallVec5dImplR>::Dhop "<<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; | ||||
|  | ||||
|     typedef WilsonFermion5D<DomainWallVec5dImplR> WilsonFermion5DR; | ||||
|     LatticeFermion ssrc(sFGrid); | ||||
|     LatticeFermion sref(sFGrid); | ||||
|     LatticeFermion sresult(sFGrid); | ||||
|  | ||||
|     WilsonFermion5DR sDw(Umu,*sFGrid,*sFrbGrid,*sUGrid,*sUrbGrid,M5); | ||||
|  | ||||
|     localConvert(src,ssrc); | ||||
|     std::cout<<GridLogMessage<< "src norms "<< norm2(src)<<" " <<norm2(ssrc)<<std::endl; | ||||
|     FGrid->Barrier(); | ||||
|     sDw.Dhop(ssrc,sresult,0); | ||||
|     sDw.ZeroCounters(); | ||||
|     double t0=usecond(); | ||||
|     for(int i=0;i<ncall;i++){ | ||||
|       __SSC_START; | ||||
|       sDw.Dhop(ssrc,sresult,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 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<< "res norms "<< norm2(result)<<" " <<norm2(sresult)<<std::endl; | ||||
|     sDw.Report(); | ||||
|     RealD sum=0; | ||||
|  | ||||
|     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); | ||||
|  | ||||
|     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; | ||||
|       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); | ||||
|       LatticeFermion sr_o   (sFrbGrid); | ||||
|  | ||||
|       pickCheckerboard(Even,ssrc_e,ssrc); | ||||
|       pickCheckerboard(Odd,ssrc_o,ssrc); | ||||
|       //      setCheckerboard(sr_eo,ssrc_o); | ||||
|       //      setCheckerboard(sr_eo,ssrc_e); | ||||
|  | ||||
|       sr_e = zero; | ||||
|       sr_o = zero; | ||||
|  | ||||
|       FGrid->Barrier(); | ||||
|       sDw.DhopEO(ssrc_o, sr_e, DaggerNo); | ||||
|       sDw.ZeroCounters(); | ||||
|       //      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(); | ||||
|  | ||||
|       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; | ||||
|       sDw.Report(); | ||||
|  | ||||
|       sDw.DhopEO(ssrc_o,sr_e,DaggerNo); | ||||
|       sDw.DhopOE(ssrc_e,sr_o,DaggerNo); | ||||
|       sDw.Dhop  (ssrc  ,sresult,DaggerNo); | ||||
|  | ||||
|       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; | ||||
|       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) ) {  | ||||
| 	setCheckerboard(ssrc,ssrc_o); | ||||
| 	setCheckerboard(ssrc,ssrc_e); | ||||
| 	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) | ||||
|   { // Naive wilson dag 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,1); | ||||
|       for(int i=0;i<ref._odata.size();i++){ | ||||
| 	ref._odata[i]+= tmp._odata[i] + Gamma(Gmu[mu])*tmp._odata[i]; ; | ||||
| @@ -164,13 +365,19 @@ int main (int argc, char ** argv) | ||||
|     } | ||||
|     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; | ||||
|  | ||||
|   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); | ||||
| @@ -178,25 +385,44 @@ int main (int argc, char ** argv) | ||||
|   LatticeFermion r_eo  (FGrid); | ||||
|  | ||||
|  | ||||
|   std::cout<<GridLogMessage << "Calling Deo and Doe"<<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. | ||||
|   static int Opt;  // these are a temporary hack | ||||
|   static int Comms;  // these are a temporary hack | ||||
|  | ||||
|   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; | ||||
|   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; | ||||
|   { | ||||
|     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); | ||||
|     } | ||||
|     double t1=usecond(); | ||||
|     FGrid->Barrier(); | ||||
|      | ||||
|     double volume=Ls;  for(int mu=0;mu<Nd;mu++) volume=volume*latt4[mu]; | ||||
|     double flops=(1344.0*volume*ncall)/2; | ||||
|  | ||||
|     std::cout<<GridLogMessage << "Deo mflop/s =   "<< flops/(t1-t0)<<std::endl; | ||||
|     std::cout<<GridLogMessage << "Deo mflop/s per node   "<< flops/(t1-t0)/NP<<std::endl; | ||||
|     std::cout<<GridLogMessage << "Deo mflop/s per rank   "<< flops/(t1-t0)/NP<<std::endl; | ||||
|     Dw.Report(); | ||||
|   } | ||||
|   Dw.DhopEO(src_o,r_e,DaggerNo); | ||||
|   Dw.DhopOE(src_e,r_o,DaggerNo); | ||||
| @@ -211,11 +437,19 @@ int main (int argc, char ** argv) | ||||
|  | ||||
|   err = r_eo-result;  | ||||
|   std::cout<<GridLogMessage << "norm diff   "<< norm2(err)<<std::endl; | ||||
|   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); | ||||
|  | ||||
|   Grid_finalize(); | ||||
| } | ||||
|   | ||||
							
								
								
									
										366
									
								
								benchmarks/Benchmark_dwf_sweep.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										366
									
								
								benchmarks/Benchmark_dwf_sweep.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,366 @@ | ||||
|     /************************************************************************************* | ||||
|  | ||||
|     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> | ||||
|  | ||||
|     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; | ||||
|  | ||||
| template<class d> | ||||
| struct scal { | ||||
|   d internal; | ||||
| }; | ||||
|  | ||||
|   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 ); | ||||
| void benchsDw(std::vector<int> & L, int Ls, int threads, int report=0 ); | ||||
|  | ||||
| int main (int argc, char ** argv) | ||||
| { | ||||
|   Grid_init(&argc,&argv); | ||||
|  | ||||
|   std::cout << GridLogMessage<< "*****************************************************************" <<std::endl; | ||||
|   std::cout << GridLogMessage<< "* Kernel options --dslash-generic, --dslash-unroll, --dslash-asm" <<std::endl; | ||||
|   std::cout << GridLogMessage<< "*****************************************************************" <<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; | ||||
|  | ||||
|   const int Ls=8; | ||||
|   int threads = GridThread::GetThreads(); | ||||
|   std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl; | ||||
|   std::cout<<GridLogMessage << "=========================================================================="<<std::endl; | ||||
|   std::cout<<GridLogMessage << "= Benchmarking DWF"<<std::endl; | ||||
|   std::cout<<GridLogMessage << "=========================================================================="<<std::endl; | ||||
|   std::cout<<GridLogMessage << "Volume \t\t\tProcs \t Dw \t eoDw \t sDw \t eosDw (Mflop/s)  "<<std::endl; | ||||
|   std::cout<<GridLogMessage << "=========================================================================="<<std::endl; | ||||
|  | ||||
|   int Lmax=16; | ||||
|   int dmin=2; | ||||
|   if ( getenv("LMAX") ) Lmax=atoi(getenv("LMAX")); | ||||
|   if ( getenv("DMIN") ) dmin=atoi(getenv("DMIN")); | ||||
|   for (int L=8;L<=Lmax;L*=2){ | ||||
|     std::vector<int> latt4(4,L); | ||||
|     for(int d=4;d>dmin;d--){ | ||||
|       if ( d<=3 ) latt4[d]*=2; | ||||
|       std::cout << GridLogMessage <<"\t"; | ||||
|       for(int d=0;d<Nd;d++){ | ||||
| 	std::cout<<latt4[d]<<"x"; | ||||
|       } | ||||
|       std::cout <<Ls<<"\t" ; | ||||
|       benchDw (latt4,Ls,threads,0); | ||||
|       benchsDw(latt4,Ls,threads,0); | ||||
|       std::cout<<std::endl; | ||||
|     } | ||||
|   } | ||||
|   std::cout<<GridLogMessage << "=========================================================================="<<std::endl; | ||||
|   { | ||||
|     std::vector<int> latt4(4,16); | ||||
|     std::cout<<GridLogMessage << "16^4 Dw miss rate"<<std::endl; | ||||
|     benchDw (latt4,Ls,threads,1); | ||||
|     std::cout<<GridLogMessage << "16^4 sDw miss rate"<<std::endl; | ||||
|     benchsDw(latt4,Ls,threads,1); | ||||
|   } | ||||
|  | ||||
|   Grid_finalize(); | ||||
| } | ||||
|  | ||||
| #undef CHECK | ||||
|  | ||||
| void benchDw(std::vector<int> & latt4, int Ls, int threads,int report ) | ||||
| { | ||||
|   GridCartesian         * UGrid   = SpaceTimeGrid::makeFourDimGrid(latt4, GridDefaultSimd(Nd,vComplex::Nsimd()),GridDefaultMpi()); | ||||
|   GridRedBlackCartesian * UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid); | ||||
|   GridCartesian         * FGrid   = SpaceTimeGrid::makeFiveDimGrid(Ls,UGrid); | ||||
|   GridRedBlackCartesian * FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls,UGrid); | ||||
|  | ||||
|   std::vector<int> seeds4({1,2,3,4}); | ||||
|   std::vector<int> seeds5({5,6,7,8}); | ||||
|  | ||||
| #ifdef CHECK  | ||||
|   GridParallelRNG          RNG4(UGrid);  RNG4.SeedFixedIntegers(seeds4); | ||||
|   GridParallelRNG          RNG5(FGrid);  RNG5.SeedFixedIntegers(seeds5); | ||||
|   LatticeFermion src   (FGrid); random(RNG5,src); | ||||
|   LatticeGaugeField Umu(UGrid);  | ||||
|   random(RNG4,Umu); | ||||
| #else  | ||||
|   LatticeFermion src   (FGrid); src=zero; | ||||
|   LatticeGaugeField Umu(UGrid); Umu=zero; | ||||
| #endif | ||||
|  | ||||
|   LatticeFermion result(FGrid); result=zero; | ||||
|   LatticeFermion    ref(FGrid);    ref=zero; | ||||
|   LatticeFermion    tmp(FGrid); | ||||
|   LatticeFermion    err(FGrid); | ||||
|  | ||||
|   ColourMatrix cm = Complex(1.0,0.0); | ||||
|  | ||||
|   LatticeGaugeField Umu5d(FGrid);  | ||||
|  | ||||
|   // replicate across fifth dimension | ||||
|   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); | ||||
|   } | ||||
|  | ||||
| #ifdef CHECK | ||||
|   if (1) { | ||||
|  | ||||
|     ref = zero; | ||||
|     for(int mu=0;mu<Nd;mu++){ | ||||
|       tmp = U[mu]*Cshift(src,mu+1,1); | ||||
|       ref=ref + tmp - Gamma(Gmu[mu])*tmp; | ||||
|  | ||||
|       tmp =adj(U[mu])*src; | ||||
|       tmp =Cshift(tmp,mu+1,-1); | ||||
|       ref=ref + tmp + Gamma(Gmu[mu])*tmp; | ||||
|     } | ||||
|     ref = -0.5*ref; | ||||
|   } | ||||
| #endif | ||||
|  | ||||
|   RealD mass=0.1; | ||||
|   RealD M5  =1.8; | ||||
|   RealD NP = UGrid->_Nprocessors; | ||||
|  | ||||
|   DomainWallFermionR Dw(Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5); | ||||
|    | ||||
|   double t0=usecond(); | ||||
|   Dw.Dhop(src,result,0); | ||||
|   double t1=usecond(); | ||||
|  | ||||
| #ifdef TIMERS_OFF | ||||
|     int ncall =10; | ||||
| #else | ||||
|   int ncall =1+(int) ((5.0*1000*1000)/(t1-t0)); | ||||
| #endif | ||||
|  | ||||
|   if (ncall < 5 ) exit(0); | ||||
|  | ||||
|   Dw.Dhop(src,result,0); | ||||
|  | ||||
|   PerformanceCounter Counter(8); | ||||
|   Counter.Start(); | ||||
|   t0=usecond(); | ||||
|   for(int i=0;i<ncall;i++){ | ||||
|     Dw.Dhop(src,result,0); | ||||
|   } | ||||
|   t1=usecond(); | ||||
|   Counter.Stop(); | ||||
|   if ( report ) { | ||||
|     Counter.Report(); | ||||
|   } | ||||
|    | ||||
|   if ( ! report ) { | ||||
|     double volume=Ls;  for(int mu=0;mu<Nd;mu++) volume=volume*latt4[mu]; | ||||
|     double flops=1344*volume*ncall; | ||||
|     std::cout <<"\t"<<NP<< "\t"<<flops/(t1-t0)<< "\t"; | ||||
|   } | ||||
|    | ||||
| #ifdef CHECK | ||||
|   err = ref-result;  | ||||
|   RealD errd = norm2(err); | ||||
|   if ( errd> 1.0e-4 ) { | ||||
|     std::cout<<GridLogMessage << "oops !!! norm diff   "<< norm2(err)<<std::endl; | ||||
|     exit(-1); | ||||
|   } | ||||
| #endif | ||||
|      | ||||
|   LatticeFermion src_e (FrbGrid); | ||||
|   LatticeFermion src_o (FrbGrid); | ||||
|   LatticeFermion r_e   (FrbGrid); | ||||
|   LatticeFermion r_o   (FrbGrid); | ||||
|   LatticeFermion r_eo  (FGrid); | ||||
|    | ||||
|   pickCheckerboard(Even,src_e,src); | ||||
|   pickCheckerboard(Odd,src_o,src); | ||||
|    | ||||
|   { | ||||
|     Dw.DhopEO(src_o,r_e,DaggerNo); | ||||
|     double t0=usecond(); | ||||
|     for(int i=0;i<ncall;i++){ | ||||
|       Dw.DhopEO(src_o,r_e,DaggerNo); | ||||
|     } | ||||
|     double t1=usecond(); | ||||
|      | ||||
|     if(!report){ | ||||
|       double volume=Ls;  for(int mu=0;mu<Nd;mu++) volume=volume*latt4[mu]; | ||||
|       double flops=(1344.0*volume*ncall)/2; | ||||
|       std::cout<< flops/(t1-t0); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| #define CHECK_SDW | ||||
| void benchsDw(std::vector<int> & latt4, int Ls, int threads, int report ) | ||||
| { | ||||
|  | ||||
|   GridCartesian         * UGrid   = SpaceTimeGrid::makeFourDimGrid(latt4, GridDefaultSimd(Nd,vComplex::Nsimd()),GridDefaultMpi()); | ||||
|   GridRedBlackCartesian * UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid); | ||||
|   GridCartesian         * FGrid   = SpaceTimeGrid::makeFiveDimGrid(Ls,UGrid); | ||||
|   GridRedBlackCartesian * FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls,UGrid); | ||||
|  | ||||
|   GridCartesian         * sUGrid   = SpaceTimeGrid::makeFourDimDWFGrid(latt4,GridDefaultMpi()); | ||||
|   GridRedBlackCartesian * sUrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(sUGrid); | ||||
|   GridCartesian         * sFGrid   = SpaceTimeGrid::makeFiveDimDWFGrid(Ls,UGrid); | ||||
|   GridRedBlackCartesian * sFrbGrid = SpaceTimeGrid::makeFiveDimDWFRedBlackGrid(Ls,UGrid); | ||||
|  | ||||
|   std::vector<int> seeds4({1,2,3,4}); | ||||
|   std::vector<int> seeds5({5,6,7,8}); | ||||
|  | ||||
| #ifdef CHECK_SDW | ||||
|   GridParallelRNG          RNG4(UGrid);  RNG4.SeedFixedIntegers(seeds4); | ||||
|   GridParallelRNG          RNG5(FGrid);  RNG5.SeedFixedIntegers(seeds5); | ||||
|   LatticeFermion src   (FGrid); random(RNG5,src); | ||||
|   LatticeGaugeField Umu(UGrid);  | ||||
|   random(RNG4,Umu); | ||||
| #else  | ||||
|   LatticeFermion src   (FGrid); src=zero; | ||||
|   LatticeGaugeField Umu(UGrid); Umu=zero; | ||||
| #endif | ||||
|  | ||||
|   LatticeFermion result(FGrid); result=zero; | ||||
|   LatticeFermion    ref(FGrid);    ref=zero; | ||||
|   LatticeFermion    tmp(FGrid); | ||||
|   LatticeFermion    err(FGrid); | ||||
|  | ||||
|   ColourMatrix cm = Complex(1.0,0.0); | ||||
|  | ||||
|   LatticeGaugeField Umu5d(FGrid);  | ||||
|  | ||||
|   // replicate across fifth dimension | ||||
|   for(int ss=0;ss<Umu._grid->oSites();ss++){ | ||||
|     for(int s=0;s<Ls;s++){ | ||||
|       Umu5d._odata[Ls*ss+s] = Umu._odata[ss]; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   RealD mass=0.1; | ||||
|   RealD M5  =1.8; | ||||
|  | ||||
|   typedef WilsonFermion5D<DomainWallVec5dImplR> WilsonFermion5DR; | ||||
|   LatticeFermion ssrc(sFGrid); | ||||
|   LatticeFermion sref(sFGrid); | ||||
|   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); | ||||
|   }}}}} | ||||
|  | ||||
|   double t0=usecond(); | ||||
|   sDw.Dhop(ssrc,sresult,0); | ||||
|   double t1=usecond(); | ||||
|  | ||||
| #ifdef TIMERS_OFF | ||||
|   int ncall =10; | ||||
| #else  | ||||
|   int ncall =1+(int) ((5.0*1000*1000)/(t1-t0)); | ||||
| #endif | ||||
|  | ||||
|   PerformanceCounter Counter(8); | ||||
|   Counter.Start(); | ||||
|   t0=usecond(); | ||||
|   for(int i=0;i<ncall;i++){ | ||||
|     sDw.Dhop(ssrc,sresult,0); | ||||
|   } | ||||
|   t1=usecond(); | ||||
|   Counter.Stop(); | ||||
|    | ||||
|   if ( report ) { | ||||
|     Counter.Report(); | ||||
|   } else {  | ||||
|     double volume=Ls;  for(int mu=0;mu<Nd;mu++) volume=volume*latt4[mu]; | ||||
|     double flops=1344*volume*ncall; | ||||
|     std::cout<<"\t"<< flops/(t1-t0); | ||||
|   } | ||||
|  | ||||
|   LatticeFermion sr_eo(sFGrid); | ||||
|   LatticeFermion serr(sFGrid); | ||||
|    | ||||
|   LatticeFermion ssrc_e (sFrbGrid); | ||||
|   LatticeFermion ssrc_o (sFrbGrid); | ||||
|   LatticeFermion sr_e   (sFrbGrid); | ||||
|   LatticeFermion sr_o   (sFrbGrid); | ||||
|        | ||||
|   pickCheckerboard(Even,ssrc_e,ssrc); | ||||
|   pickCheckerboard(Odd,ssrc_o,ssrc); | ||||
|    | ||||
|   setCheckerboard(sr_eo,ssrc_o); | ||||
|   setCheckerboard(sr_eo,ssrc_e); | ||||
|      | ||||
|   sr_e = zero; | ||||
|   sr_o = zero; | ||||
|    | ||||
|   sDw.DhopEO(ssrc_o,sr_e,DaggerNo); | ||||
|   PerformanceCounter CounterSdw(8); | ||||
|   CounterSdw.Start(); | ||||
|   t0=usecond(); | ||||
|   for(int i=0;i<ncall;i++){ | ||||
|     __SSC_START; | ||||
|     sDw.DhopEO(ssrc_o,sr_e,DaggerNo); | ||||
|     __SSC_STOP; | ||||
|   } | ||||
|   t1=usecond(); | ||||
|   CounterSdw.Stop(); | ||||
|  | ||||
|   if ( report ) {  | ||||
|     CounterSdw.Report(); | ||||
|   } else { | ||||
|     double volume=Ls;  for(int mu=0;mu<Nd;mu++) volume=volume*latt4[mu]; | ||||
|     double flops=(1344.0*volume*ncall)/2; | ||||
|     std::cout<<"\t"<< flops/(t1-t0); | ||||
|   } | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -26,7 +26,7 @@ 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> | ||||
| #include <Grid/Grid.h> | ||||
|  | ||||
| using namespace std; | ||||
| using namespace Grid; | ||||
| @@ -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++){ | ||||
|   | ||||
| @@ -26,7 +26,7 @@ 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> | ||||
| #include <Grid/Grid.h> | ||||
|  | ||||
| using namespace std; | ||||
| using namespace Grid; | ||||
| @@ -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); | ||||
|   | ||||
							
								
								
									
										222
									
								
								benchmarks/Benchmark_mooee.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										222
									
								
								benchmarks/Benchmark_mooee.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,222 @@ | ||||
|     /************************************************************************************* | ||||
|  | ||||
|     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> | ||||
|  | ||||
|     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); | ||||
|  | ||||
|   int threads = GridThread::GetThreads(); | ||||
|   std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl; | ||||
|  | ||||
|   std::vector<int> latt4 = GridDefaultLatt(); | ||||
|   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); | ||||
|   GridRedBlackCartesian * FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls,UGrid); | ||||
|  | ||||
|   std::cout << GridLogMessage << "Making Vec5d innermost grids"<<std::endl; | ||||
|   GridCartesian         * sUGrid   = SpaceTimeGrid::makeFourDimDWFGrid(GridDefaultLatt(),GridDefaultMpi()); | ||||
|   GridRedBlackCartesian * sUrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(sUGrid); | ||||
|   GridCartesian         * sFGrid   = SpaceTimeGrid::makeFiveDimDWFGrid(Ls,UGrid); | ||||
|   GridRedBlackCartesian * sFrbGrid = SpaceTimeGrid::makeFiveDimDWFRedBlackGrid(Ls,UGrid); | ||||
|  | ||||
|   std::vector<int> seeds4({1,2,3,4}); | ||||
|   std::vector<int> seeds5({5,6,7,8}); | ||||
|  | ||||
|   GridParallelRNG          RNG4(UGrid);  RNG4.SeedFixedIntegers(seeds4); | ||||
|   std::cout << GridLogMessage << "Seeded"<<std::endl; | ||||
|  | ||||
|   LatticeGaugeField Umu(UGrid); SU3::HotConfiguration(RNG4,Umu); | ||||
|  | ||||
|   std::cout << GridLogMessage << "made random gauge fields"<<std::endl; | ||||
|  | ||||
|   RealD mass=0.1; | ||||
|   RealD M5  =1.8; | ||||
|   RealD NP = UGrid->_Nprocessors; | ||||
|  | ||||
|  | ||||
|   if (1) | ||||
|   { | ||||
|     const int ncall=1000; | ||||
|  | ||||
|     std::cout << GridLogMessage<< "*********************************************************" <<std::endl; | ||||
|     std::cout << GridLogMessage<< "* Benchmarking DomainWallFermionR::Dhop "<<std::endl; | ||||
|     std::cout << GridLogMessage<< "*********************************************************" <<std::endl; | ||||
|  | ||||
|     GridParallelRNG RNG5(FGrid); | ||||
|     LatticeFermion src(FGrid); random(RNG5,src); | ||||
|     LatticeFermion result(FGrid); | ||||
|  | ||||
|     DomainWallFermionR Dw(Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5); | ||||
|     double t0,t1; | ||||
|  | ||||
|     LatticeFermion r_eo(FGrid); | ||||
|     LatticeFermion src_e (FrbGrid); | ||||
|     LatticeFermion src_o (FrbGrid); | ||||
|     LatticeFermion r_e   (FrbGrid); | ||||
|     LatticeFermion r_o   (FrbGrid); | ||||
|      | ||||
|     pickCheckerboard(Even,src_e,src); | ||||
|     pickCheckerboard(Odd,src_o,src); | ||||
|      | ||||
|     setCheckerboard(r_eo,src_o); | ||||
|     setCheckerboard(r_eo,src_e); | ||||
|      | ||||
|     r_e = zero; | ||||
|     r_o = zero; | ||||
|  | ||||
|  | ||||
| #define BENCH_DW(A,in,out)			\ | ||||
|     Dw.CayleyZeroCounters();			\ | ||||
|     Dw. A (in,out);				\ | ||||
|     FGrid->Barrier();				\ | ||||
|     t0=usecond();				\ | ||||
|     for(int i=0;i<ncall;i++){			\ | ||||
|       Dw. A (in,out);				\ | ||||
|     }						\ | ||||
|     t1=usecond();				\ | ||||
|     FGrid->Barrier();				\ | ||||
|     Dw.CayleyReport();					\ | ||||
|     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);				\ | ||||
|     FGrid->Barrier();				\ | ||||
|     t0=usecond();				\ | ||||
|     for(int i=0;i<ncall;i++){			\ | ||||
|       Dw. A (in,out,0);				\ | ||||
|     }						\ | ||||
|     t1=usecond();				\ | ||||
|     FGrid->Barrier();				\ | ||||
|     Dw.CayleyReport();					\ | ||||
|     std::cout<<GridLogMessage << "Called " #A " "<< (t1-t0)/ncall<<" us"<<std::endl;\ | ||||
|     std::cout<<GridLogMessage << "******************"<<std::endl; | ||||
|  | ||||
|     BENCH_DW_MEO(Dhop    ,src,result); | ||||
|     BENCH_DW_MEO(DhopEO  ,src_o,r_e); | ||||
|     BENCH_DW(Meooe   ,src_o,r_e); | ||||
|     BENCH_DW(Mooee   ,src_o,r_o); | ||||
|     BENCH_DW(MooeeInv,src_o,r_o); | ||||
|  | ||||
|   } | ||||
|  | ||||
|   if (1) | ||||
|   { | ||||
|     const int ncall=1000; | ||||
|  | ||||
|     std::cout << GridLogMessage<< "*********************************************************" <<std::endl; | ||||
|     std::cout << GridLogMessage<< "* Benchmarking DomainWallFermionVec5dR::Dhop "<<std::endl; | ||||
|     std::cout << GridLogMessage<< "*********************************************************" <<std::endl; | ||||
|  | ||||
|     GridParallelRNG RNG5(sFGrid); | ||||
|     LatticeFermion src(sFGrid); random(RNG5,src); | ||||
|     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(); | ||||
|  | ||||
|     double t0,t1; | ||||
|  | ||||
|     LatticeFermion r_eo(sFGrid); | ||||
|     LatticeFermion src_e (sFrbGrid); | ||||
|     LatticeFermion src_o (sFrbGrid); | ||||
|     LatticeFermion r_e   (sFrbGrid); | ||||
|     LatticeFermion r_o   (sFrbGrid); | ||||
|      | ||||
|     pickCheckerboard(Even,src_e,src); | ||||
|     pickCheckerboard(Odd,src_o,src); | ||||
|      | ||||
|     setCheckerboard(r_eo,src_o); | ||||
|     setCheckerboard(r_eo,src_e); | ||||
|      | ||||
|     r_e = zero; | ||||
|     r_o = zero; | ||||
|  | ||||
|     BENCH_DW_MEO(Dhop    ,src,result); | ||||
|     BENCH_DW_MEO(DhopEO  ,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(); | ||||
| } | ||||
| @@ -26,7 +26,7 @@ Author: Peter Boyle <peterboyle@Peters-MacBook-Pro-2.local> | ||||
|     See the full license in the file "LICENSE" in the top level distribution directory | ||||
|     *************************************************************************************/ | ||||
|     /*  END LEGAL */ | ||||
| #include <Grid.h> | ||||
| #include <Grid/Grid.h> | ||||
|  | ||||
| using namespace std; | ||||
| using namespace Grid; | ||||
| @@ -55,7 +55,7 @@ int main (int argc, char ** argv) | ||||
|       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); | ||||
| @@ -88,7 +88,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}); | ||||
|  | ||||
|       LatticeColourMatrix z(&Grid); //random(pRNG,z); | ||||
|       LatticeColourMatrix x(&Grid); //random(pRNG,x); | ||||
| @@ -119,7 +119,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}); | ||||
|  | ||||
|       LatticeColourMatrix z(&Grid); //random(pRNG,z); | ||||
|       LatticeColourMatrix x(&Grid); //random(pRNG,x); | ||||
| @@ -150,7 +150,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}); | ||||
|  | ||||
|       LatticeColourMatrix z(&Grid); //random(pRNG,z); | ||||
|       LatticeColourMatrix x(&Grid); //random(pRNG,x); | ||||
|   | ||||
| @@ -26,7 +26,7 @@ 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> | ||||
| #include <Grid/Grid.h> | ||||
|  | ||||
| using namespace std; | ||||
| using namespace Grid; | ||||
| @@ -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]; ; | ||||
|   | ||||
							
								
								
									
										130
									
								
								benchmarks/Benchmark_wilson_sweep.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								benchmarks/Benchmark_wilson_sweep.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,130 @@ | ||||
| /************************************************************************************* | ||||
|     Grid physics library, www.github.com/paboyle/Grid  | ||||
|     Source file: ./benchmarks/Benchmark_wilson.cc | ||||
|     Copyright (C) 2015 | ||||
| Author: Peter Boyle <paboyle@ph.ed.ac.uk> | ||||
| Author: paboyle <paboyle@ph.ed.ac.uk> | ||||
| Author: Richard Rollins <rprollins@users.noreply.github.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/Grid.h> | ||||
|  | ||||
| using namespace std; | ||||
| using namespace Grid; | ||||
| using namespace Grid::QCD; | ||||
|  | ||||
| template<class d> | ||||
| struct scal { | ||||
|   d internal; | ||||
| }; | ||||
|  | ||||
| Gamma::Algebra Gmu [] = { | ||||
|     Gamma::Algebra::GammaX, | ||||
|     Gamma::Algebra::GammaY, | ||||
|     Gamma::Algebra::GammaZ, | ||||
|     Gamma::Algebra::GammaT | ||||
| }; | ||||
|  | ||||
| bool overlapComms = false; | ||||
|  | ||||
| void bench_wilson ( | ||||
| 		   LatticeFermion &    src, | ||||
| 		   LatticeFermion & result, | ||||
| 		   WilsonFermionR &     Dw, | ||||
| 		   double const     volume, | ||||
| 		   int const           dag ); | ||||
|  | ||||
| int main (int argc, char ** argv) | ||||
| { | ||||
|   Grid_init(&argc,&argv); | ||||
|   if( GridCmdOptionExists(argv,argv+argc,"--asynch") ){ overlapComms = true; } | ||||
|   typename WilsonFermionR::ImplParams params; | ||||
|   params.overlapCommsCompute = overlapComms; | ||||
|  | ||||
|   std::vector<int> simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd()); | ||||
|   std::vector<int> mpi_layout  = GridDefaultMpi(); | ||||
|   std::vector<int> seeds({1,2,3,4}); | ||||
|   RealD mass = 0.1; | ||||
|  | ||||
|   std::cout << GridLogMessage<< "*****************************************************************" <<std::endl; | ||||
|   std::cout << GridLogMessage<< "* Kernel options --dslash-generic, --dslash-unroll, --dslash-asm" <<std::endl; | ||||
|   std::cout << GridLogMessage<< "*****************************************************************" <<std::endl; | ||||
|   std::cout << GridLogMessage<< "*****************************************************************" <<std::endl; | ||||
|   std::cout << GridLogMessage<< "* Benchmarking WilsonFermionR::Dhop                  "<<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; | ||||
|   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; | ||||
|  | ||||
|   std::cout<<GridLogMessage << "============================================================================="<< std::endl; | ||||
|   std::cout<<GridLogMessage << "= Benchmarking Wilson" << std::endl; | ||||
|   std::cout<<GridLogMessage << "============================================================================="<< std::endl; | ||||
|   std::cout<<GridLogMessage << "Volume\t\t\tWilson/MFLOPs\tWilsonDag/MFLOPs" << std::endl; | ||||
|   std::cout<<GridLogMessage << "============================================================================="<< std::endl; | ||||
|  | ||||
|   int Lmax = 32; | ||||
|   int dmin = 0; | ||||
|   if ( getenv("LMAX") ) Lmax=atoi(getenv("LMAX")); | ||||
|   if ( getenv("DMIN") ) dmin=atoi(getenv("DMIN")); | ||||
|   for (int L=8; L<=Lmax; L*=2) | ||||
|     { | ||||
|       std::vector<int> latt_size = std::vector<int>(4,L); | ||||
|       for(int d=4; d>dmin; d--) | ||||
| 	{ | ||||
| 	  if ( d<=3 ) { latt_size[d] *= 2; } | ||||
|  | ||||
| 	  std::cout << GridLogMessage; | ||||
| 	  std::copy( latt_size.begin(), --latt_size.end(), std::ostream_iterator<int>( std::cout, std::string("x").c_str() ) ); | ||||
| 	  std::cout << latt_size.back() << "\t\t"; | ||||
|  | ||||
| 	  GridCartesian           Grid(latt_size,simd_layout,mpi_layout); | ||||
| 	  GridRedBlackCartesian RBGrid(latt_size,simd_layout,mpi_layout); | ||||
|  | ||||
| 	  GridParallelRNG  pRNG(&Grid); pRNG.SeedFixedIntegers(seeds); | ||||
| 	  LatticeGaugeField Umu(&Grid); random(pRNG,Umu); | ||||
| 	  LatticeFermion    src(&Grid); random(pRNG,src); | ||||
| 	  LatticeFermion result(&Grid); result=zero; | ||||
|  | ||||
| 	  double volume = std::accumulate(latt_size.begin(),latt_size.end(),1,std::multiplies<int>()); | ||||
|  | ||||
| 	  WilsonFermionR Dw(Umu,Grid,RBGrid,mass,params); | ||||
|        | ||||
| 	  bench_wilson(src,result,Dw,volume,DaggerNo); | ||||
| 	  bench_wilson(src,result,Dw,volume,DaggerYes); | ||||
| 	  std::cout << std::endl; | ||||
| 	} | ||||
|     } | ||||
|  | ||||
|   std::cout<<GridLogMessage << "============================================================================="<< std::endl; | ||||
|   Grid_finalize(); | ||||
| } | ||||
|  | ||||
| void bench_wilson ( | ||||
| 		   LatticeFermion &    src, | ||||
| 		   LatticeFermion & result, | ||||
| 		   WilsonFermionR &     Dw, | ||||
| 		   double const     volume, | ||||
| 		   int const           dag ) | ||||
| { | ||||
|   int ncall    = 1000; | ||||
|   double t0    = usecond(); | ||||
|   for(int i=0; i<ncall; i++) { Dw.Dhop(src,result,dag); } | ||||
|   double t1    = usecond(); | ||||
|   double flops = 1344 * volume * ncall; | ||||
|   std::cout << flops/(t1-t0) << "\t\t"; | ||||
| } | ||||
| @@ -1,172 +0,0 @@ | ||||
|     /************************************************************************************* | ||||
|  | ||||
|     Grid physics library, www.github.com/paboyle/Grid  | ||||
|  | ||||
|     Source file: ./tests/Test_zmm.cc | ||||
|  | ||||
|     Copyright (C) 2015 | ||||
|  | ||||
| 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.h> | ||||
| #include <PerfCount.h> | ||||
|  | ||||
|  | ||||
| using namespace Grid; | ||||
| using namespace Grid::QCD; | ||||
|  | ||||
|  | ||||
| int bench(std::ofstream &os, std::vector<int> &latt4,int Ls); | ||||
|  | ||||
| int main(int argc,char **argv) | ||||
| { | ||||
|   Grid_init(&argc,&argv); | ||||
|   std::ofstream os("zmm.dat"); | ||||
|  | ||||
|   os << "#V Ls Lxy Lzt C++ Asm OMP L1 " <<std::endl; | ||||
|   for(int L=4;L<=32;L+=4){ | ||||
|     for(int m=1;m<=2;m++){ | ||||
|       for(int Ls=8;Ls<=16;Ls+=8){ | ||||
| 	std::vector<int> grid({L,L,m*L,m*L}); | ||||
| 	for(int i=0;i<4;i++) {  | ||||
| 	  std::cout << grid[i]<<"x"; | ||||
| 	} | ||||
| 	std::cout << Ls<<std::endl; | ||||
| 	bench(os,grid,Ls); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| int bench(std::ofstream &os, std::vector<int> &latt4,int Ls) | ||||
| { | ||||
|  | ||||
|   GridCartesian         * UGrid   = SpaceTimeGrid::makeFourDimGrid(latt4, GridDefaultSimd(Nd,vComplex::Nsimd()),GridDefaultMpi()); | ||||
|   GridRedBlackCartesian * UrbGrid = SpaceTimeGrid::makeFourDimRedBlackGrid(UGrid); | ||||
|   GridCartesian         * FGrid   = SpaceTimeGrid::makeFiveDimGrid(Ls,UGrid); | ||||
|   GridRedBlackCartesian * FrbGrid = SpaceTimeGrid::makeFiveDimRedBlackGrid(Ls,UGrid); | ||||
|  | ||||
|   std::vector<int> simd_layout = GridDefaultSimd(Nd,vComplex::Nsimd()); | ||||
|   std::vector<int> mpi_layout  = GridDefaultMpi(); | ||||
|   int threads = GridThread::GetThreads(); | ||||
|  | ||||
|   std::vector<int> seeds4({1,2,3,4}); | ||||
|   std::vector<int> seeds5({5,6,7,8}); | ||||
|  | ||||
|   GridSerialRNG sRNG; sRNG.SeedFixedIntegers(seeds4); | ||||
|  | ||||
|   LatticeFermion src (FGrid); | ||||
|   LatticeFermion tmp (FGrid); | ||||
|   LatticeFermion srce(FrbGrid); | ||||
|  | ||||
|   LatticeFermion resulto(FrbGrid); resulto=zero; | ||||
|   LatticeFermion resulta(FrbGrid); resulta=zero; | ||||
|   LatticeFermion junk(FrbGrid); junk=zero; | ||||
|   LatticeFermion diff(FrbGrid);  | ||||
|   LatticeGaugeField Umu(UGrid); | ||||
|  | ||||
|   double mfc, mfa, mfo, mfl1; | ||||
|  | ||||
|   GridParallelRNG          RNG4(UGrid);  RNG4.SeedFixedIntegers(seeds4); | ||||
|   GridParallelRNG          RNG5(FGrid);  RNG5.SeedFixedIntegers(seeds5); | ||||
|   random(RNG5,src); | ||||
| #if 1 | ||||
|   random(RNG4,Umu); | ||||
| #else | ||||
|   int mmu=2; | ||||
|   std::vector<LatticeColourMatrix> U(4,UGrid); | ||||
|   for(int mu=0;mu<Nd;mu++){ | ||||
|     U[mu] = PeekIndex<LorentzIndex>(Umu,mu); | ||||
|     if ( mu!=mmu ) U[mu] = zero; | ||||
|     if ( mu==mmu ) U[mu] = 1.0; | ||||
|     PokeIndex<LorentzIndex>(Umu,U[mu],mu); | ||||
|   } | ||||
| #endif | ||||
|  pickCheckerboard(Even,srce,src); | ||||
|  | ||||
|   RealD mass=0.1; | ||||
|   RealD M5  =1.8; | ||||
|   DomainWallFermionR Dw(Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5); | ||||
|  | ||||
|   std::cout<<GridLogMessage << "Calling Dw"<<std::endl; | ||||
|   int ncall=50; | ||||
|   double t0=usecond(); | ||||
|   for(int i=0;i<ncall;i++){ | ||||
|     Dw.DhopOE(srce,resulto,0); | ||||
|   } | ||||
|   double t1=usecond(); | ||||
|  | ||||
|   double volume=Ls;  for(int mu=0;mu<Nd;mu++) volume=volume*latt4[mu]; | ||||
|   double flops=1344*volume/2; | ||||
|  | ||||
|   mfc = flops*ncall/(t1-t0); | ||||
|   std::cout<<GridLogMessage << "Called C++ Dw"<< " mflop/s =   "<< mfc<<std::endl; | ||||
|  | ||||
|   QCD::WilsonFermion5DStatic::AsmOptDslash=1; | ||||
|   t0=usecond(); | ||||
|   for(int i=0;i<ncall;i++){ | ||||
|     Dw.DhopOE(srce,resulta,0); | ||||
|   } | ||||
|   t1=usecond(); | ||||
|   mfa = flops*ncall/(t1-t0); | ||||
|   std::cout<<GridLogMessage << "Called ASM Dw"<< " mflop/s =   "<< mfa<<std::endl; | ||||
|   /* | ||||
|   int dag=DaggerNo; | ||||
|   t0=usecond(); | ||||
|   for(int i=0;i<1;i++){ | ||||
|     Dw.DhopInternalOMPbench(Dw.StencilEven,Dw.LebesgueEvenOdd,Dw.UmuOdd,srce,resulta,dag); | ||||
|   } | ||||
|   t1=usecond(); | ||||
|   mfo = flops*100/(t1-t0); | ||||
|   std::cout<<GridLogMessage << "Called ASM-OMP Dw"<< " mflop/s =   "<< mfo<<std::endl; | ||||
|  | ||||
|   t0=usecond(); | ||||
|   for(int i=0;i<1;i++){ | ||||
|     Dw.DhopInternalL1bench(Dw.StencilEven,Dw.LebesgueEvenOdd,Dw.UmuOdd,srce,resulta,dag); | ||||
|   } | ||||
|   t1=usecond(); | ||||
|   mfl1= flops*100/(t1-t0); | ||||
|   std::cout<<GridLogMessage << "Called ASM-L1 Dw"<< " mflop/s =   "<< mfl1<<std::endl; | ||||
|   os << latt4[0]*latt4[1]*latt4[2]*latt4[3]<< " "<<Ls<<" "<< latt4[0] <<" " <<latt4[2]<< " " | ||||
|      << mfc<<" " | ||||
|      << mfa<<" " | ||||
|      << mfo<<" " | ||||
|      << mfl1<<std::endl; | ||||
|   */ | ||||
|  | ||||
| #if 0 | ||||
|   for(int i=0;i< PerformanceCounter::NumTypes(); i++ ){ | ||||
|     Dw.DhopOE(srce,resulta,0); | ||||
|     PerformanceCounter Counter(i); | ||||
|     Counter.Start(); | ||||
|     Dw.DhopOE(srce,resulta,0); | ||||
|     Counter.Stop(); | ||||
|     Counter.Report(); | ||||
|   } | ||||
| #endif | ||||
|   //resulta = (-0.5) * resulta; | ||||
|  | ||||
|   diff = resulto-resulta; | ||||
|   std::cout<<GridLogMessage << "diff "<< norm2(diff)<<std::endl; | ||||
|   std::cout<<std::endl; | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -1,31 +0,0 @@ | ||||
|  | ||||
| bin_PROGRAMS = Benchmark_comms Benchmark_dwf Benchmark_memory_asynch Benchmark_memory_bandwidth Benchmark_su3 Benchmark_wilson Benchmark_zmm | ||||
|  | ||||
|  | ||||
| Benchmark_comms_SOURCES=Benchmark_comms.cc | ||||
| Benchmark_comms_LDADD=-lGrid | ||||
|  | ||||
|  | ||||
| Benchmark_dwf_SOURCES=Benchmark_dwf.cc | ||||
| Benchmark_dwf_LDADD=-lGrid | ||||
|  | ||||
|  | ||||
| Benchmark_memory_asynch_SOURCES=Benchmark_memory_asynch.cc | ||||
| Benchmark_memory_asynch_LDADD=-lGrid | ||||
|  | ||||
|  | ||||
| Benchmark_memory_bandwidth_SOURCES=Benchmark_memory_bandwidth.cc | ||||
| Benchmark_memory_bandwidth_LDADD=-lGrid | ||||
|  | ||||
|  | ||||
| Benchmark_su3_SOURCES=Benchmark_su3.cc | ||||
| Benchmark_su3_LDADD=-lGrid | ||||
|  | ||||
|  | ||||
| Benchmark_wilson_SOURCES=Benchmark_wilson.cc | ||||
| Benchmark_wilson_LDADD=-lGrid | ||||
|  | ||||
|  | ||||
| Benchmark_zmm_SOURCES=Benchmark_zmm.cc | ||||
| Benchmark_zmm_LDADD=-lGrid | ||||
|  | ||||
| @@ -1,8 +1,11 @@ | ||||
| # additional include paths necessary to compile the C++ library | ||||
| AM_CXXFLAGS = -I$(top_srcdir)/lib | ||||
| AM_LDFLAGS = -L$(top_builddir)/lib | ||||
|  | ||||
| # | ||||
| # Test code | ||||
| # | ||||
| 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 | ||||
|   | ||||
							
								
								
									
										11
									
								
								benchmarks/simple_simd_test.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								benchmarks/simple_simd_test.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| #include <Grid/Grid.h> | ||||
|  | ||||
| Grid::vRealD add(const Grid::vRealD &x, const Grid::vRealD &y) | ||||
| { | ||||
| 	return x+y; | ||||
| } | ||||
|  | ||||
| Grid::vRealD sub(const Grid::vRealD &x, const Grid::vRealD &y) | ||||
| { | ||||
| 	return x-y; | ||||
| } | ||||
| @@ -25,7 +25,7 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk> | ||||
|     See the full license in the file "LICENSE" in the top level distribution directory | ||||
|     *************************************************************************************/ | ||||
|     /*  END LEGAL */ | ||||
| #include <Grid.h> | ||||
| #include <Grid/Grid.h> | ||||
|  | ||||
| using namespace std; | ||||
| using namespace Grid; | ||||
|   | ||||
| @@ -25,7 +25,7 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk> | ||||
|     See the full license in the file "LICENSE" in the top level distribution directory | ||||
|     *************************************************************************************/ | ||||
|     /*  END LEGAL */ | ||||
| #include <Grid.h> | ||||
| #include <Grid/Grid.h> | ||||
|  | ||||
| using namespace std; | ||||
| using namespace Grid; | ||||
|   | ||||
							
								
								
									
										13
									
								
								bootstrap.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										13
									
								
								bootstrap.sh
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| #!/usr/bin/env bash | ||||
|  | ||||
| EIGEN_URL='http://bitbucket.org/eigen/eigen/get/3.2.9.tar.bz2' | ||||
|  | ||||
| echo "-- deploying Eigen source..." | ||||
| wget ${EIGEN_URL} --no-check-certificate | ||||
| ./scripts/update_eigen.sh `basename ${EIGEN_URL}` | ||||
| rm `basename ${EIGEN_URL}` | ||||
|  | ||||
| echo '-- generating Make.inc files...' | ||||
| ./scripts/filelist | ||||
| echo '-- generating configure script...' | ||||
| autoreconf -fvi | ||||
							
								
								
									
										563
									
								
								configure.ac
									
									
									
									
									
								
							
							
						
						
									
										563
									
								
								configure.ac
									
									
									
									
									
								
							| @@ -1,287 +1,442 @@ | ||||
| #                         -*- Autoconf -*- | ||||
| # Process this file with autoconf to produce a configure script. | ||||
| # | ||||
| # Project Grid package   | ||||
| #  | ||||
| # Time-stamp: <2015-07-10 17:46:21 neo> | ||||
|  | ||||
| AC_PREREQ([2.63]) | ||||
| AC_INIT([Grid], [1.0], [paboyle@ph.ed.ac.uk]) | ||||
| AC_CANONICAL_SYSTEM | ||||
| AC_INIT([Grid], [0.6.0], [https://github.com/paboyle/Grid], [Grid]) | ||||
| AC_CANONICAL_BUILD | ||||
| AC_CANONICAL_HOST | ||||
| AC_CANONICAL_TARGET | ||||
| AM_INIT_AUTOMAKE(subdir-objects) | ||||
| 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])]) | ||||
|  | ||||
| AC_MSG_NOTICE([ | ||||
|  | ||||
| ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: | ||||
| Configuring $PACKAGE v$VERSION  for $host | ||||
| ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: | ||||
| ]) | ||||
|  | ||||
| # Checks for programs. | ||||
| AC_LANG(C++) | ||||
| ############### Checks for programs | ||||
| CXXFLAGS="-O3 $CXXFLAGS" | ||||
| AC_PROG_CXX | ||||
| AC_OPENMP | ||||
| AC_PROG_RANLIB | ||||
| #AX_CXX_COMPILE_STDCXX_11(noext, mandatory) | ||||
| AX_EXT | ||||
|  | ||||
| # Checks for libraries. | ||||
| #AX_GCC_VAR_ATTRIBUTE(aligned) | ||||
| ############### Get compiler informations | ||||
| AC_LANG([C++]) | ||||
| AX_CXX_COMPILE_STDCXX_11([noext],[mandatory]) | ||||
| AX_COMPILER_VENDOR | ||||
| AC_DEFINE_UNQUOTED([CXX_COMP_VENDOR],["$ax_cv_cxx_compiler_vendor"], | ||||
|       [vendor of C++ compiler that will compile the code]) | ||||
| AX_GXX_VERSION | ||||
| AC_DEFINE_UNQUOTED([GXX_VERSION],["$GXX_VERSION"], | ||||
|       [version of g++ that will compile the code]) | ||||
|  | ||||
| # Checks for header files. | ||||
| ############### Checks for typedefs, structures, and compiler characteristics | ||||
| AC_TYPE_SIZE_T | ||||
| AC_TYPE_UINT32_T | ||||
| AC_TYPE_UINT64_T | ||||
|  | ||||
| ############### OpenMP  | ||||
| AC_OPENMP | ||||
| ac_openmp=no | ||||
| if test "${OPENMP_CXXFLAGS}X" != "X"; then | ||||
|   ac_openmp=yes | ||||
|   AM_CXXFLAGS="$OPENMP_CXXFLAGS $AM_CXXFLAGS" | ||||
|   AM_LDFLAGS="$OPENMP_CXXFLAGS $AM_LDFLAGS" | ||||
| fi | ||||
|  | ||||
| ############### Checks for header files | ||||
| AC_CHECK_HEADERS(stdint.h) | ||||
| AC_CHECK_HEADERS(mm_malloc.h) | ||||
| AC_CHECK_HEADERS(malloc/malloc.h) | ||||
| AC_CHECK_HEADERS(malloc.h) | ||||
| AC_CHECK_HEADERS(endian.h) | ||||
| AC_CHECK_HEADERS(execinfo.h) | ||||
| AC_CHECK_HEADERS(gmp.h) | ||||
| AC_CHECK_DECLS([ntohll],[], [], [[#include <arpa/inet.h>]]) | ||||
| AC_CHECK_DECLS([be64toh],[], [], [[#include <arpa/inet.h>]]) | ||||
|  | ||||
| # Checks for typedefs, structures, and compiler characteristics. | ||||
| AC_TYPE_SIZE_T | ||||
| AC_TYPE_UINT32_T | ||||
| AC_TYPE_UINT64_T | ||||
| ############### GMP and MPFR | ||||
| AC_ARG_WITH([gmp], | ||||
|     [AS_HELP_STRING([--with-gmp=prefix], | ||||
|     [try this for a non-standard install prefix of the GMP library])], | ||||
|     [AM_CXXFLAGS="-I$with_gmp/include $AM_CXXFLAGS"] | ||||
|     [AM_LDFLAGS="-L$with_gmp/lib $AM_LDFLAGS"]) | ||||
| AC_ARG_WITH([mpfr], | ||||
|     [AS_HELP_STRING([--with-mpfr=prefix], | ||||
|     [try this for a non-standard install prefix of the MPFR library])], | ||||
|     [AM_CXXFLAGS="-I$with_mpfr/include $AM_CXXFLAGS"] | ||||
|     [AM_LDFLAGS="-L$with_mpfr/lib $AM_LDFLAGS"]) | ||||
|  | ||||
| # Checks for library functions. | ||||
| echo | ||||
| echo Checking libraries  | ||||
| echo ::::::::::::::::::::::::::::::::::::::::::: | ||||
| ############### 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  | ||||
| AC_ARG_ENABLE([lapack], | ||||
|     [AC_HELP_STRING([--enable-lapack=yes|no|prefix], [enable LAPACK])],  | ||||
|     [ac_LAPACK=${enable_lapack}], [ac_LAPACK=no]) | ||||
|  | ||||
| case ${ac_LAPACK} in | ||||
|     no) | ||||
|         ;; | ||||
|     yes) | ||||
|         AC_DEFINE([USE_LAPACK],[1],[use LAPACK]);; | ||||
|     *) | ||||
|         AM_CXXFLAGS="-I$ac_LAPACK/include $AM_CXXFLAGS" | ||||
|         AM_LDFLAGS="-L$ac_LAPACK/lib $AM_LDFLAGS" | ||||
|         AC_DEFINE([USE_LAPACK],[1],[use LAPACK]);; | ||||
| esac | ||||
|  | ||||
| ############### MKL | ||||
| AC_ARG_ENABLE([mkl], | ||||
|     [AC_HELP_STRING([--enable-mkl=yes|no|prefix], [enable Intel MKL for LAPACK & FFTW])], | ||||
|     [ac_MKL=${enable_mkl}], [ac_MKL=no]) | ||||
|  | ||||
| case ${ac_MKL} in | ||||
|     no) | ||||
|         ;; | ||||
|     yes) | ||||
|         AC_DEFINE([USE_MKL], [1], [Define to 1 if you use the Intel MKL]);; | ||||
|     *) | ||||
|         AM_CXXFLAGS="-I$ac_MKL/include $AM_CXXFLAGS" | ||||
|         AM_LDFLAGS="-L$ac_MKL/lib $AM_LDFLAGS" | ||||
|         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_NUMA=${enable_NUMA}],[ac_NUMA=no]) | ||||
|  | ||||
| case ${ac_NUMA} in | ||||
|     no) | ||||
|         ;; | ||||
|     yes) | ||||
|         AC_DEFINE([GRID_NUMA],[1],[First touch numa locality]);; | ||||
|     *) | ||||
|         AC_DEFINE([GRID_NUMA],[1],[First touch numa locality]);; | ||||
| esac | ||||
|  | ||||
| ############### Checks for library functions | ||||
| CXXFLAGS_CPY=$CXXFLAGS | ||||
| LDFLAGS_CPY=$LDFLAGS | ||||
| CXXFLAGS="$AM_CXXFLAGS $CXXFLAGS" | ||||
| LDFLAGS="$AM_LDFLAGS $LDFLAGS" | ||||
|  | ||||
| AC_CHECK_FUNCS([gettimeofday]) | ||||
|  | ||||
| if test "${ac_MKL}x" != "nox"; then | ||||
|     AC_SEARCH_LIBS([mkl_set_interface_layer], [mkl_rt], [], | ||||
|                    [AC_MSG_ERROR("MKL enabled but library not found")]) | ||||
| fi | ||||
|  | ||||
| # | ||||
| # SIMD instructions selection | ||||
| # | ||||
| AC_SEARCH_LIBS([__gmpf_init], [gmp], | ||||
|                [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])] | ||||
|                [have_gmp=true]) | ||||
|  | ||||
| AC_ARG_ENABLE([simd],[AC_HELP_STRING([--enable-simd=SSE4|AVX|AVXFMA4|AVX2|AVX512|IMCI],\ | ||||
| 	[Select instructions to be SSE4.0, AVX 1.0, AVX 2.0+FMA, AVX 512, IMCI])],\ | ||||
| 	[ac_SIMD=${enable_simd}],[ac_SIMD=DEBUG]) | ||||
| if test "${ac_LAPACK}x" != "nox"; then | ||||
|     AC_SEARCH_LIBS([LAPACKE_sbdsdc], [lapack], [], | ||||
|                    [AC_MSG_ERROR("LAPACK enabled but library not found")]) | ||||
| fi    | ||||
|  | ||||
| supported=no | ||||
| AC_SEARCH_LIBS([fftw_execute], [fftw3], | ||||
|                [AC_SEARCH_LIBS([fftwf_execute], [fftw3f], [], | ||||
|                                [AC_MSG_ERROR("single precision FFTW library not found")])] | ||||
|                [AC_DEFINE([HAVE_FFTW], [1], [Define to 1 if you have the `FFTW' library])] | ||||
|                [have_fftw=true]) | ||||
|  | ||||
| ac_ZMM=no; | ||||
| 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 | ||||
|  | ||||
| ############### SIMD instruction selection | ||||
| AC_ARG_ENABLE([simd],[AC_HELP_STRING([--enable-simd=code], | ||||
|               [select SIMD target (cf. README.md)])], [ac_SIMD=${enable_simd}], [ac_SIMD=GEN]) | ||||
|  | ||||
| AC_ARG_ENABLE([gen-simd-width], | ||||
|             [AS_HELP_STRING([--enable-gen-simd-width=size], | ||||
|             [size (in bytes) of the generic SIMD vectors (default: 32)])], | ||||
|             [ac_gen_simd_width=$enable_gen_simd_width], | ||||
|             [ac_gen_simd_width=32]) | ||||
|  | ||||
| case ${ax_cv_cxx_compiler_vendor} in | ||||
|   clang|gnu) | ||||
|     case ${ac_SIMD} in | ||||
|       SSE4) | ||||
|         AC_DEFINE([SSE4],[1],[SSE4 intrinsics]) | ||||
|         SIMD_FLAGS='-msse4.2';; | ||||
|       AVX) | ||||
|         AC_DEFINE([AVX1],[1],[AVX intrinsics]) | ||||
|         SIMD_FLAGS='-mavx';; | ||||
|       AVXFMA4) | ||||
|         AC_DEFINE([AVXFMA4],[1],[AVX intrinsics with FMA4]) | ||||
|         SIMD_FLAGS='-mavx -mfma4';; | ||||
|       AVXFMA) | ||||
|         AC_DEFINE([AVXFMA],[1],[AVX intrinsics with FMA3]) | ||||
|         SIMD_FLAGS='-mavx -mfma';; | ||||
|       AVX2) | ||||
|         AC_DEFINE([AVX2],[1],[AVX2 intrinsics]) | ||||
|         SIMD_FLAGS='-mavx2 -mfma';; | ||||
|       AVX512) | ||||
|         AC_DEFINE([AVX512],[1],[AVX512 intrinsics]) | ||||
|         SIMD_FLAGS='-mavx512f -mavx512pf -mavx512er -mavx512cd';; | ||||
|       KNC) | ||||
|         AC_DEFINE([IMCI],[1],[IMCI intrinsics for Knights Corner]) | ||||
|         SIMD_FLAGS='';; | ||||
|       KNL) | ||||
|         AC_DEFINE([AVX512],[1],[AVX512 intrinsics]) | ||||
|         SIMD_FLAGS='-march=knl';; | ||||
|       GEN) | ||||
|         AC_DEFINE([GEN],[1],[generic vector code]) | ||||
|         AC_DEFINE_UNQUOTED([GEN_SIMD_WIDTH],[$ac_gen_simd_width], | ||||
|                            [generic SIMD vector width (in bytes)]) | ||||
|         SIMD_GEN_WIDTH_MSG=" (width= $ac_gen_simd_width)" | ||||
|         SIMD_FLAGS='';; | ||||
|       QPX|BGQ) | ||||
|         AC_DEFINE([QPX],[1],[QPX intrinsics for BG/Q]) | ||||
|         SIMD_FLAGS='';; | ||||
|       *) | ||||
|         AC_MSG_ERROR(["SIMD option ${ac_SIMD} not supported by the GCC/Clang compiler"]);; | ||||
|     esac;; | ||||
|   intel) | ||||
|     case ${ac_SIMD} in | ||||
|       SSE4) | ||||
|         AC_DEFINE([SSE4],[1],[SSE4 intrinsics]) | ||||
|         SIMD_FLAGS='-msse4.2 -xsse4.2';; | ||||
|       AVX) | ||||
|         AC_DEFINE([AVX1],[1],[AVX intrinsics]) | ||||
|         SIMD_FLAGS='-mavx -xavx';; | ||||
|       AVXFMA) | ||||
|         AC_DEFINE([AVXFMA],[1],[AVX intrinsics with FMA3]) | ||||
|         SIMD_FLAGS='-mavx -fma';; | ||||
|       AVX2) | ||||
|         AC_DEFINE([AVX2],[1],[AVX2 intrinsics]) | ||||
|         SIMD_FLAGS='-march=core-avx2 -xcore-avx2';; | ||||
|       AVX512) | ||||
|         AC_DEFINE([AVX512],[1],[AVX512 intrinsics]) | ||||
|         SIMD_FLAGS='-xcore-avx512';; | ||||
|       KNC) | ||||
|         AC_DEFINE([IMCI],[1],[IMCI Intrinsics for Knights Corner]) | ||||
|         SIMD_FLAGS='';; | ||||
|       KNL) | ||||
|         AC_DEFINE([AVX512],[1],[AVX512 intrinsics for Knights Landing]) | ||||
|         SIMD_FLAGS='-xmic-avx512';; | ||||
|       GEN) | ||||
|         AC_DEFINE([GEN],[1],[generic vector code]) | ||||
|         AC_DEFINE_UNQUOTED([GEN_SIMD_WIDTH],[$ac_gen_simd_width], | ||||
|                            [generic SIMD vector width (in bytes)]) | ||||
|         SIMD_GEN_WIDTH_MSG=" (width= $ac_gen_simd_width)" | ||||
|         SIMD_FLAGS='';; | ||||
|       *) | ||||
|         AC_MSG_ERROR(["SIMD option ${ac_SIMD} not supported by the Intel compiler"]);; | ||||
|     esac;; | ||||
|   *) | ||||
|     AC_MSG_WARN([Compiler unknown, using generic vector code]) | ||||
|     AC_DEFINE([GENERIC_VEC],[1],[generic vector code]);; | ||||
| esac | ||||
| AM_CXXFLAGS="$SIMD_FLAGS $AM_CXXFLAGS" | ||||
| AM_CFLAGS="$SIMD_FLAGS $AM_CFLAGS" | ||||
|  | ||||
| case ${ac_SIMD} in | ||||
|      SSE4) | ||||
|        echo Configuring for SSE4 | ||||
|        AC_DEFINE([SSE4],[1],[SSE4 Intrinsics] ) | ||||
|        if test x"$ax_cv_support_ssse3_ext" = x"yes"; then  dnl minimal support for SSE4 | ||||
|          supported=yes | ||||
|        else | ||||
|   	AC_MSG_WARN([Your processor does not support SSE4 instructions]) | ||||
|        fi | ||||
|      ;; | ||||
|      AVX) | ||||
|        echo Configuring for AVX | ||||
|        AC_DEFINE([AVX1],[1],[AVX Intrinsics] ) | ||||
|        if test x"$ax_cv_support_avx_ext" = x"yes"; then  dnl minimal support for AVX | ||||
|        supported=yes			   | ||||
|        else | ||||
|        	AC_MSG_WARN([Your processor does not support AVX instructions]) | ||||
|        fi | ||||
|      ;; | ||||
|      AVXFMA4) | ||||
|        echo Configuring for AVX | ||||
|        AC_DEFINE([AVXFMA4],[1],[AVX Intrinsics with FMA4] ) | ||||
|        if test x"$ax_cv_support_avx_ext" = x"yes"; then  dnl minimal support for AVX | ||||
|        supported=yes			   | ||||
|        else | ||||
|        	AC_MSG_WARN([Your processor does not support AVX instructions]) | ||||
|        fi | ||||
|      ;; | ||||
|      AVX2) | ||||
|        echo Configuring for AVX2 | ||||
|        AC_DEFINE([AVX2],[1],[AVX2 Intrinsics] ) | ||||
|        if test x"$ax_cv_support_avx2_ext" = x"yes"; then  dnl minimal support for AVX2 | ||||
|        supported=yes | ||||
|        else | ||||
|        AC_MSG_WARN([Your processor does not support AVX2 instructions]) | ||||
|        fi | ||||
|      ;; | ||||
|      AVX512) | ||||
|        echo Configuring for AVX512  | ||||
|        AC_DEFINE([AVX512],[1],[AVX512 Intrinsics for Knights Landing] ) | ||||
|        supported="cross compilation" | ||||
|        ac_ZMM=yes; | ||||
|      ;; | ||||
|      IMCI) | ||||
|        echo Configuring for IMCI | ||||
|        AC_DEFINE([IMCI],[1],[IMCI Intrinsics for Knights Corner] ) | ||||
|        supported="cross compilation" | ||||
|        ac_ZMM=no; | ||||
|      ;; | ||||
|      NEONv8) | ||||
|        echo Configuring for experimental ARMv8a support  | ||||
|        AC_DEFINE([NEONv8],[1],[NEON ARMv8 Experimental support ] ) | ||||
|        supported="cross compilation" | ||||
|      ;; | ||||
|      DEBUG) | ||||
|        echo Configuring without SIMD support - only for compiler DEBUGGING! | ||||
|        AC_DEFINE([EMPTY_SIMD],[1],[EMPTY_SIMD only for DEBUGGING] ) | ||||
|       ;;      | ||||
|      *) | ||||
|      AC_MSG_ERROR([${ac_SIMD} flag unsupported as --enable-simd option\nRun ./configure --help for the list of options]);  | ||||
|      ;; | ||||
|   AVX512|KNL) | ||||
|     AC_DEFINE([TEST_ZMM],[1],[compile ZMM test]);; | ||||
|   *) | ||||
| 	;; | ||||
| esac | ||||
|  | ||||
| case ${ac_ZMM} in | ||||
| yes) | ||||
| 	echo Enabling ZMM source code | ||||
| ;; | ||||
| no) | ||||
| 	echo Disabling ZMM source code | ||||
| ;; | ||||
| esac | ||||
| ############### Precision selection | ||||
| AC_ARG_ENABLE([precision], | ||||
|               [AC_HELP_STRING([--enable-precision=single|double], | ||||
|                               [Select default word size of Real])], | ||||
|               [ac_PRECISION=${enable_precision}],[ac_PRECISION=double]) | ||||
|  | ||||
| AM_CONDITIONAL(BUILD_ZMM,[ test "X${ac_ZMM}X" == "XyesX" ]) | ||||
|  | ||||
| AC_ARG_ENABLE([precision],[AC_HELP_STRING([--enable-precision=single|double],[Select default word size of Real])],[ac_PRECISION=${enable_precision}],[ac_PRECISION=double]) | ||||
| case ${ac_PRECISION} in | ||||
|      single) | ||||
|        echo default precision is single | ||||
|        AC_DEFINE([GRID_DEFAULT_PRECISION_SINGLE],[1],[GRID_DEFAULT_PRECISION is SINGLE] ) | ||||
|      ;; | ||||
|      double) | ||||
|        echo default precision is double | ||||
|        AC_DEFINE([GRID_DEFAULT_PRECISION_DOUBLE],[1],[GRID_DEFAULT_PRECISION is DOUBLE] ) | ||||
|      ;; | ||||
| esac | ||||
|  | ||||
| # | ||||
| # Comms selection | ||||
| # | ||||
|  | ||||
| AC_ARG_ENABLE([comms],[AC_HELP_STRING([--enable-comms=none|mpi],[Select communications])],[ac_COMMS=${enable_comms}],[ac_COMMS=none]) | ||||
| ############### communication type selection | ||||
| AC_ARG_ENABLE([comms],[AC_HELP_STRING([--enable-comms=none|mpi|mpi-auto|mpi3|mpi3-auto|shmem], | ||||
|               [Select communications])],[ac_COMMS=${enable_comms}],[ac_COMMS=none]) | ||||
|  | ||||
| case ${ac_COMMS} in | ||||
|      none) | ||||
|        echo Configuring for NO communications | ||||
|        AC_DEFINE([GRID_COMMS_NONE],[1],[GRID_COMMS_NONE] ) | ||||
|         AC_DEFINE([GRID_COMMS_NONE],[1],[GRID_COMMS_NONE] ) | ||||
|         comms_type='none' | ||||
|      ;; | ||||
|      mpi) | ||||
|        echo Configuring for MPI communications | ||||
|        AC_DEFINE([GRID_COMMS_MPI],[1],[GRID_COMMS_MPI] ) | ||||
|      mpi3l*) | ||||
|        AC_DEFINE([GRID_COMMS_MPI3L],[1],[GRID_COMMS_MPI3L] ) | ||||
|        comms_type='mpi3l' | ||||
|      ;; | ||||
|      mpi3*) | ||||
|         AC_DEFINE([GRID_COMMS_MPI3],[1],[GRID_COMMS_MPI3] ) | ||||
|         comms_type='mpi3' | ||||
|      ;; | ||||
|      mpi*) | ||||
|         AC_DEFINE([GRID_COMMS_MPI],[1],[GRID_COMMS_MPI] ) | ||||
|         comms_type='mpi' | ||||
|      ;; | ||||
|      shmem) | ||||
|        echo Configuring for SHMEM communications | ||||
|        AC_DEFINE([GRID_COMMS_SHMEM],[1],[GRID_COMMS_SHMEM] ) | ||||
|         AC_DEFINE([GRID_COMMS_SHMEM],[1],[GRID_COMMS_SHMEM] ) | ||||
|         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 | ||||
|     *-auto) | ||||
|         LX_FIND_MPI | ||||
|         if test "x$have_CXX_mpi" = 'xno'; then AC_MSG_ERROR(["The configure could not find the MPI compilation flags. N.B. The -auto mode is not supported by Cray wrappers. Use the non -auto version in this case."]); fi | ||||
|         AM_CXXFLAGS="$MPI_CXXFLAGS $AM_CXXFLAGS" | ||||
|         AM_CFLAGS="$MPI_CFLAGS $AM_CFLAGS" | ||||
|         AM_LDFLAGS="`echo $MPI_CXXLDFLAGS | sed -E 's/-l@<:@^ @:>@+//g'` $AM_LDFLAGS" | ||||
|         LIBS="`echo $MPI_CXXLDFLAGS | sed -E 's/-L@<:@^ @:>@+//g'` $LIBS";; | ||||
|     *) | ||||
|         ;; | ||||
| esac | ||||
|  | ||||
| AM_CONDITIONAL(BUILD_COMMS_SHMEM,[ test "X${ac_COMMS}X" == "XshmemX" ]) | ||||
| AM_CONDITIONAL(BUILD_COMMS_MPI,[ test "X${ac_COMMS}X" == "XmpiX" ]) | ||||
| AM_CONDITIONAL(BUILD_COMMS_NONE,[ test "X${ac_COMMS}X" == "XnoneX" ]) | ||||
| AM_CONDITIONAL(BUILD_COMMS_SHMEM, [ test "${comms_type}X" == "shmemX" ]) | ||||
| AM_CONDITIONAL(BUILD_COMMS_MPI,   [ test "${comms_type}X" == "mpiX" ]) | ||||
| AM_CONDITIONAL(BUILD_COMMS_MPI3,  [ test "${comms_type}X" == "mpi3X" ] ) | ||||
| 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|sitmo],\ | ||||
| 	            [Select Random Number Generator to be used])],\ | ||||
| 	            [ac_RNG=${enable_rng}],[ac_RNG=sitmo]) | ||||
|  | ||||
| # | ||||
| # RNG selection | ||||
| # | ||||
| AC_ARG_ENABLE([rng],[AC_HELP_STRING([--enable-rng=ranlux48|mt19937],\ | ||||
| 	[Select Random Number Generator to be used])],\ | ||||
| 	[ac_RNG=${enable_rng}],[ac_RNG=ranlux48]) | ||||
| case ${ac_RNG} in | ||||
|      ranlux48) | ||||
|      AC_DEFINE([RNG_RANLUX],[1],[RNG_RANLUX] ) | ||||
|       AC_DEFINE([RNG_RANLUX],[1],[RNG_RANLUX] ) | ||||
|      ;; | ||||
|      mt19937) | ||||
|      AC_DEFINE([RNG_MT19937],[1],[RNG_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 | ||||
| # | ||||
| # Chroma regression tests | ||||
| # | ||||
| AC_ARG_ENABLE([chroma],[AC_HELP_STRING([--enable-chroma],[Expect chroma compiled under c++11 ])],ac_CHROMA=yes,ac_CHROMA=no) | ||||
|  | ||||
| case ${ac_CHROMA} in | ||||
| ############### Timer option | ||||
| AC_ARG_ENABLE([timers],[AC_HELP_STRING([--enable-timers],\ | ||||
| 	            [Enable system dependent high res timers])],\ | ||||
| 	            [ac_TIMERS=${enable_timers}],[ac_TIMERS=yes]) | ||||
|  | ||||
| case ${ac_TIMERS} in | ||||
|      yes) | ||||
|        echo Enabling tests regressing to Chroma | ||||
|       AC_DEFINE([TIMERS_ON],[1],[TIMERS_ON] ) | ||||
|      ;; | ||||
|      no) | ||||
|        echo Disabling tests regressing to Chroma | ||||
|       AC_DEFINE([TIMERS_OFF],[1],[TIMERS_OFF] ) | ||||
|      ;; | ||||
|      *) | ||||
|      AC_MSG_ERROR([${ac_CHROMA} unsupported --enable-chroma option]);  | ||||
|       AC_MSG_ERROR([${ac_TIMERS} unsupported --enable-timers option]);  | ||||
|      ;; | ||||
| esac | ||||
|  | ||||
| ############### Chroma regression test | ||||
| AC_ARG_ENABLE([chroma],[AC_HELP_STRING([--enable-chroma], | ||||
|               [Expect chroma compiled under c++11 ])],ac_CHROMA=yes,ac_CHROMA=no) | ||||
|  | ||||
| case ${ac_CHROMA} in | ||||
|      yes|no) | ||||
|      ;; | ||||
|      *) | ||||
|        AC_MSG_ERROR([${ac_CHROMA} unsupported --enable-chroma option]);  | ||||
|      ;; | ||||
| esac | ||||
|  | ||||
| AM_CONDITIONAL(BUILD_CHROMA_REGRESSION,[ test "X${ac_CHROMA}X" == "XyesX" ]) | ||||
|  | ||||
| # | ||||
| # Lapack | ||||
| # | ||||
| AC_ARG_ENABLE([lapack],[AC_HELP_STRING([--enable-lapack],[Enable lapack yes/no ])],[ac_LAPACK=${enable_lapack}],[ac_LAPACK=no]) | ||||
| ############### Doxygen | ||||
| DX_DOXYGEN_FEATURE([OFF]) | ||||
| DX_DOT_FEATURE([OFF]) | ||||
| DX_HTML_FEATURE([ON]) | ||||
| DX_CHM_FEATURE([OFF]) | ||||
| DX_CHI_FEATURE([OFF]) | ||||
| DX_MAN_FEATURE([OFF]) | ||||
| DX_RTF_FEATURE([OFF]) | ||||
| DX_XML_FEATURE([OFF]) | ||||
| DX_PDF_FEATURE([OFF]) | ||||
| DX_PS_FEATURE([OFF]) | ||||
| DX_INIT_DOXYGEN([$PACKAGE_NAME], [doxygen.cfg]) | ||||
|  | ||||
| case ${ac_LAPACK} in | ||||
|      yes) | ||||
|        echo Enabling lapack | ||||
|      ;; | ||||
|      no) | ||||
|        echo Disabling lapack | ||||
|      ;; | ||||
|      *) | ||||
|        echo Enabling lapack at ${ac_LAPACK} | ||||
|      ;; | ||||
| esac | ||||
|  | ||||
| AM_CONDITIONAL(USE_LAPACK,[ test "X${ac_LAPACK}X" != "XnoX" ]) | ||||
| AM_CONDITIONAL(USE_LAPACK_LIB,[ test "X${ac_LAPACK}X" != "XyesX" ]) | ||||
|  | ||||
| ################################################################### | ||||
| # Checks for doxygen support | ||||
| # if present enables the "make doxyfile" command | ||||
| #echo | ||||
| #echo Checking doxygen support  | ||||
| #echo ::::::::::::::::::::::::::::::::::::::::::: | ||||
| #AC_PROG_DOXYGEN | ||||
|  | ||||
| #if test -n "$DOXYGEN" | ||||
| #then | ||||
| #AC_CONFIG_FILES([docs/doxy.cfg]) | ||||
| #fi | ||||
|  | ||||
| echo | ||||
| echo Creating configuration files | ||||
| echo ::::::::::::::::::::::::::::::::::::::::::: | ||||
| ############### Ouput | ||||
| cwd=`pwd -P`; cd ${srcdir}; abs_srcdir=`pwd -P`; cd ${cwd} | ||||
| 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/hadrons/Makefile) | ||||
| AC_CONFIG_FILES(tests/hmc/Makefile) | ||||
| AC_CONFIG_FILES(tests/solver/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 " | ||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
| Summary of configuration for $PACKAGE v$VERSION | ||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||
|  | ||||
| The following features are enabled: | ||||
|  | ||||
| - architecture (build)          : $build_cpu | ||||
| - os (build)                    : $build_os | ||||
| - architecture (target)         : $target_cpu | ||||
| - os (target)                   : $target_os | ||||
| - build DOXYGEN documentation   : `if test "x$enable_doc" = xyes; then echo yes; else echo no; fi` | ||||
| - graphs and diagrams           : `if test "x$enable_dot" = xyes; then echo yes; else echo no; fi` | ||||
| - Supported SIMD flags          : $SIMD_FLAGS | ||||
| ---------------------------------------------------------- | ||||
| - enabled simd support          : ${ac_SIMD}   (config macro says supported: $supported ) | ||||
| - communications type           : ${ac_COMMS} | ||||
| - default precision             : ${ac_PRECISION} | ||||
| - RNG choice                    : ${ac_RNG}  | ||||
| - LAPACK	                : ${ac_LAPACK}  | ||||
|  | ||||
|  | ||||
| " | ||||
| ----- PLATFORM ---------------------------------------- | ||||
| architecture (build)        : $build_cpu | ||||
| os (build)                  : $build_os | ||||
| architecture (target)       : $target_cpu | ||||
| os (target)                 : $target_os | ||||
| 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}  | ||||
| Communications type         : ${comms_type} | ||||
| Default precision           : ${ac_PRECISION} | ||||
| 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` | ||||
| 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: | ||||
| `echo ${AM_CXXFLAGS} ${CXXFLAGS} | tr ' ' '\n' | sed 's/^-/    -/g'` | ||||
| LDFLAGS: | ||||
| `echo ${AM_LDFLAGS} ${LDFLAGS} | tr ' ' '\n' | sed 's/^-/    -/g'` | ||||
| LIBS: | ||||
| `echo ${LIBS} | tr ' ' '\n' | sed 's/^-/    -/g'` | ||||
| -------------------------------------------------------" > config.summary | ||||
| echo "" | ||||
| cat config.summary | ||||
| echo "" | ||||
|   | ||||
							
								
								
									
										2305
									
								
								docs/doxy.cfg.in
									
									
									
									
									
								
							
							
						
						
									
										2305
									
								
								docs/doxy.cfg.in
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										184
									
								
								doxygen.inc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										184
									
								
								doxygen.inc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,184 @@ | ||||
| # Copyright (C) 2004 Oren Ben-Kiki | ||||
| # This file is distributed under the same terms as the Automake macro files. | ||||
|  | ||||
| # Generate automatic documentation using Doxygen. Goals and variables values | ||||
| # are controlled by the various DX_COND_??? conditionals set by autoconf. | ||||
| # | ||||
| # The provided goals are: | ||||
| # doxygen-doc: Generate all doxygen documentation. | ||||
| # doxygen-run: Run doxygen, which will generate some of the documentation | ||||
| #              (HTML, CHM, CHI, MAN, RTF, XML) but will not do the post | ||||
| #              processing required for the rest of it (PS, PDF, and some MAN). | ||||
| # doxygen-man: Rename some doxygen generated man pages. | ||||
| # doxygen-ps: Generate doxygen PostScript documentation. | ||||
| # doxygen-pdf: Generate doxygen PDF documentation. | ||||
| # | ||||
| # Note that by default these are not integrated into the automake goals. If | ||||
| # doxygen is used to generate man pages, you can achieve this integration by | ||||
| # setting man3_MANS to the list of man pages generated and then adding the | ||||
| # dependency: | ||||
| # | ||||
| #   $(man3_MANS): doxygen-doc | ||||
| # | ||||
| # This will cause make to run doxygen and generate all the documentation. | ||||
| # | ||||
| # The following variable is intended for use in Makefile.am: | ||||
| # | ||||
| # DX_CLEANFILES = everything to clean. | ||||
| # | ||||
| # This is usually added to MOSTLYCLEANFILES. | ||||
|  | ||||
| ## --------------------------------- ## | ||||
| ## Format-independent Doxygen rules. ## | ||||
| ## --------------------------------- ## | ||||
|  | ||||
| if DX_COND_doc | ||||
|  | ||||
| ## ------------------------------- ## | ||||
| ## Rules specific for HTML output. ## | ||||
| ## ------------------------------- ## | ||||
|  | ||||
| if DX_COND_html | ||||
|  | ||||
| DX_CLEAN_HTML = @DX_DOCDIR@/html | ||||
|  | ||||
| endif DX_COND_html | ||||
|  | ||||
| ## ------------------------------ ## | ||||
| ## Rules specific for CHM output. ## | ||||
| ## ------------------------------ ## | ||||
|  | ||||
| if DX_COND_chm | ||||
|  | ||||
| DX_CLEAN_CHM = @DX_DOCDIR@/chm | ||||
|  | ||||
| if DX_COND_chi | ||||
|  | ||||
| DX_CLEAN_CHI = @DX_DOCDIR@/@PACKAGE@.chi | ||||
|  | ||||
| endif DX_COND_chi | ||||
|  | ||||
| endif DX_COND_chm | ||||
|  | ||||
| ## ------------------------------ ## | ||||
| ## Rules specific for MAN output. ## | ||||
| ## ------------------------------ ## | ||||
|  | ||||
| if DX_COND_man | ||||
|  | ||||
| DX_CLEAN_MAN = @DX_DOCDIR@/man | ||||
|  | ||||
| endif DX_COND_man | ||||
|  | ||||
| ## ------------------------------ ## | ||||
| ## Rules specific for RTF output. ## | ||||
| ## ------------------------------ ## | ||||
|  | ||||
| if DX_COND_rtf | ||||
|  | ||||
| DX_CLEAN_RTF = @DX_DOCDIR@/rtf | ||||
|  | ||||
| endif DX_COND_rtf | ||||
|  | ||||
| ## ------------------------------ ## | ||||
| ## Rules specific for XML output. ## | ||||
| ## ------------------------------ ## | ||||
|  | ||||
| if DX_COND_xml | ||||
|  | ||||
| DX_CLEAN_XML = @DX_DOCDIR@/xml | ||||
|  | ||||
| endif DX_COND_xml | ||||
|  | ||||
| ## ----------------------------- ## | ||||
| ## Rules specific for PS output. ## | ||||
| ## ----------------------------- ## | ||||
|  | ||||
| if DX_COND_ps | ||||
|  | ||||
| DX_CLEAN_PS = @DX_DOCDIR@/@PACKAGE@.ps | ||||
|  | ||||
| DX_PS_GOAL = doxygen-ps | ||||
|  | ||||
| doxygen-ps: @DX_DOCDIR@/@PACKAGE@.ps | ||||
|  | ||||
| @DX_DOCDIR@/@PACKAGE@.ps: @DX_DOCDIR@/@PACKAGE@.tag | ||||
| 	cd @DX_DOCDIR@/latex; \ | ||||
| 	rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \ | ||||
| 	$(DX_LATEX) refman.tex; \ | ||||
| 	$(MAKEINDEX_PATH) refman.idx; \ | ||||
| 	$(DX_LATEX) refman.tex; \ | ||||
| 	countdown=5; \ | ||||
| 	while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \ | ||||
| 	                  refman.log > /dev/null 2>&1 \ | ||||
| 	   && test $$countdown -gt 0; do \ | ||||
| 	    $(DX_LATEX) refman.tex; \ | ||||
| 	    countdown=`expr $$countdown - 1`; \ | ||||
| 	done; \ | ||||
| 	$(DX_DVIPS) -o ../@PACKAGE@.ps refman.dvi | ||||
|  | ||||
| endif DX_COND_ps | ||||
|  | ||||
| ## ------------------------------ ## | ||||
| ## Rules specific for PDF output. ## | ||||
| ## ------------------------------ ## | ||||
|  | ||||
| if DX_COND_pdf | ||||
|  | ||||
| DX_CLEAN_PDF = @DX_DOCDIR@/@PACKAGE@.pdf | ||||
|  | ||||
| DX_PDF_GOAL = doxygen-pdf | ||||
|  | ||||
| doxygen-pdf: @DX_DOCDIR@/@PACKAGE@.pdf | ||||
|  | ||||
| @DX_DOCDIR@/@PACKAGE@.pdf: @DX_DOCDIR@/@PACKAGE@.tag | ||||
| 	cd @DX_DOCDIR@/latex; \ | ||||
| 	rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \ | ||||
| 	$(DX_PDFLATEX) refman.tex; \ | ||||
| 	$(DX_MAKEINDEX) refman.idx; \ | ||||
| 	$(DX_PDFLATEX) refman.tex; \ | ||||
| 	countdown=5; \ | ||||
| 	while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \ | ||||
| 	                  refman.log > /dev/null 2>&1 \ | ||||
| 	   && test $$countdown -gt 0; do \ | ||||
| 	    $(DX_PDFLATEX) refman.tex; \ | ||||
| 	    countdown=`expr $$countdown - 1`; \ | ||||
| 	done; \ | ||||
| 	mv refman.pdf ../@PACKAGE@.pdf | ||||
|  | ||||
| endif DX_COND_pdf | ||||
|  | ||||
| ## ------------------------------------------------- ## | ||||
| ## Rules specific for LaTeX (shared for PS and PDF). ## | ||||
| ## ------------------------------------------------- ## | ||||
|  | ||||
| if DX_COND_latex | ||||
|  | ||||
| DX_CLEAN_LATEX = @DX_DOCDIR@/latex | ||||
|  | ||||
| endif DX_COND_latex | ||||
|  | ||||
| .INTERMEDIATE: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL) | ||||
|  | ||||
| doxygen-run: @DX_DOCDIR@/@PACKAGE@.tag | ||||
|  | ||||
| doxygen-doc: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL) | ||||
|  | ||||
| @DX_DOCDIR@/@PACKAGE@.tag: $(DX_CONFIG) $(pkginclude_HEADERS) | ||||
| 	rm -rf @DX_DOCDIR@ | ||||
| 	$(DX_ENV) $(DX_DOXYGEN) $(srcdir)/$(DX_CONFIG) | ||||
|  | ||||
| DX_CLEANFILES = \ | ||||
|     @DX_DOCDIR@/@PACKAGE@.tag \ | ||||
|     -r \ | ||||
|     $(DX_CLEAN_HTML) \ | ||||
|     $(DX_CLEAN_CHM) \ | ||||
|     $(DX_CLEAN_CHI) \ | ||||
|     $(DX_CLEAN_MAN) \ | ||||
|     $(DX_CLEAN_RTF) \ | ||||
|     $(DX_CLEAN_XML) \ | ||||
|     $(DX_CLEAN_PS) \ | ||||
|     $(DX_CLEAN_PDF) \ | ||||
|     $(DX_CLEAN_LATEX) | ||||
|  | ||||
| endif DX_COND_doc | ||||
							
								
								
									
										317
									
								
								extras/Hadrons/Application.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										317
									
								
								extras/Hadrons/Application.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,317 @@ | ||||
| /************************************************************************************* | ||||
|  | ||||
| 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 \ | ||||
| auto 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; | ||||
| } | ||||
							
								
								
									
										150
									
								
								extras/Hadrons/Global.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										150
									
								
								extras/Hadrons/Global.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,150 @@ | ||||
| /************************************************************************************* | ||||
|  | ||||
| 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>()); | ||||
| } | ||||
|  | ||||
| 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_ | ||||
							
								
								
									
										40
									
								
								extras/Hadrons/Modules.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								extras/Hadrons/Modules.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | ||||
| /************************************************************************************* | ||||
|  | ||||
| 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/Meson.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/MSolver/RBPrecCG.hpp> | ||||
| #include <Grid/Hadrons/Modules/MSource/Point.hpp> | ||||
| #include <Grid/Hadrons/Modules/MSource/SeqGamma.hpp> | ||||
| #include <Grid/Hadrons/Modules/MSource/Z2.hpp> | ||||
| #include <Grid/Hadrons/Modules/Quark.hpp> | ||||
							
								
								
									
										134
									
								
								extras/Hadrons/Modules/MAction/DWF.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								extras/Hadrons/Modules/MAction/DWF.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,134 @@ | ||||
| /************************************************************************************* | ||||
|  | ||||
| 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); | ||||
| }; | ||||
|  | ||||
| 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; | ||||
|     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); | ||||
|     FMat *fMatPt = new DomainWallFermion<FImpl>(U, g5, grb5, g4, grb4, | ||||
|                                                 par().mass, par().M5); | ||||
|     env().setObject(getName(), fMatPt); | ||||
| } | ||||
|  | ||||
| END_MODULE_NAMESPACE | ||||
|  | ||||
| END_HADRONS_NAMESPACE | ||||
|  | ||||
| #endif // Hadrons_DWF_hpp_ | ||||
							
								
								
									
										126
									
								
								extras/Hadrons/Modules/MAction/Wilson.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								extras/Hadrons/Modules/MAction/Wilson.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,126 @@ | ||||
| /************************************************************************************* | ||||
|  | ||||
| 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); | ||||
| }; | ||||
|  | ||||
| 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; | ||||
|     auto &U      = *env().template getObject<LatticeGaugeField>(par().gauge); | ||||
|     auto &grid   = *env().getGrid(); | ||||
|     auto &gridRb = *env().getRbGrid(); | ||||
|     FMat *fMatPt = new WilsonFermion<FImpl>(U, grid, gridRb, par().mass); | ||||
|     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; | ||||
|      | ||||
|     XmlWriter             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_ | ||||
							
								
								
									
										137
									
								
								extras/Hadrons/Modules/MContraction/Meson.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										137
									
								
								extras/Hadrons/Modules/MContraction/Meson.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,137 @@ | ||||
| /************************************************************************************* | ||||
|  | ||||
| Grid physics library, www.github.com/paboyle/Grid  | ||||
|  | ||||
| Source file: extras/Hadrons/Modules/MContraction/Meson.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_Meson_hpp_ | ||||
| #define Hadrons_Meson_hpp_ | ||||
|  | ||||
| #include <Grid/Hadrons/Global.hpp> | ||||
| #include <Grid/Hadrons/Module.hpp> | ||||
| #include <Grid/Hadrons/ModuleFactory.hpp> | ||||
|  | ||||
| BEGIN_HADRONS_NAMESPACE | ||||
|  | ||||
| /****************************************************************************** | ||||
|  *                                TMeson                                       * | ||||
|  ******************************************************************************/ | ||||
| BEGIN_MODULE_NAMESPACE(MContraction) | ||||
|  | ||||
| class MesonPar: Serializable | ||||
| { | ||||
| public: | ||||
|     GRID_SERIALIZABLE_CLASS_MEMBERS(MesonPar, | ||||
|                                     std::string,    q1, | ||||
|                                     std::string,    q2, | ||||
|                                     std::string,    output, | ||||
|                                     Gamma::Algebra, gammaSource, | ||||
|                                     Gamma::Algebra, gammaSink); | ||||
| }; | ||||
|  | ||||
| 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, 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); | ||||
|     // 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; | ||||
| } | ||||
|  | ||||
| // 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; | ||||
|      | ||||
|     XmlWriter             writer(par().output); | ||||
|     PropagatorField1      &q1 = *env().template getObject<PropagatorField1>(par().q1); | ||||
|     PropagatorField2      &q2 = *env().template getObject<PropagatorField2>(par().q2); | ||||
|     LatticeComplex        c(env().getGrid()); | ||||
|     Gamma                 gSrc(par().gammaSource), gSnk(par().gammaSink); | ||||
|     Gamma                 g5(Gamma::Algebra::Gamma5); | ||||
|     std::vector<TComplex> buf; | ||||
|     Result                result; | ||||
|      | ||||
|     c = trace(gSnk*q1*adj(gSrc)*g5*adj(q2)*g5); | ||||
|     sliceSum(c, buf, Tp); | ||||
|     result.corr.resize(buf.size()); | ||||
|     for (unsigned int t = 0; t < buf.size(); ++t) | ||||
|     { | ||||
|         result.corr[t] = TensorRemove(buf[t]); | ||||
|     } | ||||
|     write(writer, "meson", result); | ||||
| } | ||||
|  | ||||
| END_MODULE_NAMESPACE | ||||
|  | ||||
| END_HADRONS_NAMESPACE | ||||
|  | ||||
| #endif // Hadrons_Meson_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) | ||||
| { | ||||
|     NerscField  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_nersc_header(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/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_ | ||||
							
								
								
									
										163
									
								
								extras/Hadrons/Modules/MSource/SeqGamma.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										163
									
								
								extras/Hadrons/Modules/MSource/SeqGamma.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,163 @@ | ||||
| /************************************************************************************* | ||||
|  | ||||
| Grid physics library, www.github.com/paboyle/Grid  | ||||
|  | ||||
| Source file: extras/Hadrons/Modules/MSource/SeqGamma.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_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; | ||||
|     } | ||||
|     ph = exp(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_ | ||||
							
								
								
									
										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, 0., 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 | ||||
							
								
								
									
										19
									
								
								extras/Hadrons/modules.inc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								extras/Hadrons/modules.inc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | ||||
| modules_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/Meson.hpp \ | ||||
|   Modules/MGauge/Load.hpp \ | ||||
|   Modules/MGauge/Random.hpp \ | ||||
|   Modules/MGauge/Unit.hpp \ | ||||
|   Modules/MSolver/RBPrecCG.hpp \ | ||||
|   Modules/MSource/Point.hpp \ | ||||
|   Modules/MSource/SeqGamma.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 | ||||
							
								
								
									
										1
									
								
								include/Grid
									
									
									
									
									
										Symbolic link
									
								
							
							
						
						
									
										1
									
								
								include/Grid
									
									
									
									
									
										Symbolic link
									
								
							| @@ -0,0 +1 @@ | ||||
| ../lib | ||||
							
								
								
									
										51
									
								
								lib/Grid.h
									
									
									
									
									
								
							
							
						
						
									
										51
									
								
								lib/Grid.h
									
									
									
									
									
								
							| @@ -38,51 +38,10 @@ 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 <serialisation/Serialisation.h> | ||||
| #include <Config.h> | ||||
| #include <Timer.h> | ||||
| #include <PerfCount.h> | ||||
| #include <Log.h> | ||||
| #include <AlignedAllocator.h> | ||||
| #include <Simd.h> | ||||
| #include <Threads.h> | ||||
| #include <Lexicographic.h> | ||||
| #include <Communicator.h>  | ||||
| #include <Cartesian.h>     | ||||
| #include <Tensors.h>       | ||||
| #include <Lattice.h>       | ||||
| #include <Cshift.h>        | ||||
| #include <Stencil.h>       | ||||
| #include <Algorithms.h>    | ||||
| #include <parallelIO/BinaryIO.h> | ||||
| #include <qcd/QCD.h> | ||||
| #include <parallelIO/NerscIO.h> | ||||
| #include <Init.h> | ||||
|  | ||||
| #include <qcd/hmc/NerscCheckpointer.h> | ||||
| #include <qcd/hmc/HmcRunner.h> | ||||
|  | ||||
|  | ||||
| #include <Grid/GridCore.h> | ||||
| #include <Grid/GridQCDcore.h> | ||||
| #include <Grid/qcd/action/Action.h> | ||||
| #include <Grid/qcd/smearing/Smearing.h> | ||||
| #include <Grid/qcd/hmc/HMC_aggregate.h> | ||||
|  | ||||
| #endif | ||||
|   | ||||
							
								
								
									
										81
									
								
								lib/GridCore.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								lib/GridCore.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,81 @@ | ||||
|     /************************************************************************************* | ||||
|  | ||||
|     Grid physics library, www.github.com/paboyle/Grid  | ||||
|  | ||||
|     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 | ||||
|     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 */ | ||||
| // | ||||
| //  Grid.h | ||||
| //  simd | ||||
| // | ||||
| //  Created by Peter Boyle on 09/05/2014. | ||||
| //  Copyright (c) 2014 University of Edinburgh. All rights reserved. | ||||
| // | ||||
|  | ||||
| #ifndef GRID_BASE_H | ||||
| #define GRID_BASE_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 "Config.h" | ||||
|  | ||||
| #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>    | ||||
|  | ||||
| #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 | ||||
							
								
								
									
										1
									
								
								lib/Hadrons
									
									
									
									
									
										Symbolic link
									
								
							
							
						
						
									
										1
									
								
								lib/Hadrons
									
									
									
									
									
										Symbolic link
									
								
							| @@ -0,0 +1 @@ | ||||
| ../extras/Hadrons | ||||
							
								
								
									
										343
									
								
								lib/Init.cc
									
									
									
									
									
								
							
							
						
						
									
										343
									
								
								lib/Init.cc
									
									
									
									
									
								
							| @@ -1,343 +0,0 @@ | ||||
|     /************************************************************************************* | ||||
|  | ||||
|     Grid physics library, www.github.com/paboyle/Grid  | ||||
|  | ||||
|     Source file: ./lib/Init.cc | ||||
|  | ||||
|     Copyright (C) 2015 | ||||
|  | ||||
| Author: Azusa Yamaguchi <ayamaguc@staffmail.ed.ac.uk> | ||||
| Author: Peter Boyle <paboyle@ph.ed.ac.uk> | ||||
| Author: Peter Boyle <peterboyle@MacBook-Pro.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 | ||||
|     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 */ | ||||
| /****************************************************************************/ | ||||
| /* pab: Signal magic. Processor state dump is x86-64 specific               */ | ||||
| /****************************************************************************/ | ||||
| #include <stdlib.h> | ||||
| #include <stdio.h> | ||||
| #include <stdint.h> | ||||
| #include <unistd.h> | ||||
| #include <sys/mman.h> | ||||
| #include <sys/stat.h>  | ||||
| #include <sys/time.h> | ||||
| #include <signal.h> | ||||
| #include <iostream> | ||||
| #include <iterator> | ||||
| #include <Grid.h> | ||||
| #include <algorithm> | ||||
| #include <iterator> | ||||
|  | ||||
| namespace Grid { | ||||
|  | ||||
| ////////////////////////////////////////////////////// | ||||
| // Convenience functions to access stadard command line arg | ||||
| // driven parallelism controls | ||||
| ////////////////////////////////////////////////////// | ||||
| static std::vector<int> Grid_default_latt; | ||||
| static std::vector<int> Grid_default_mpi; | ||||
|  | ||||
| int GridThread::_threads =1; | ||||
| int GridThread::_hyperthreads=1; | ||||
| int GridThread::_cores=1; | ||||
|  | ||||
| const std::vector<int> &GridDefaultLatt(void)     {return Grid_default_latt;}; | ||||
| const std::vector<int> &GridDefaultMpi(void)      {return Grid_default_mpi;}; | ||||
| const std::vector<int> GridDefaultSimd(int dims,int nsimd) | ||||
| { | ||||
|     std::vector<int> layout(dims); | ||||
|     int nn=nsimd; | ||||
|     for(int d=dims-1;d>=0;d--){ | ||||
|       if ( nn>=2) { | ||||
| 	layout[d]=2; | ||||
| 	nn/=2; | ||||
|       } else {  | ||||
| 	layout[d]=1; | ||||
|       } | ||||
|     } | ||||
|     assert(nn==1); | ||||
|     return layout; | ||||
| } | ||||
|    | ||||
| //////////////////////////////////////////////////////////// | ||||
| // Command line parsing assist for stock controls | ||||
| //////////////////////////////////////////////////////////// | ||||
| std::string GridCmdOptionPayload(char ** begin, char ** end, const std::string & option) | ||||
| { | ||||
|   char ** itr = std::find(begin, end, option); | ||||
|   if (itr != end && ++itr != end) { | ||||
|     std::string payload(*itr); | ||||
|     return payload; | ||||
|   } | ||||
|   return std::string(""); | ||||
| } | ||||
| bool GridCmdOptionExists(char** begin, char** end, const std::string& option) | ||||
| { | ||||
|   return std::find(begin, end, option) != end; | ||||
| } | ||||
|   // Comma separated list | ||||
| void GridCmdOptionCSL(std::string str,std::vector<std::string> & vec) | ||||
| { | ||||
|   size_t pos = 0; | ||||
|   std::string token; | ||||
|   std::string delimiter(","); | ||||
|  | ||||
|   vec.resize(0); | ||||
|   while ((pos = str.find(delimiter)) != std::string::npos) { | ||||
|     token = str.substr(0, pos); | ||||
|     vec.push_back(token); | ||||
|     str.erase(0, pos + delimiter.length()); | ||||
|   } | ||||
|   token = str; | ||||
|   vec.push_back(token); | ||||
|   return; | ||||
| } | ||||
|  | ||||
| void GridCmdOptionIntVector(std::string &str,std::vector<int> & vec) | ||||
| { | ||||
|   vec.resize(0); | ||||
|   std::stringstream ss(str); | ||||
|   int i; | ||||
|   while (ss >> i){ | ||||
|     vec.push_back(i); | ||||
|     if(std::ispunct(ss.peek())) | ||||
|       ss.ignore(); | ||||
|   }     | ||||
|   return; | ||||
| } | ||||
|  | ||||
|  | ||||
| void GridParseLayout(char **argv,int argc, | ||||
| 		     std::vector<int> &latt, | ||||
| 		     std::vector<int> &mpi) | ||||
| { | ||||
|   mpi =std::vector<int>({1,1,1,1}); | ||||
|   latt=std::vector<int>({8,8,8,8}); | ||||
|  | ||||
|   GridThread::SetMaxThreads(); | ||||
|  | ||||
|   std::string arg; | ||||
|   if( GridCmdOptionExists(argv,argv+argc,"--mpi") ){ | ||||
|     arg = GridCmdOptionPayload(argv,argv+argc,"--mpi"); | ||||
|     GridCmdOptionIntVector(arg,mpi); | ||||
|   } | ||||
|   if( GridCmdOptionExists(argv,argv+argc,"--grid") ){ | ||||
|     arg= GridCmdOptionPayload(argv,argv+argc,"--grid"); | ||||
|     GridCmdOptionIntVector(arg,latt); | ||||
|   } | ||||
|   if( GridCmdOptionExists(argv,argv+argc,"--threads") ){ | ||||
|     std::vector<int> ompthreads(0); | ||||
| #ifndef GRID_OMP | ||||
|     std::cout << GridLogWarning << "'--threads' option used but Grid was" | ||||
|               << " not compiled with thread support" << std::endl; | ||||
| #endif | ||||
|     arg= GridCmdOptionPayload(argv,argv+argc,"--threads"); | ||||
|     GridCmdOptionIntVector(arg,ompthreads); | ||||
|     assert(ompthreads.size()==1); | ||||
|     GridThread::SetThreads(ompthreads[0]); | ||||
|   } | ||||
|   if( GridCmdOptionExists(argv,argv+argc,"--cores") ){ | ||||
|     std::vector<int> cores(0); | ||||
|     arg= GridCmdOptionPayload(argv,argv+argc,"--cores"); | ||||
|     GridCmdOptionIntVector(arg,cores); | ||||
|     GridThread::SetCores(cores[0]); | ||||
|   } | ||||
|  | ||||
| } | ||||
|  | ||||
| std::string GridCmdVectorIntToString(const std::vector<int> & vec){ | ||||
|   std::ostringstream oss; | ||||
|   std::copy(vec.begin(), vec.end(),std::ostream_iterator<int>(oss, " ")); | ||||
|   return oss.str(); | ||||
| } | ||||
| ///////////////////////////////////////////////////////// | ||||
| // | ||||
| ///////////////////////////////////////////////////////// | ||||
| void Grid_init(int *argc,char ***argv) | ||||
| { | ||||
|   CartesianCommunicator::Init(argc,argv); | ||||
|  | ||||
|   // Parse command line args. | ||||
|  | ||||
|   GridLogger::StopWatch.Start(); | ||||
|  | ||||
|   std::string arg; | ||||
|   std::vector<std::string> logstreams; | ||||
|   std::string defaultLog("Error,Warning,Message,Performance"); | ||||
|  | ||||
|   GridCmdOptionCSL(defaultLog,logstreams); | ||||
|   GridLogConfigure(logstreams); | ||||
|  | ||||
|   if( GridCmdOptionExists(*argv,*argv+*argc,"--help") ){ | ||||
|     std::cout<<GridLogMessage<<"--help : this message"<<std::endl; | ||||
|     std::cout<<GridLogMessage<<"--debug-signals : catch sigsegv and print a blame report"<<std::endl; | ||||
|     std::cout<<GridLogMessage<<"--debug-stdout  : print stdout from EVERY node"<<std::endl;     | ||||
|     std::cout<<GridLogMessage<<"--decomposition : report on default omp,mpi and simd decomposition"<<std::endl;     | ||||
|     std::cout<<GridLogMessage<<"--mpi n.n.n.n   : default MPI decomposition"<<std::endl;     | ||||
|     std::cout<<GridLogMessage<<"--threads n     : default number of OMP threads"<<std::endl; | ||||
|     std::cout<<GridLogMessage<<"--grid n.n.n.n  : default Grid size"<<std::endl;     | ||||
|     std::cout<<GridLogMessage<<"--log list      : comma separted list of streams from Error,Warning,Message,Performance,Iterative,Integrator,Debug"<<std::endl; | ||||
|     exit(EXIT_SUCCESS); | ||||
|   } | ||||
|  | ||||
|   if( GridCmdOptionExists(*argv,*argv+*argc,"--log") ){ | ||||
|     arg = GridCmdOptionPayload(*argv,*argv+*argc,"--log"); | ||||
|     GridCmdOptionCSL(arg,logstreams); | ||||
|     GridLogConfigure(logstreams); | ||||
|   } | ||||
|  | ||||
|  | ||||
|   if( GridCmdOptionExists(*argv,*argv+*argc,"--debug-signals") ){ | ||||
|     Grid_debug_handler_init(); | ||||
|   } | ||||
|   if( !GridCmdOptionExists(*argv,*argv+*argc,"--debug-stdout") ){ | ||||
|     Grid_quiesce_nodes(); | ||||
|   } | ||||
|   if( GridCmdOptionExists(*argv,*argv+*argc,"--dslash-opt") ){ | ||||
|     QCD::WilsonFermionStatic::HandOptDslash=1; | ||||
|     QCD::WilsonFermion5DStatic::HandOptDslash=1; | ||||
|   } | ||||
|   if( GridCmdOptionExists(*argv,*argv+*argc,"--lebesgue") ){ | ||||
|     LebesgueOrder::UseLebesgueOrder=1; | ||||
|   } | ||||
|  | ||||
|   if( GridCmdOptionExists(*argv,*argv+*argc,"--cacheblocking") ){ | ||||
|     arg= GridCmdOptionPayload(*argv,*argv+*argc,"--cacheblocking"); | ||||
|     GridCmdOptionIntVector(arg,LebesgueOrder::Block); | ||||
|   } | ||||
|   GridParseLayout(*argv,*argc, | ||||
| 		  Grid_default_latt, | ||||
| 		  Grid_default_mpi); | ||||
|   if( GridCmdOptionExists(*argv,*argv+*argc,"--decomposition") ){ | ||||
|     std::cout<<GridLogMessage<<"Grid Decomposition\n"; | ||||
|     std::cout<<GridLogMessage<<"\tOpenMP threads : "<<GridThread::GetThreads()<<std::endl; | ||||
|     std::cout<<GridLogMessage<<"\tMPI tasks      : "<<GridCmdVectorIntToString(GridDefaultMpi())<<std::endl; | ||||
|     std::cout<<GridLogMessage<<"\tvRealF         : "<<sizeof(vRealF)*8    <<"bits ; " <<GridCmdVectorIntToString(GridDefaultSimd(4,vRealF::Nsimd()))<<std::endl; | ||||
|     std::cout<<GridLogMessage<<"\tvRealD         : "<<sizeof(vRealD)*8    <<"bits ; " <<GridCmdVectorIntToString(GridDefaultSimd(4,vRealD::Nsimd()))<<std::endl; | ||||
|     std::cout<<GridLogMessage<<"\tvComplexF      : "<<sizeof(vComplexF)*8 <<"bits ; " <<GridCmdVectorIntToString(GridDefaultSimd(4,vComplexF::Nsimd()))<<std::endl; | ||||
|     std::cout<<GridLogMessage<<"\tvComplexD      : "<<sizeof(vComplexD)*8 <<"bits ; " <<GridCmdVectorIntToString(GridDefaultSimd(4,vComplexD::Nsimd()))<<std::endl; | ||||
|   } | ||||
|  | ||||
|   std::cout <<std::endl; | ||||
|   std::cout <<Logger::RED  << "__|__|__|__|__"<<             "|__|__|_"<<Logger::PURPLE<<"_|__|__|"<<                "__|__|__|__|__"<<std::endl;  | ||||
|   std::cout <<Logger::RED  << "__|__|__|__|__"<<             "|__|__|_"<<Logger::PURPLE<<"_|__|__|"<<                "__|__|__|__|__"<<std::endl;  | ||||
|   std::cout <<Logger::RED  << "__|__|  |  |  "<<             "|  |  | "<<Logger::PURPLE<<" |  |  |"<<                "  |  |  | _|__"<<std::endl;  | ||||
|   std::cout <<Logger::RED  << "__|__         "<<             "        "<<Logger::PURPLE<<"        "<<                "          _|__"<<std::endl;  | ||||
|   std::cout <<Logger::RED  << "__|_  "<<Logger::GREEN<<" GGGG   "<<Logger::RED<<" RRRR   "<<Logger::BLUE  <<" III    "<<Logger::PURPLE<<"DDDD  "<<Logger::PURPLE<<"    _|__"<<std::endl; | ||||
|   std::cout <<Logger::RED  << "__|_  "<<Logger::GREEN<<"G       "<<Logger::RED<<" R   R  "<<Logger::BLUE  <<"  I     "<<Logger::PURPLE<<"D   D "<<Logger::PURPLE<<"    _|__"<<std::endl; | ||||
|   std::cout <<Logger::RED  << "__|_  "<<Logger::GREEN<<"G       "<<Logger::RED<<" R   R  "<<Logger::BLUE  <<"  I     "<<Logger::PURPLE<<"D    D"<<Logger::PURPLE<<"    _|__"<<std::endl; | ||||
|   std::cout <<Logger::BLUE << "__|_  "<<Logger::GREEN<<"G  GG   "<<Logger::RED<<" RRRR   "<<Logger::BLUE  <<"  I     "<<Logger::PURPLE<<"D    D"<<Logger::GREEN <<"    _|__"<<std::endl; | ||||
|   std::cout <<Logger::BLUE << "__|_  "<<Logger::GREEN<<"G   G   "<<Logger::RED<<" R  R   "<<Logger::BLUE  <<"  I     "<<Logger::PURPLE<<"D   D "<<Logger::GREEN <<"    _|__"<<std::endl; | ||||
|   std::cout <<Logger::BLUE << "__|_  "<<Logger::GREEN<<" GGGG   "<<Logger::RED<<" R   R  "<<Logger::BLUE  <<" III    "<<Logger::PURPLE<<"DDDD  "<<Logger::GREEN <<"    _|__"<<std::endl; | ||||
|   std::cout <<Logger::BLUE << "__|__         "<<             "        "<<Logger::GREEN <<"        "<<                "          _|__"<<std::endl;  | ||||
|   std::cout <<Logger::BLUE << "__|__|__|__|__"<<             "|__|__|_"<<Logger::GREEN <<"_|__|__|"<<                "__|__|__|__|__"<<std::endl;  | ||||
|   std::cout <<Logger::BLUE << "__|__|__|__|__"<<             "|__|__|_"<<Logger::GREEN <<"_|__|__|"<<                "__|__|__|__|__"<<std::endl;  | ||||
|   std::cout <<Logger::BLUE << "  |  |  |  |  "<<             "|  |  | "<<Logger::GREEN <<" |  |  |"<<                "  |  |  |  |  "<<std::endl;  | ||||
|   std::cout << std::endl; | ||||
|   std::cout << std::endl; | ||||
|   std::cout <<Logger::YELLOW<< std::endl; | ||||
|   std::cout << "Copyright (C) 2015 Peter Boyle, Azusa Yamaguchi, Guido Cossu, Antonin Portelli and other authors"<<std::endl; | ||||
|   std::cout << "Colours by Tadahito Boyle "<<std::endl; | ||||
|   std::cout << std::endl; | ||||
|   std::cout << "This program is free software; you can redistribute it and/or modify"<<std::endl; | ||||
|   std::cout << "it under the terms of the GNU General Public License as published by"<<std::endl; | ||||
|   std::cout << "the Free Software Foundation; either version 2 of the License, or"<<std::endl; | ||||
|   std::cout << "(at your option) any later version."<<std::endl; | ||||
|   std::cout << std::endl; | ||||
|   std::cout << "This program is distributed in the hope that it will be useful,"<<std::endl; | ||||
|   std::cout << "but WITHOUT ANY WARRANTY; without even the implied warranty of"<<std::endl; | ||||
|   std::cout << "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the"<<std::endl; | ||||
|   std::cout << "GNU General Public License for more details."<<std::endl; | ||||
|   std::cout << Logger::BLACK <<std::endl; | ||||
| } | ||||
|  | ||||
|    | ||||
| void Grid_finalize(void) | ||||
| { | ||||
| #ifdef GRID_COMMS_MPI | ||||
|   MPI_Finalize(); | ||||
|   Grid_unquiesce_nodes(); | ||||
| #endif | ||||
| } | ||||
| double usecond(void) { | ||||
|   struct timeval tv; | ||||
|   gettimeofday(&tv,NULL); | ||||
|   return 1.0*tv.tv_usec + 1.0e6*tv.tv_sec; | ||||
| } | ||||
|  | ||||
| void * Grid_backtrace_buffer[_NBACKTRACE]; | ||||
|  | ||||
| void Grid_sa_signal_handler(int sig,siginfo_t *si,void * ptr) | ||||
| { | ||||
|   printf("Caught signal %d\n",si->si_signo); | ||||
|   printf("  mem address %llx\n",(unsigned long long)si->si_addr); | ||||
|   printf("         code %d\n",si->si_code); | ||||
|  | ||||
|   // Linux/Posix | ||||
| #ifdef __linux__ | ||||
|   // And x86 64bit | ||||
| #ifdef __x86_64__ | ||||
|   ucontext_t * uc= (ucontext_t *)ptr; | ||||
|   struct sigcontext *sc = (struct sigcontext *)&uc->uc_mcontext; | ||||
|   printf("  instruction %llx\n",(unsigned long long)sc->rip); | ||||
| #define REG(A)  printf("  %s %lx\n",#A,sc-> A); | ||||
|   REG(rdi); | ||||
|   REG(rsi); | ||||
|   REG(rbp); | ||||
|   REG(rbx); | ||||
|   REG(rdx); | ||||
|   REG(rax); | ||||
|   REG(rcx); | ||||
|   REG(rsp); | ||||
|   REG(rip); | ||||
|  | ||||
|  | ||||
|   REG(r8); | ||||
|   REG(r9); | ||||
|   REG(r10); | ||||
|   REG(r11); | ||||
|   REG(r12); | ||||
|   REG(r13); | ||||
|   REG(r14); | ||||
|   REG(r15); | ||||
| #endif | ||||
| #endif | ||||
|   BACKTRACE(); | ||||
|   exit(0); | ||||
|   return; | ||||
| }; | ||||
| #ifdef GRID_FPE | ||||
| #define _GNU_SOURCE | ||||
| #include <fenv.h> | ||||
| #endif | ||||
| void Grid_debug_handler_init(void) | ||||
| { | ||||
|   struct sigaction sa,osa; | ||||
|   sigemptyset (&sa.sa_mask); | ||||
|   sa.sa_sigaction= Grid_sa_signal_handler; | ||||
|   sa.sa_flags    = SA_SIGINFO; | ||||
|   sigaction(SIGSEGV,&sa,NULL); | ||||
|   sigaction(SIGTRAP,&sa,NULL); | ||||
| #ifdef GRID_FPE | ||||
|   feenableexcept( FE_INVALID|FE_OVERFLOW|FE_DIVBYZERO); | ||||
|   sigaction(SIGFPE,&sa,NULL); | ||||
| #endif | ||||
| } | ||||
| } | ||||
							
								
								
									
										126
									
								
								lib/Log.cc
									
									
									
									
									
								
							
							
						
						
									
										126
									
								
								lib/Log.cc
									
									
									
									
									
								
							| @@ -1,126 +0,0 @@ | ||||
|     /************************************************************************************* | ||||
|  | ||||
|     Grid physics library, www.github.com/paboyle/Grid  | ||||
|  | ||||
|     Source file: ./lib/Log.cc | ||||
|  | ||||
|     Copyright (C) 2015 | ||||
|  | ||||
| Author: Antonin Portelli <antonin.portelli@me.com> | ||||
| Author: Azusa Yamaguchi <ayamaguc@staffmail.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 */ | ||||
| #include <Grid.h> | ||||
|  | ||||
| namespace Grid { | ||||
|  | ||||
| GridStopWatch Logger::StopWatch; | ||||
| std::ostream  Logger::devnull(0); | ||||
| std::string Logger::BLACK("\033[30m"); | ||||
| std::string Logger::RED("\033[31m"); | ||||
| std::string Logger::GREEN("\033[32m"); | ||||
| std::string Logger::YELLOW("\033[33m"); | ||||
| std::string Logger::BLUE("\033[34m"); | ||||
| std::string Logger::PURPLE("\033[35m"); | ||||
| std::string Logger::CYAN("\033[36m"); | ||||
| std::string Logger::WHITE("\033[37m"); | ||||
| std::string Logger::NORMAL("\033[0;39m"); | ||||
| std::string EMPTY(""); | ||||
|  | ||||
| #if 0   | ||||
|   GridLogger GridLogError      (1,"Error",Logger::RED); | ||||
|   GridLogger GridLogWarning    (1,"Warning",Logger::YELLOW); | ||||
|   GridLogger GridLogMessage    (1,"Message",Logger::BLACK); | ||||
|   GridLogger GridLogDebug      (1,"Debug",Logger::PURPLE); | ||||
|   GridLogger GridLogPerformance(1,"Performance",Logger::GREEN); | ||||
|   GridLogger GridLogIterative  (1,"Iterative",Logger::BLUE); | ||||
|   GridLogger GridLogIntegrator (1,"Integrator",Logger::BLUE); | ||||
| #else | ||||
|   GridLogger GridLogError      (1,"Error",EMPTY); | ||||
|   GridLogger GridLogWarning    (1,"Warning",EMPTY); | ||||
|   GridLogger GridLogMessage    (1,"Message",EMPTY); | ||||
|   GridLogger GridLogDebug      (1,"Debug",EMPTY); | ||||
|   GridLogger GridLogPerformance(1,"Performance",EMPTY); | ||||
|   GridLogger GridLogIterative  (1,"Iterative",EMPTY); | ||||
|   GridLogger GridLogIntegrator (1,"Integrator",EMPTY); | ||||
| #endif | ||||
|  | ||||
| void GridLogConfigure(std::vector<std::string> &logstreams) | ||||
| { | ||||
|   GridLogError.Active(0); | ||||
|   GridLogWarning.Active(0); | ||||
|   GridLogMessage.Active(0); | ||||
|   GridLogIterative.Active(0); | ||||
|   GridLogDebug.Active(0); | ||||
|   GridLogPerformance.Active(0); | ||||
|   GridLogIntegrator.Active(0); | ||||
|  | ||||
|   int blackAndWhite = 1; | ||||
|   if(blackAndWhite){ | ||||
|     Logger::BLACK = std::string(""); | ||||
|     Logger::RED    =Logger::BLACK; | ||||
|     Logger::GREEN  =Logger::BLACK; | ||||
|     Logger::YELLOW =Logger::BLACK; | ||||
|     Logger::BLUE   =Logger::BLACK; | ||||
|     Logger::PURPLE =Logger::BLACK; | ||||
|     Logger::CYAN   =Logger::BLACK; | ||||
|     Logger::WHITE  =Logger::BLACK; | ||||
|     Logger::NORMAL =Logger::BLACK; | ||||
|   } | ||||
|  | ||||
|   for(int i=0;i<logstreams.size();i++){ | ||||
|     if ( logstreams[i]== std::string("Error")       ) GridLogError.Active(1); | ||||
|     if ( logstreams[i]== std::string("Warning")     ) GridLogWarning.Active(1); | ||||
|     if ( logstreams[i]== std::string("Message")     ) GridLogMessage.Active(1); | ||||
|     if ( logstreams[i]== std::string("Iterative")   ) GridLogIterative.Active(1); | ||||
|     if ( logstreams[i]== std::string("Debug")       ) GridLogDebug.Active(1); | ||||
|     if ( logstreams[i]== std::string("Performance") ) GridLogPerformance.Active(1); | ||||
|     if ( logstreams[i]== std::string("Integrator" ) ) GridLogIntegrator.Active(1); | ||||
|   } | ||||
| } | ||||
|  | ||||
| //////////////////////////////////////////////////////////// | ||||
| // Verbose limiter on MPI tasks | ||||
| //////////////////////////////////////////////////////////// | ||||
| void Grid_quiesce_nodes(void) | ||||
| { | ||||
|   int me=0; | ||||
| #ifdef GRID_COMMS_MPI | ||||
|   MPI_Comm_rank(MPI_COMM_WORLD,&me); | ||||
| #endif | ||||
| #ifdef GRID_COMMS_SHMEM | ||||
|   me = shmem_my_pe(); | ||||
| #endif | ||||
|   if ( me ) {  | ||||
|     std::cout.setstate(std::ios::badbit); | ||||
|   } | ||||
| } | ||||
|  | ||||
| void Grid_unquiesce_nodes(void) | ||||
| { | ||||
| #ifdef GRID_COMMS_MPI | ||||
|     std::cout.clear(); | ||||
| #endif | ||||
| } | ||||
|  | ||||
|  | ||||
| } | ||||
|  | ||||
							
								
								
									
										132
									
								
								lib/Log.h
									
									
									
									
									
								
							
							
						
						
									
										132
									
								
								lib/Log.h
									
									
									
									
									
								
							| @@ -1,132 +0,0 @@ | ||||
|     /************************************************************************************* | ||||
|  | ||||
|     Grid physics library, www.github.com/paboyle/Grid  | ||||
|  | ||||
|     Source file: ./lib/Log.h | ||||
|  | ||||
|     Copyright (C) 2015 | ||||
|  | ||||
| Author: Antonin Portelli <antonin.portelli@me.com> | ||||
| 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_LOG_H | ||||
| #define GRID_LOG_H | ||||
|  | ||||
| #ifdef HAVE_EXECINFO_H | ||||
| #include <execinfo.h> | ||||
| #endif | ||||
|  | ||||
| namespace Grid { | ||||
|  | ||||
| // Dress the output; use std::chrono for time stamping via the StopWatch class | ||||
| int Rank(void); // used for early stage debug before library init | ||||
|  | ||||
|  | ||||
| class Logger { | ||||
| protected: | ||||
|     int active; | ||||
|     std::string name, topName, COLOUR; | ||||
| public: | ||||
|     static GridStopWatch StopWatch; | ||||
|     static std::ostream devnull; | ||||
|  | ||||
|     static std::string BLACK; | ||||
|     static std::string RED  ; | ||||
|     static std::string GREEN; | ||||
|     static std::string YELLOW; | ||||
|     static std::string BLUE  ; | ||||
|     static std::string PURPLE; | ||||
|     static std::string CYAN  ; | ||||
|     static std::string WHITE ; | ||||
|     static std::string NORMAL; | ||||
|      | ||||
|  Logger(std::string topNm, int on, std::string nm,std::string col) | ||||
|    : active(on), name(nm), topName(topNm), COLOUR(col) {}; | ||||
|      | ||||
|     void Active(int on) {active = on;}; | ||||
|     int  isActive(void) {return active;}; | ||||
|      | ||||
|     friend std::ostream& operator<< (std::ostream& stream, const Logger& log){ | ||||
|         if ( log.active ) { | ||||
|             StopWatch.Stop(); | ||||
|             GridTime now = StopWatch.Elapsed(); | ||||
|             StopWatch.Start(); | ||||
|             stream << BLACK <<std::setw(8) << std::left << log.topName << BLACK<< " : "; | ||||
|             stream << log.COLOUR <<std::setw(11)  << log.name << BLACK << " : "; | ||||
|             stream << YELLOW <<std::setw(6) << now <<BLACK << " : " ; | ||||
|             stream << log.COLOUR; | ||||
|             return stream; | ||||
|         } else {  | ||||
|             return devnull; | ||||
|         } | ||||
|     } | ||||
|      | ||||
| }; | ||||
|      | ||||
| class GridLogger: public Logger { | ||||
| public: | ||||
|  GridLogger(int on, std::string nm, std::string col = Logger::BLACK): Logger("Grid", on, nm, col){}; | ||||
| }; | ||||
|  | ||||
| void GridLogConfigure(std::vector<std::string> &logstreams); | ||||
|  | ||||
| extern GridLogger GridLogError; | ||||
| extern GridLogger GridLogWarning; | ||||
| extern GridLogger GridLogMessage; | ||||
| extern GridLogger GridLogDebug  ; | ||||
| extern GridLogger GridLogPerformance; | ||||
| extern GridLogger GridLogIterative  ; | ||||
| extern GridLogger GridLogIntegrator  ; | ||||
|  | ||||
|  | ||||
| #define _NBACKTRACE (256) | ||||
| extern void * Grid_backtrace_buffer[_NBACKTRACE]; | ||||
|  | ||||
| #define BACKTRACEFILE() {\ | ||||
|     char string[20];					\ | ||||
|     std::sprintf(string,"backtrace.%d",Rank());				\ | ||||
|     std::FILE * fp = std::fopen(string,"w");				\ | ||||
|     BACKTRACEFP(fp)\ | ||||
|     std::fclose(fp);	    \ | ||||
| } | ||||
|  | ||||
|  | ||||
| #ifdef HAVE_EXECINFO_H | ||||
| #define BACKTRACEFP(fp) { \ | ||||
|   int symbols    = backtrace        (Grid_backtrace_buffer,_NBACKTRACE);\ | ||||
|   char **strings = backtrace_symbols(Grid_backtrace_buffer,symbols);\ | ||||
|   for (int i = 0; i < symbols; i++){\ | ||||
|     std::fprintf (fp,"BackTrace Strings: %d %s\n",i, strings[i]); std::fflush(fp); \ | ||||
|   }\ | ||||
| } | ||||
| #else  | ||||
| #define BACKTRACEFP(fp) { \ | ||||
|     std::fprintf (fp,"BT %d %lx\n",0, __builtin_return_address(0)); std::fflush(fp); \ | ||||
|     std::fprintf (fp,"BT %d %lx\n",1, __builtin_return_address(1)); std::fflush(fp); \ | ||||
|     std::fprintf (fp,"BT %d %lx\n",2, __builtin_return_address(2)); std::fflush(fp); \ | ||||
|     std::fprintf (fp,"BT %d %lx\n",3, __builtin_return_address(3)); std::fflush(fp); \ | ||||
| } | ||||
| #endif | ||||
|  | ||||
| #define BACKTRACE() BACKTRACEFP(stdout)  | ||||
|  | ||||
| } | ||||
| #endif | ||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @@ -1,32 +1,47 @@ | ||||
| # additional include paths necessary to compile the C++ library | ||||
| AM_CXXFLAGS = -I$(top_srcdir)/ | ||||
|  | ||||
| extra_sources= | ||||
| extra_headers= | ||||
| if BUILD_COMMS_MPI | ||||
|   extra_sources+=communicator/Communicator_mpi.cc | ||||
|   extra_sources+=communicator/Communicator_base.cc | ||||
| endif | ||||
|  | ||||
| if BUILD_COMMS_MPI3 | ||||
|   extra_sources+=communicator/Communicator_mpi3.cc | ||||
|   extra_sources+=communicator/Communicator_base.cc | ||||
| endif | ||||
|  | ||||
| if BUILD_COMMS_MPI3L | ||||
|   extra_sources+=communicator/Communicator_mpi3_leader.cc | ||||
|   extra_sources+=communicator/Communicator_base.cc | ||||
| endif | ||||
|  | ||||
| if BUILD_COMMS_SHMEM | ||||
|   extra_sources+=communicator/Communicator_shmem.cc | ||||
|   extra_sources+=communicator/Communicator_base.cc | ||||
| endif | ||||
|  | ||||
| if BUILD_COMMS_NONE | ||||
|   extra_sources+=communicator/Communicator_none.cc | ||||
|   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 | ||||
| # | ||||
|  | ||||
| include Make.inc | ||||
| include Eigen.inc | ||||
|  | ||||
| lib_LIBRARIES = libGrid.a | ||||
| libGrid_a_SOURCES = $(CCFILES) $(extra_sources) | ||||
|  | ||||
| CCFILES += $(extra_sources) | ||||
| HFILES  += $(extra_headers) | ||||
|  | ||||
| #	qcd/action/fermion/PartialFractionFermion5D.cc\	\ | ||||
| # | ||||
| # Include files | ||||
| # | ||||
| nobase_include_HEADERS=$(HFILES) | ||||
|  | ||||
| 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 | ||||
							
								
								
									
										856
									
								
								lib/Stencil.h
									
									
									
									
									
								
							
							
						
						
									
										856
									
								
								lib/Stencil.h
									
									
									
									
									
								
							| @@ -1,856 +0,0 @@ | ||||
|     /************************************************************************************* | ||||
|  | ||||
|     Grid physics library, www.github.com/paboyle/Grid  | ||||
|  | ||||
|     Source file: ./lib/Stencil.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_STENCIL_H | ||||
| #define GRID_STENCIL_H | ||||
|  | ||||
| #include <thread> | ||||
|  | ||||
| #include <stencil/Lebesgue.h>   // subdir aggregate | ||||
|  | ||||
| ////////////////////////////////////////////////////////////////////////////////////////// | ||||
| // Must not lose sight that goal is to be able to construct really efficient | ||||
| // gather to a point stencil code. CSHIFT is not the best way, so need | ||||
| // additional stencil support. | ||||
| // | ||||
| // Stencil based code will pre-exchange haloes and use a table lookup for neighbours. | ||||
| // This will be done with generality to allow easier efficient implementations. | ||||
| // Overlap of comms and compute could be semi-automated by tabulating off-node connected, | ||||
| // and  | ||||
| // | ||||
| // Lattice <foo> could also allocate haloes which get used for stencil code. | ||||
| // | ||||
| // Grid could create a neighbour index table for a given stencil. | ||||
| // | ||||
| // Could also implement CovariantCshift, to fuse the loops and enhance performance. | ||||
| // | ||||
| // | ||||
| // General stencil computation: | ||||
| // | ||||
| // Generic services | ||||
| // 0) Prebuild neighbour tables | ||||
| // 1) Compute sizes of all haloes/comms buffers; allocate them. | ||||
| // | ||||
| // 2) Gather all faces, and communicate. | ||||
| // 3) Loop over result sites, giving nbr index/offnode info for each | ||||
| //  | ||||
| // Could take a  | ||||
| // SpinProjectFaces  | ||||
| // start comms | ||||
| // complete comms  | ||||
| // Reconstruct Umu | ||||
| // | ||||
| // Approach. | ||||
| // | ||||
| ////////////////////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| namespace Grid { | ||||
|    | ||||
|   struct StencilEntry {  | ||||
|     int _offset; | ||||
|     int _is_local; | ||||
|     int _permute; | ||||
|     int _around_the_world; | ||||
|   }; | ||||
|  | ||||
|   template<class vobj,class cobj> | ||||
|   class CartesianStencil { // Stencil runs along coordinate axes only; NO diagonal fill in. | ||||
|   public: | ||||
|  | ||||
|       typedef uint32_t StencilInteger; | ||||
|       typedef typename cobj::vector_type vector_type; | ||||
|       typedef typename cobj::scalar_type scalar_type; | ||||
|       typedef typename cobj::scalar_object scalar_object; | ||||
|  | ||||
|       ////////////////////////////////////////// | ||||
|       // Comms packet queue for asynch thread | ||||
|       ////////////////////////////////////////// | ||||
|  | ||||
|       struct Packet { | ||||
| 	void * send_buf; | ||||
| 	void * recv_buf; | ||||
| 	Integer to_rank; | ||||
| 	Integer from_rank; | ||||
| 	Integer bytes; | ||||
| 	volatile Integer done; | ||||
|       }; | ||||
|  | ||||
|       std::vector<Packet> Packets; | ||||
|  | ||||
| #define SEND_IMMEDIATE | ||||
| #define SERIAL_SENDS | ||||
|  | ||||
|       void AddPacket(void *xmit,void * rcv, Integer to,Integer from,Integer bytes){ | ||||
| 	comms_bytes+=2.0*bytes; | ||||
| #ifdef SEND_IMMEDIATE | ||||
| 	commtime-=usecond(); | ||||
| 	_grid->SendToRecvFrom(xmit,to,rcv,from,bytes); | ||||
| 	commtime+=usecond(); | ||||
| #endif | ||||
| 	Packet p; | ||||
| 	p.send_buf = xmit; | ||||
| 	p.recv_buf = rcv; | ||||
| 	p.to_rank  = to; | ||||
| 	p.from_rank= from; | ||||
| 	p.bytes    = bytes; | ||||
| 	p.done     = 0; | ||||
| 	comms_bytes+=2.0*bytes; | ||||
| 	Packets.push_back(p); | ||||
|  | ||||
|       } | ||||
|  | ||||
| #ifdef SERIAL_SENDS | ||||
|       void Communicate(void ) {  | ||||
| 	commtime-=usecond(); | ||||
| 	for(int i=0;i<Packets.size();i++){ | ||||
| #ifndef SEND_IMMEDIATE | ||||
| 	  _grid->SendToRecvFrom( | ||||
| 				Packets[i].send_buf, | ||||
| 				Packets[i].to_rank, | ||||
| 				Packets[i].recv_buf, | ||||
| 				Packets[i].from_rank, | ||||
| 				Packets[i].bytes); | ||||
| #endif | ||||
| 	  Packets[i].done = 1; | ||||
| 	} | ||||
| 	commtime+=usecond(); | ||||
|       } | ||||
| #else | ||||
|       void Communicate(void ) {  | ||||
| 	typedef CartesianCommunicator::CommsRequest_t CommsRequest_t; | ||||
| 	std::vector<std::vector<CommsRequest_t> > reqs(Packets.size()); | ||||
| 	commtime-=usecond(); | ||||
| 	const int concurrency=2; | ||||
| 	for(int i=0;i<Packets.size();i+=concurrency){ | ||||
| 	  for(int ii=0;ii<concurrency;ii++){ | ||||
| 	    int j = i+ii; | ||||
| 	    if ( j<Packets.size() ) { | ||||
| #ifndef SEND_IMMEDIATE | ||||
| 	      _grid->SendToRecvFromBegin(reqs[j], | ||||
| 					 Packets[j].send_buf, | ||||
| 					 Packets[j].to_rank, | ||||
| 					 Packets[j].recv_buf, | ||||
| 					 Packets[j].from_rank, | ||||
| 					 Packets[j].bytes); | ||||
| #endif | ||||
| 	    } | ||||
| 	  } | ||||
| 	  for(int ii=0;ii<concurrency;ii++){ | ||||
| 	    int j = i+ii; | ||||
| 	    if ( j<Packets.size() ) { | ||||
| #ifndef SEND_IMMEDIATE | ||||
| 	      _grid->SendToRecvFromComplete(reqs[i]); | ||||
| #endif | ||||
| 	    } | ||||
| 	  } | ||||
| 	  for(int ii=0;ii<concurrency;ii++){ | ||||
| 	    int j = i+ii; | ||||
| 	    if ( j<Packets.size() ) { | ||||
| 	      Packets[j].done = 1; | ||||
| 	    } | ||||
| 	  } | ||||
| 	} | ||||
| 	commtime+=usecond(); | ||||
|       } | ||||
| #endif | ||||
|  | ||||
|       /////////////////////////////////////////// | ||||
|       // Simd merge queue for asynch comms | ||||
|       /////////////////////////////////////////// | ||||
|       struct Merge { | ||||
|         cobj * mpointer; | ||||
| 	std::vector<scalar_object *> rpointers; | ||||
| 	Integer buffer_size; | ||||
| 	Integer packet_id; | ||||
|       }; | ||||
|  | ||||
|       std::vector<Merge> Mergers; | ||||
|  | ||||
|       void AddMerge(cobj *merge_p,std::vector<scalar_object *> &rpointers,Integer buffer_size,Integer packet_id) { | ||||
| 	Merge m; | ||||
| 	m.mpointer = merge_p; | ||||
| 	m.rpointers= rpointers; | ||||
| 	m.buffer_size = buffer_size; | ||||
| 	m.packet_id   = packet_id; | ||||
| #ifdef SEND_IMMEDIATE | ||||
| 	mergetime-=usecond(); | ||||
| PARALLEL_FOR_LOOP | ||||
|         for(int o=0;o<m.buffer_size;o++){ | ||||
| 	  merge1(m.mpointer[o],m.rpointers,o); | ||||
| 	} | ||||
| 	mergetime+=usecond(); | ||||
| #else | ||||
| 	Mergers.push_back(m); | ||||
| #endif | ||||
|  | ||||
|       } | ||||
|  | ||||
|       void CommsMerge(void ) {  | ||||
| 	//PARALLEL_NESTED_LOOP2  | ||||
| 	for(int i=0;i<Mergers.size();i++){	 | ||||
| 	   | ||||
| 	spintime-=usecond(); | ||||
| 	int packet_id = Mergers[i].packet_id; | ||||
| 	while(! Packets[packet_id].done ); // spin for completion | ||||
| 	spintime+=usecond(); | ||||
|  | ||||
| #ifndef SEND_IMMEDIATE | ||||
| 	mergetime-=usecond(); | ||||
| PARALLEL_FOR_LOOP | ||||
| 	  for(int o=0;o<Mergers[i].buffer_size;o++){ | ||||
| 	    merge1(Mergers[i].mpointer[o],Mergers[i].rpointers,o); | ||||
| 	  } | ||||
| 	mergetime+=usecond(); | ||||
| #endif | ||||
|  | ||||
| 	} | ||||
|       } | ||||
|  | ||||
|       //////////////////////////////////////// | ||||
|       // Basic Grid and stencil info | ||||
|       //////////////////////////////////////// | ||||
|  | ||||
|       int                               _checkerboard; | ||||
|       int                               _npoints; // Move to template param? | ||||
|       GridBase *                        _grid; | ||||
|  | ||||
|       // npoints of these | ||||
|       std::vector<int>                  _directions; | ||||
|       std::vector<int>                  _distances; | ||||
|       std::vector<int>                  _comm_buf_size; | ||||
|       std::vector<int>                  _permute_type; | ||||
|  | ||||
|       // npoints x Osites() of these | ||||
|       std::vector<std::vector<StencilEntry> > _entries; | ||||
|       inline StencilEntry * GetEntry(int &ptype,int point,int osite) { ptype = _permute_type[point]; return & _entries[point][osite]; } | ||||
|  | ||||
|       // Comms buffers | ||||
|       std::vector<Vector<scalar_object> > u_simd_send_buf; | ||||
|       std::vector<Vector<scalar_object> > u_simd_recv_buf; | ||||
|       Vector<cobj>          u_send_buf; | ||||
|       Vector<cobj>          comm_buf; | ||||
|       int u_comm_offset; | ||||
|       int _unified_buffer_size; | ||||
|  | ||||
|       ///////////////////////////////////////// | ||||
|       // Timing info; ugly; possibly temporary | ||||
|       ///////////////////////////////////////// | ||||
| #define TIMING_HACK | ||||
| #ifdef TIMING_HACK | ||||
|       double jointime; | ||||
|       double gathertime; | ||||
|       double commtime; | ||||
|       double halogtime; | ||||
|       double mergetime; | ||||
|       double spintime; | ||||
|       double comms_bytes; | ||||
|       double gathermtime; | ||||
|       double splicetime; | ||||
|       double nosplicetime; | ||||
| #endif | ||||
|  | ||||
|   CartesianStencil(GridBase *grid, | ||||
| 				     int npoints, | ||||
| 				     int checkerboard, | ||||
| 				     const std::vector<int> &directions, | ||||
| 				     const std::vector<int> &distances)  | ||||
|     :   _entries(npoints), _permute_type(npoints), _comm_buf_size(npoints) | ||||
|     { | ||||
| #ifdef TIMING_HACK | ||||
|       gathertime=0; | ||||
|       jointime=0; | ||||
|       commtime=0; | ||||
|       halogtime=0; | ||||
|       mergetime=0; | ||||
|       spintime=0; | ||||
|       gathermtime=0; | ||||
|       splicetime=0; | ||||
|       nosplicetime=0; | ||||
|       comms_bytes=0; | ||||
| #endif | ||||
|       _npoints = npoints; | ||||
|       _grid    = grid; | ||||
|       _directions = directions; | ||||
|       _distances  = distances; | ||||
|       _unified_buffer_size=0; | ||||
|  | ||||
|       int osites  = _grid->oSites(); | ||||
|  | ||||
|       for(int ii=0;ii<npoints;ii++){ | ||||
|  | ||||
| 	int i = ii; // reverse direction to get SIMD comms done first | ||||
| 	int point = i; | ||||
|  | ||||
| 	_entries[i].resize( osites); | ||||
|  | ||||
| 	int dimension    = directions[i]; | ||||
| 	int displacement = distances[i]; | ||||
| 	int shift = displacement; | ||||
| 	 | ||||
| 	int fd = _grid->_fdimensions[dimension]; | ||||
| 	int rd = _grid->_rdimensions[dimension]; | ||||
| 	_permute_type[point]=_grid->PermuteType(dimension); | ||||
|  | ||||
| 	_checkerboard = checkerboard; | ||||
|  | ||||
| 	// the permute type | ||||
| 	int simd_layout     = _grid->_simd_layout[dimension]; | ||||
| 	int comm_dim        = _grid->_processors[dimension] >1 ; | ||||
| 	int splice_dim      = _grid->_simd_layout[dimension]>1 && (comm_dim); | ||||
| 	int rotate_dim      = _grid->_simd_layout[dimension]>2; | ||||
|  | ||||
| 	assert ( (rotate_dim && comm_dim) == false) ; // Do not think spread out is supported | ||||
|  | ||||
| 	int sshift[2]; | ||||
| 	 | ||||
| 	// Underlying approach. For each local site build | ||||
| 	// up a table containing the npoint "neighbours" and whether they  | ||||
| 	// live in lattice or a comms buffer. | ||||
| 	if ( !comm_dim ) { | ||||
| 	  sshift[0] = _grid->CheckerBoardShiftForCB(_checkerboard,dimension,shift,Even); | ||||
| 	  sshift[1] = _grid->CheckerBoardShiftForCB(_checkerboard,dimension,shift,Odd); | ||||
|  | ||||
| 	  if ( sshift[0] == sshift[1] ) { | ||||
| 	    Local(point,dimension,shift,0x3); | ||||
| 	  } else { | ||||
| 	    Local(point,dimension,shift,0x1);// if checkerboard is unfavourable take two passes | ||||
| 	    Local(point,dimension,shift,0x2);// both with block stride loop iteration | ||||
| 	  } | ||||
| 	} else { // All permute extract done in comms phase prior to Stencil application | ||||
| 	  //        So tables are the same whether comm_dim or splice_dim | ||||
| 	  sshift[0] = _grid->CheckerBoardShiftForCB(_checkerboard,dimension,shift,Even); | ||||
| 	  sshift[1] = _grid->CheckerBoardShiftForCB(_checkerboard,dimension,shift,Odd); | ||||
|  | ||||
| 	  if ( sshift[0] == sshift[1] ) { | ||||
| 	    Comms(point,dimension,shift,0x3); | ||||
| 	  } else { | ||||
| 	    Comms(point,dimension,shift,0x1);// if checkerboard is unfavourable take two passes | ||||
| 	    Comms(point,dimension,shift,0x2);// both with block stride loop iteration | ||||
| 	  } | ||||
| 	} | ||||
|       } | ||||
|       u_send_buf.resize(_unified_buffer_size); | ||||
|       comm_buf.resize(_unified_buffer_size); | ||||
|        | ||||
|       const int Nsimd = grid->Nsimd(); | ||||
|       u_simd_send_buf.resize(Nsimd); | ||||
|       u_simd_recv_buf.resize(Nsimd); | ||||
|       for(int l=0;l<Nsimd;l++){ | ||||
| 	u_simd_send_buf[l].resize(_unified_buffer_size); | ||||
| 	u_simd_recv_buf[l].resize(_unified_buffer_size); | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     void Local     (int point, int dimension,int shiftpm,int cbmask) | ||||
|     { | ||||
|       int fd = _grid->_fdimensions[dimension]; | ||||
|       int rd = _grid->_rdimensions[dimension]; | ||||
|       int ld = _grid->_ldimensions[dimension]; | ||||
|       int gd = _grid->_gdimensions[dimension]; | ||||
|       int ly = _grid->_simd_layout[dimension]; | ||||
|  | ||||
|       // Map to always positive shift modulo global full dimension. | ||||
|       int shift = (shiftpm+fd)%fd; | ||||
|        | ||||
|       // the permute type | ||||
|       int permute_dim =_grid->PermuteDim(dimension); | ||||
|        | ||||
|       for(int x=0;x<rd;x++){        | ||||
| 	 | ||||
| 	int o   = 0; | ||||
| 	int bo  = x * _grid->_ostride[dimension]; | ||||
| 	 | ||||
| 	int cb= (cbmask==0x2)? Odd : Even; | ||||
| 	   | ||||
| 	int sshift = _grid->CheckerBoardShiftForCB(_checkerboard,dimension,shift,cb); | ||||
| 	int sx     = (x+sshift)%rd; | ||||
|  | ||||
| 	int wraparound=0; | ||||
| 	if ( (shiftpm==-1) && (sx>x)  ) { | ||||
| 	  wraparound = 1; | ||||
| 	} | ||||
| 	if ( (shiftpm== 1) && (sx<x)  ) { | ||||
| 	  wraparound = 1; | ||||
| 	} | ||||
| 	   | ||||
| 	int permute_slice=0; | ||||
| 	if(permute_dim){ | ||||
| 	  int wrap = sshift/rd; | ||||
| 	  int  num = sshift%rd; | ||||
| 	  if ( x< rd-num ) permute_slice=wrap; | ||||
| 	  else permute_slice = (wrap+1)%ly; | ||||
| 	} | ||||
|  | ||||
|   	CopyPlane(point,dimension,x,sx,cbmask,permute_slice,wraparound); | ||||
|    | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     void Comms     (int point,int dimension,int shiftpm,int cbmask) | ||||
|     { | ||||
|       GridBase *grid=_grid; | ||||
|       const int Nsimd = grid->Nsimd(); | ||||
|        | ||||
|       int fd              = _grid->_fdimensions[dimension]; | ||||
|       int ld              = _grid->_ldimensions[dimension]; | ||||
|       int rd              = _grid->_rdimensions[dimension]; | ||||
|       int pd              = _grid->_processors[dimension]; | ||||
|       int simd_layout     = _grid->_simd_layout[dimension]; | ||||
|       int comm_dim        = _grid->_processors[dimension] >1 ; | ||||
|        | ||||
|       assert(comm_dim==1); | ||||
|       int shift = (shiftpm + fd) %fd; | ||||
|       assert(shift>=0); | ||||
|       assert(shift<fd); | ||||
|  | ||||
|       int buffer_size = _grid->_slice_nblock[dimension]*_grid->_slice_block[dimension]; // done in reduced dims, so SIMD factored | ||||
|  | ||||
|       _comm_buf_size[point] = buffer_size; // Size of _one_ plane. Multiple planes may be gathered and | ||||
|                                            // send to one or more remote nodes. | ||||
|  | ||||
|       int cb= (cbmask==0x2)? Odd : Even; | ||||
|       int sshift= _grid->CheckerBoardShiftForCB(_checkerboard,dimension,shift,cb); | ||||
|  | ||||
|       for(int x=0;x<rd;x++){        | ||||
|  | ||||
| 	int permute_type=grid->PermuteType(dimension); | ||||
|  | ||||
| 	int sx        =  (x+sshift)%rd; | ||||
| 	 | ||||
|     	int offnode = 0; | ||||
| 	if ( simd_layout > 1 ) { | ||||
|  | ||||
| 	  for(int i=0;i<Nsimd;i++){ | ||||
|  | ||||
| 	    int inner_bit = (Nsimd>>(permute_type+1)); | ||||
| 	    int ic= (i&inner_bit)? 1:0; | ||||
| 	    int my_coor          = rd*ic + x; | ||||
| 	    int nbr_coor         = my_coor+sshift; | ||||
| 	    int nbr_proc = ((nbr_coor)/ld) % pd;// relative shift in processors | ||||
|  | ||||
| 	    if ( nbr_proc ) {  | ||||
| 	      offnode =1; | ||||
| 	    } | ||||
| 	  } | ||||
| 	   | ||||
| 	} else {  | ||||
| 	  int comm_proc = ((x+sshift)/rd)%pd; | ||||
| 	  offnode = (comm_proc!= 0); | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	int wraparound=0; | ||||
| 	if ( (shiftpm==-1) && (sx>x) && (grid->_processor_coor[dimension]==0) ) { | ||||
| 	  wraparound = 1; | ||||
| 	} | ||||
| 	if ( (shiftpm== 1) && (sx<x) && (grid->_processor_coor[dimension]==grid->_processors[dimension]-1) ) { | ||||
| 	  wraparound = 1; | ||||
| 	} | ||||
| 	if (!offnode) { | ||||
| 	   | ||||
| 	  int permute_slice=0; | ||||
| 	  CopyPlane(point,dimension,x,sx,cbmask,permute_slice,wraparound);  | ||||
| 	   | ||||
| 	} else { | ||||
| 	   | ||||
| 	  int words = buffer_size; | ||||
| 	  if (cbmask != 0x3) words=words>>1; | ||||
| 	   | ||||
| 	  int rank           = grid->_processor; | ||||
| 	  int recv_from_rank; | ||||
| 	  int xmit_to_rank; | ||||
|  | ||||
| 	  int unified_buffer_offset = _unified_buffer_size; | ||||
| 	  _unified_buffer_size    += words; | ||||
|  | ||||
| 	  ScatterPlane(point,dimension,x,cbmask,unified_buffer_offset,wraparound); // permute/extract/merge is done in comms phase | ||||
| 	   | ||||
| 	} | ||||
|       } | ||||
|     } | ||||
|   // Routine builds up integer table for each site in _offsets, _is_local, _permute | ||||
|   void CopyPlane(int point, int dimension,int lplane,int rplane,int cbmask,int permute,int wrap) | ||||
|     { | ||||
|       int rd = _grid->_rdimensions[dimension]; | ||||
|        | ||||
|       if ( !_grid->CheckerBoarded(dimension) ) { | ||||
| 	 | ||||
| 	int o   = 0;                                     // relative offset to base within plane | ||||
| 	int ro  = rplane*_grid->_ostride[dimension]; // base offset for start of plane  | ||||
| 	int lo  = lplane*_grid->_ostride[dimension]; // offset in buffer | ||||
| 	 | ||||
| 	// Simple block stride gather of SIMD objects | ||||
| 	for(int n=0;n<_grid->_slice_nblock[dimension];n++){ | ||||
| 	  for(int b=0;b<_grid->_slice_block[dimension];b++){ | ||||
| 	    _entries[point][lo+o+b]._offset  =ro+o+b; | ||||
| 	    _entries[point][lo+o+b]._is_local=1; | ||||
| 	    _entries[point][lo+o+b]._permute=permute; | ||||
| 	    _entries[point][lo+o+b]._around_the_world=wrap; | ||||
| 	  } | ||||
| 	  o +=_grid->_slice_stride[dimension]; | ||||
| 	} | ||||
| 	 | ||||
|       } else { | ||||
| 	 | ||||
| 	int ro  = rplane*_grid->_ostride[dimension]; // base offset for start of plane  | ||||
| 	int lo  = lplane*_grid->_ostride[dimension]; // base offset for start of plane  | ||||
| 	int o   = 0;                                     // relative offset to base within plane | ||||
| 	 | ||||
| 	for(int n=0;n<_grid->_slice_nblock[dimension];n++){ | ||||
| 	  for(int b=0;b<_grid->_slice_block[dimension];b++){ | ||||
| 	     | ||||
| 	    int ocb=1<<_grid->CheckerBoardFromOindex(o+b); | ||||
| 	     | ||||
| 	    if ( ocb&cbmask ) { | ||||
| 	      _entries[point][lo+o+b]._offset =ro+o+b; | ||||
| 	      _entries[point][lo+o+b]._is_local=1; | ||||
| 	      _entries[point][lo+o+b]._permute=permute; | ||||
| 	      _entries[point][lo+o+b]._around_the_world=wrap; | ||||
| 	    } | ||||
| 	     | ||||
| 	  } | ||||
| 	  o +=_grid->_slice_stride[dimension]; | ||||
| 	} | ||||
| 	 | ||||
|       } | ||||
|     } | ||||
|   // Routine builds up integer table for each site in _offsets, _is_local, _permute | ||||
|    void ScatterPlane (int point,int dimension,int plane,int cbmask,int offset, int wrap) | ||||
|     { | ||||
|       int rd = _grid->_rdimensions[dimension]; | ||||
|        | ||||
|       if ( !_grid->CheckerBoarded(dimension) ) { | ||||
| 	 | ||||
| 	int so  = plane*_grid->_ostride[dimension]; // base offset for start of plane  | ||||
| 	int o   = 0;                                    // relative offset to base within plane | ||||
| 	int bo  = 0;                                    // offset in buffer | ||||
|  | ||||
| 	// Simple block stride gather of SIMD objects | ||||
| 	for(int n=0;n<_grid->_slice_nblock[dimension];n++){ | ||||
| 	  for(int b=0;b<_grid->_slice_block[dimension];b++){ | ||||
| 	    _entries[point][so+o+b]._offset  =offset+(bo++); | ||||
| 	    _entries[point][so+o+b]._is_local=0; | ||||
| 	    _entries[point][so+o+b]._permute=0; | ||||
| 	    _entries[point][so+o+b]._around_the_world=wrap; | ||||
| 	  } | ||||
| 	  o +=_grid->_slice_stride[dimension]; | ||||
| 	} | ||||
|  | ||||
|       } else {  | ||||
| 	 | ||||
| 	int so  = plane*_grid->_ostride[dimension]; // base offset for start of plane  | ||||
| 	int o   = 0;                                      // relative offset to base within plane | ||||
| 	int bo  = 0;                                      // offset in buffer | ||||
|  | ||||
| 	for(int n=0;n<_grid->_slice_nblock[dimension];n++){ | ||||
| 	  for(int b=0;b<_grid->_slice_block[dimension];b++){ | ||||
|  | ||||
| 	    int ocb=1<<_grid->CheckerBoardFromOindex(o+b);// Could easily be a table lookup | ||||
| 	    if ( ocb & cbmask ) { | ||||
| 	      _entries[point][so+o+b]._offset  =offset+(bo++); | ||||
| 	      _entries[point][so+o+b]._is_local=0; | ||||
| 	      _entries[point][so+o+b]._permute =0; | ||||
| 	      _entries[point][so+o+b]._around_the_world=wrap; | ||||
| 	    } | ||||
| 	  } | ||||
| 	  o +=_grid->_slice_stride[dimension]; | ||||
| 	} | ||||
|       } | ||||
|     } | ||||
|  | ||||
|  | ||||
|       template<class compressor> | ||||
|       std::thread HaloExchangeBegin(const Lattice<vobj> &source,compressor &compress) { | ||||
| 	Mergers.resize(0);  | ||||
| 	Packets.resize(0); | ||||
| 	HaloGather(source,compress); | ||||
|         return std::thread([&] { this->Communicate(); }); | ||||
|       } | ||||
|  | ||||
|       template<class compressor> | ||||
|       void HaloExchange(const Lattice<vobj> &source,compressor &compress)  | ||||
|       { | ||||
| 	Mergers.resize(0);  | ||||
| 	Packets.resize(0); | ||||
| 	HaloGather(source,compress); | ||||
| 	Communicate(); | ||||
| 	CommsMerge(); | ||||
|       } | ||||
|  | ||||
|       void HaloExchangeComplete(std::thread &thr)  | ||||
|       { | ||||
| 	CommsMerge(); // spins | ||||
| 	jointime-=usecond(); | ||||
| 	thr.join(); | ||||
| 	jointime+=usecond(); | ||||
|       } | ||||
|  | ||||
|       template<class compressor> | ||||
|       void HaloGatherDir(const Lattice<vobj> &source,compressor &compress,int point) | ||||
|       { | ||||
| 	  int dimension    = _directions[point]; | ||||
| 	  int displacement = _distances[point]; | ||||
| 	   | ||||
| 	  int fd = _grid->_fdimensions[dimension]; | ||||
| 	  int rd = _grid->_rdimensions[dimension]; | ||||
|  | ||||
|  | ||||
| 	  // Map to always positive shift modulo global full dimension. | ||||
| 	  int shift = (displacement+fd)%fd; | ||||
| 	   | ||||
| 	  //     	  int checkerboard = _grid->CheckerBoardDestination(source.checkerboard,shift); | ||||
| 	  assert (source.checkerboard== _checkerboard); | ||||
|  | ||||
| 	  // the permute type | ||||
| 	  int simd_layout     = _grid->_simd_layout[dimension]; | ||||
| 	  int comm_dim        = _grid->_processors[dimension] >1 ; | ||||
| 	  int splice_dim      = _grid->_simd_layout[dimension]>1 && (comm_dim); | ||||
|  | ||||
| 	  // Gather phase | ||||
| 	  int sshift [2]; | ||||
| 	  if ( comm_dim ) { | ||||
| 	    sshift[0] = _grid->CheckerBoardShiftForCB(_checkerboard,dimension,shift,Even); | ||||
| 	    sshift[1] = _grid->CheckerBoardShiftForCB(_checkerboard,dimension,shift,Odd); | ||||
| 	    if ( sshift[0] == sshift[1] ) { | ||||
| 	      if (splice_dim) { | ||||
| 		splicetime-=usecond(); | ||||
| 		GatherSimd(source,dimension,shift,0x3,compress); | ||||
| 		splicetime+=usecond(); | ||||
| 	      } else {  | ||||
| 		nosplicetime-=usecond(); | ||||
| 		Gather(source,dimension,shift,0x3,compress); | ||||
| 		nosplicetime+=usecond(); | ||||
| 	      } | ||||
| 	    } else { | ||||
| 	      if(splice_dim){ | ||||
| 		splicetime-=usecond(); | ||||
| 		GatherSimd(source,dimension,shift,0x1,compress);// if checkerboard is unfavourable take two passes | ||||
| 		GatherSimd(source,dimension,shift,0x2,compress);// both with block stride loop iteration | ||||
| 		splicetime+=usecond(); | ||||
| 	      } else { | ||||
| 		nosplicetime-=usecond(); | ||||
| 		Gather(source,dimension,shift,0x1,compress); | ||||
| 		Gather(source,dimension,shift,0x2,compress); | ||||
| 		nosplicetime+=usecond(); | ||||
| 	      } | ||||
| 	    } | ||||
| 	  } | ||||
|       } | ||||
|  | ||||
|       template<class compressor> | ||||
|       void HaloGather(const Lattice<vobj> &source,compressor &compress) | ||||
|       { | ||||
| 	// conformable(source._grid,_grid); | ||||
| 	assert(source._grid==_grid); | ||||
| 	halogtime-=usecond(); | ||||
|  | ||||
| 	assert (comm_buf.size() == _unified_buffer_size ); | ||||
| 	u_comm_offset=0; | ||||
|  | ||||
| 	// Gather all comms buffers | ||||
| 	for(int point = 0 ; point < _npoints; point++) { | ||||
| 	  compress.Point(point); | ||||
| 	  HaloGatherDir(source,compress,point); | ||||
| 	} | ||||
|  | ||||
| 	assert(u_comm_offset==_unified_buffer_size); | ||||
| 	halogtime+=usecond(); | ||||
|       } | ||||
|  | ||||
|       template<class compressor> | ||||
|         void Gather(const Lattice<vobj> &rhs,int dimension,int shift,int cbmask,compressor & compress) | ||||
| 	{ | ||||
| 	  typedef typename cobj::vector_type vector_type; | ||||
| 	  typedef typename cobj::scalar_type scalar_type; | ||||
| 	   | ||||
| 	  GridBase *grid=_grid; | ||||
| 	  assert(rhs._grid==_grid); | ||||
| 	  //	  conformable(_grid,rhs._grid); | ||||
|  | ||||
| 	  int fd              = _grid->_fdimensions[dimension]; | ||||
| 	  int rd              = _grid->_rdimensions[dimension]; | ||||
| 	  int pd              = _grid->_processors[dimension]; | ||||
| 	  int simd_layout     = _grid->_simd_layout[dimension]; | ||||
| 	  int comm_dim        = _grid->_processors[dimension] >1 ; | ||||
| 	  assert(simd_layout==1); | ||||
| 	  assert(comm_dim==1); | ||||
| 	  assert(shift>=0); | ||||
| 	  assert(shift<fd); | ||||
|  | ||||
| 	  int buffer_size = _grid->_slice_nblock[dimension]*_grid->_slice_block[dimension]; | ||||
|  | ||||
| 	  int cb= (cbmask==0x2)? Odd : Even; | ||||
| 	  int sshift= _grid->CheckerBoardShiftForCB(rhs.checkerboard,dimension,shift,cb); | ||||
|  | ||||
| 	  for(int x=0;x<rd;x++){        | ||||
|  | ||||
| 	    int sx        = (x+sshift)%rd; | ||||
| 	    int comm_proc = ((x+sshift)/rd)%pd; | ||||
|  | ||||
| 	    if (comm_proc) { | ||||
| 	       | ||||
| 	      int words = buffer_size; | ||||
| 	      if (cbmask != 0x3) words=words>>1; | ||||
| 	     | ||||
| 	      int bytes = words * sizeof(cobj); | ||||
|  | ||||
| 	      gathertime-=usecond(); | ||||
| 	      Gather_plane_simple (rhs,u_send_buf,dimension,sx,cbmask,compress,u_comm_offset); | ||||
| 	      gathertime+=usecond(); | ||||
|  | ||||
| 	      int rank           = _grid->_processor; | ||||
| 	      int recv_from_rank; | ||||
| 	      int xmit_to_rank; | ||||
| 	      _grid->ShiftedRanks(dimension,comm_proc,xmit_to_rank,recv_from_rank); | ||||
| 	      assert (xmit_to_rank   != _grid->ThisRank()); | ||||
| 	      assert (recv_from_rank != _grid->ThisRank()); | ||||
|  | ||||
| 	      //      FIXME Implement asynchronous send & also avoid buffer copy | ||||
| 	      AddPacket((void *)&u_send_buf[u_comm_offset], | ||||
| 			(void *)  &comm_buf[u_comm_offset], | ||||
| 			xmit_to_rank, | ||||
| 			recv_from_rank, | ||||
| 			bytes); | ||||
| 			 | ||||
| 	      u_comm_offset+=words; | ||||
| 	    } | ||||
| 	  } | ||||
| 	} | ||||
|  | ||||
|  | ||||
|       template<class compressor> | ||||
| 	void  GatherSimd(const Lattice<vobj> &rhs,int dimension,int shift,int cbmask,compressor &compress) | ||||
| 	{ | ||||
| 	  const int Nsimd = _grid->Nsimd(); | ||||
| 	   | ||||
| 	  int fd = _grid->_fdimensions[dimension]; | ||||
| 	  int rd = _grid->_rdimensions[dimension]; | ||||
| 	  int ld = _grid->_ldimensions[dimension]; | ||||
| 	  int pd              = _grid->_processors[dimension]; | ||||
| 	  int simd_layout     = _grid->_simd_layout[dimension]; | ||||
| 	  int comm_dim        = _grid->_processors[dimension] >1 ; | ||||
|  | ||||
| 	  assert(comm_dim==1); | ||||
| 	  // This will not work with a rotate dim | ||||
| 	  assert(simd_layout==2); | ||||
| 	  assert(shift>=0); | ||||
| 	  assert(shift<fd); | ||||
|  | ||||
| 	  int permute_type=_grid->PermuteType(dimension); | ||||
|  | ||||
| 	  /////////////////////////////////////////////// | ||||
| 	  // Simd direction uses an extract/merge pair | ||||
| 	  /////////////////////////////////////////////// | ||||
| 	  int buffer_size = _grid->_slice_nblock[dimension]*_grid->_slice_block[dimension]; | ||||
| 	  int words = sizeof(cobj)/sizeof(vector_type); | ||||
|  | ||||
| 	  assert(cbmask==0x3); // Fixme think there is a latent bug if not true | ||||
|  | ||||
| 	  int bytes = buffer_size*sizeof(scalar_object); | ||||
|  | ||||
| 	  std::vector<scalar_object *> rpointers(Nsimd); | ||||
| 	  std::vector<scalar_object *> spointers(Nsimd); | ||||
|  | ||||
| 	  /////////////////////////////////////////// | ||||
| 	  // Work out what to send where | ||||
| 	  /////////////////////////////////////////// | ||||
|  | ||||
| 	  int cb    = (cbmask==0x2)? Odd : Even; | ||||
| 	  int sshift= _grid->CheckerBoardShiftForCB(rhs.checkerboard,dimension,shift,cb); | ||||
| 	   | ||||
| 	  // loop over outer coord planes orthog to dim | ||||
| 	  for(int x=0;x<rd;x++){        | ||||
|  | ||||
| 	    int any_offnode = ( ((x+sshift)%fd) >= rd ); | ||||
|  | ||||
| 	    if ( any_offnode ) { | ||||
|  | ||||
| 	      for(int i=0;i<Nsimd;i++){        | ||||
| 		spointers[i] = &u_simd_send_buf[i][u_comm_offset]; | ||||
| 	      } | ||||
|  | ||||
| 	      int sx   = (x+sshift)%rd; | ||||
| 	       | ||||
| 	      gathermtime-=usecond(); | ||||
| 	      Gather_plane_extract<cobj>(rhs,spointers,dimension,sx,cbmask,compress); | ||||
| 	      gathermtime+=usecond(); | ||||
|  | ||||
| 	      for(int i=0;i<Nsimd;i++){ | ||||
| 		 | ||||
| 		// FIXME  | ||||
| 		// This logic is hard coded to simd_layout ==2 and not allowing >2 | ||||
| 		//		std::cout << "GatherSimd : lane 1st elem " << i << u_simd_send_buf[i ][u_comm_offset]<<std::endl; | ||||
|  | ||||
| 		int inner_bit = (Nsimd>>(permute_type+1)); | ||||
| 		int ic= (i&inner_bit)? 1:0; | ||||
|  | ||||
| 		int my_coor          = rd*ic + x; | ||||
| 		int nbr_coor         = my_coor+sshift; | ||||
| 		int nbr_proc = ((nbr_coor)/ld) % pd;// relative shift in processors | ||||
| 		int nbr_lcoor= (nbr_coor%ld); | ||||
| 		int nbr_ic   = (nbr_lcoor)/rd;    // inner coord of peer | ||||
| 		int nbr_ox   = (nbr_lcoor%rd);    // outer coord of peer | ||||
| 		int nbr_lane = (i&(~inner_bit)); | ||||
| 		 | ||||
| 		if (nbr_ic) nbr_lane|=inner_bit; | ||||
| 		assert (sx == nbr_ox); | ||||
|  | ||||
| 		auto rp = &u_simd_recv_buf[i       ][u_comm_offset]; | ||||
| 		auto sp = &u_simd_send_buf[nbr_lane][u_comm_offset]; | ||||
|  | ||||
| 		void *vrp = (void *)rp; | ||||
| 		void *vsp = (void *)sp; | ||||
|  | ||||
|  | ||||
| 		if(nbr_proc){ | ||||
| 		   | ||||
| 		  int recv_from_rank; | ||||
| 		  int xmit_to_rank; | ||||
|  | ||||
| 		  _grid->ShiftedRanks(dimension,nbr_proc,xmit_to_rank,recv_from_rank);  | ||||
| 		   | ||||
| 		  AddPacket( vsp,vrp,xmit_to_rank,recv_from_rank,bytes); | ||||
| 		   | ||||
| 		  rpointers[i] = rp; | ||||
|  | ||||
| 		} else {  | ||||
|  | ||||
| 		  rpointers[i] = sp; | ||||
|  | ||||
| 		} | ||||
| 	      } | ||||
|  | ||||
| 	      AddMerge(&comm_buf[u_comm_offset],rpointers,buffer_size,Packets.size()-1); | ||||
|  | ||||
| 	      u_comm_offset     +=buffer_size; | ||||
| 	    } | ||||
| 	  } | ||||
| 	} | ||||
|  | ||||
|   }; | ||||
| } | ||||
| #endif | ||||
| @@ -29,27 +29,27 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk> | ||||
| #ifndef GRID_ALGORITHMS_H | ||||
| #define GRID_ALGORITHMS_H | ||||
| 
 | ||||
| #include <algorithms/SparseMatrix.h> | ||||
| #include <algorithms/LinearOperator.h> | ||||
| #include <algorithms/Preconditioner.h> | ||||
| #include <Grid/algorithms/SparseMatrix.h> | ||||
| #include <Grid/algorithms/LinearOperator.h> | ||||
| #include <Grid/algorithms/Preconditioner.h> | ||||
| 
 | ||||
| #include <algorithms/approx/Zolotarev.h> | ||||
| #include <algorithms/approx/Chebyshev.h> | ||||
| #include <algorithms/approx/Remez.h> | ||||
| #include <algorithms/approx/MultiShiftFunction.h> | ||||
| #include <Grid/algorithms/approx/Zolotarev.h> | ||||
| #include <Grid/algorithms/approx/Chebyshev.h> | ||||
| #include <Grid/algorithms/approx/Remez.h> | ||||
| #include <Grid/algorithms/approx/MultiShiftFunction.h> | ||||
| 
 | ||||
| #include <algorithms/iterative/ConjugateGradient.h> | ||||
| #include <algorithms/iterative/ConjugateResidual.h> | ||||
| #include <algorithms/iterative/NormalEquations.h> | ||||
| #include <algorithms/iterative/SchurRedBlack.h> | ||||
| 
 | ||||
| #include <algorithms/iterative/ConjugateGradientMultiShift.h> | ||||
| #include <Grid/algorithms/iterative/ConjugateGradient.h> | ||||
| #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 <algorithms/iterative/MatrixUtils.h> | ||||
| #include <algorithms/iterative/ImplicitlyRestartedLanczos.h> | ||||
| 
 | ||||
| #include <algorithms/CoarsenedMatrix.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
 | ||||
| @@ -31,7 +31,6 @@ Author: paboyle <paboyle@ph.ed.ac.uk> | ||||
| #ifndef  GRID_ALGORITHM_COARSENED_MATRIX_H | ||||
| #define  GRID_ALGORITHM_COARSENED_MATRIX_H | ||||
|  | ||||
| #include <Grid.h> | ||||
|  | ||||
| namespace Grid { | ||||
|  | ||||
| @@ -268,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; | ||||
| @@ -283,7 +281,7 @@ PARALLEL_FOR_LOOP | ||||
| 	  } else if(SE->_is_local) {  | ||||
| 	    nbr = in._odata[SE->_offset]; | ||||
| 	  } else { | ||||
| 	    nbr = Stencil.comm_buf[SE->_offset]; | ||||
| 	    nbr = Stencil.CommBuf()[SE->_offset]; | ||||
| 	  } | ||||
| 	  res = res + A[point]._odata[ss]*nbr; | ||||
| 	} | ||||
| @@ -381,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); | ||||
| @@ -428,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); | ||||
|   | ||||
							
								
								
									
										305
									
								
								lib/algorithms/FFT.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										305
									
								
								lib/algorithms/FFT.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,305 @@ | ||||
|  | ||||
|     /************************************************************************************* | ||||
|  | ||||
|     Grid physics library, www.github.com/paboyle/Grid  | ||||
|  | ||||
|     Source file: ./lib/Cshift.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_FFT_H_ | ||||
| #define _GRID_FFT_H_ | ||||
|  | ||||
| #ifdef HAVE_FFTW | ||||
| #ifdef USE_MKL | ||||
| #include <fftw/fftw3.h> | ||||
| #else | ||||
| #include <fftw3.h> | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
|  | ||||
| namespace Grid { | ||||
|  | ||||
|   template<class scalar> struct FFTW { }; | ||||
|  | ||||
| #ifdef HAVE_FFTW	 | ||||
|   template<> struct FFTW<ComplexD> { | ||||
|   public: | ||||
|  | ||||
|     typedef fftw_complex FFTW_scalar; | ||||
|     typedef fftw_plan    FFTW_plan; | ||||
|  | ||||
|     static FFTW_plan fftw_plan_many_dft(int rank, const int *n,int howmany, | ||||
| 					FFTW_scalar *in, const int *inembed,		 | ||||
| 					int istride, int idist,		 | ||||
| 					FFTW_scalar *out, const int *onembed,		 | ||||
| 					int ostride, int odist,		 | ||||
| 					int sign, unsigned flags) { | ||||
|       return ::fftw_plan_many_dft(rank,n,howmany,in,inembed,istride,idist,out,onembed,ostride,odist,sign,flags); | ||||
|     }	   | ||||
|      | ||||
|     static void fftw_flops(const FFTW_plan p,double *add, double *mul, double *fmas){ | ||||
|       ::fftw_flops(p,add,mul,fmas); | ||||
|     } | ||||
|  | ||||
|     inline static void fftw_execute_dft(const FFTW_plan p,FFTW_scalar *in,FFTW_scalar *out) { | ||||
|       ::fftw_execute_dft(p,in,out); | ||||
|     } | ||||
|     inline static void fftw_destroy_plan(const FFTW_plan p) { | ||||
|       ::fftw_destroy_plan(p); | ||||
|     } | ||||
|   }; | ||||
|  | ||||
|   template<> struct FFTW<ComplexF> { | ||||
|   public: | ||||
|  | ||||
|     typedef fftwf_complex FFTW_scalar; | ||||
|     typedef fftwf_plan    FFTW_plan; | ||||
|  | ||||
|     static FFTW_plan fftw_plan_many_dft(int rank, const int *n,int howmany, | ||||
| 					FFTW_scalar *in, const int *inembed,		 | ||||
| 					int istride, int idist,		 | ||||
| 					FFTW_scalar *out, const int *onembed,		 | ||||
| 					int ostride, int odist,		 | ||||
| 					int sign, unsigned flags) { | ||||
|       return ::fftwf_plan_many_dft(rank,n,howmany,in,inembed,istride,idist,out,onembed,ostride,odist,sign,flags); | ||||
|     }	   | ||||
|      | ||||
|     static void fftw_flops(const FFTW_plan p,double *add, double *mul, double *fmas){ | ||||
|       ::fftwf_flops(p,add,mul,fmas); | ||||
|     } | ||||
|  | ||||
|     inline static void fftw_execute_dft(const FFTW_plan p,FFTW_scalar *in,FFTW_scalar *out) { | ||||
|       ::fftwf_execute_dft(p,in,out); | ||||
|     } | ||||
|     inline static void fftw_destroy_plan(const FFTW_plan p) { | ||||
|       ::fftwf_destroy_plan(p); | ||||
|     } | ||||
|   }; | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #ifndef FFTW_FORWARD | ||||
| #define FFTW_FORWARD (-1) | ||||
| #define FFTW_BACKWARD (+1) | ||||
| #endif | ||||
|  | ||||
|   class FFT { | ||||
|   private: | ||||
|      | ||||
|     GridCartesian *vgrid; | ||||
|     GridCartesian *sgrid; | ||||
|      | ||||
|     int Nd; | ||||
|     double flops; | ||||
|     double flops_call; | ||||
|     uint64_t usec; | ||||
|      | ||||
|     std::vector<int> dimensions; | ||||
|     std::vector<int> processors; | ||||
|     std::vector<int> processor_coor; | ||||
|      | ||||
|   public: | ||||
|      | ||||
|     static const int forward=FFTW_FORWARD; | ||||
|     static const int backward=FFTW_BACKWARD; | ||||
|      | ||||
|     double Flops(void) {return flops;} | ||||
|     double MFlops(void) {return flops/usec;} | ||||
|     double USec(void)   {return (double)usec;}     | ||||
|  | ||||
|     FFT ( GridCartesian * grid ) : | ||||
|     vgrid(grid), | ||||
|     Nd(grid->_ndimension), | ||||
|     dimensions(grid->_fdimensions), | ||||
|     processors(grid->_processors), | ||||
|     processor_coor(grid->_processor_coor) | ||||
|     { | ||||
|       flops=0; | ||||
|       usec =0; | ||||
|       std::vector<int> layout(Nd,1); | ||||
|       sgrid = new GridCartesian(dimensions,layout,processors); | ||||
|     }; | ||||
|      | ||||
|     ~FFT ( void)  { | ||||
|       delete sgrid; | ||||
|     } | ||||
|      | ||||
|     template<class vobj> | ||||
|     void FFT_dim_mask(Lattice<vobj> &result,const Lattice<vobj> &source,std::vector<int> mask,int sign){ | ||||
|  | ||||
|       conformable(result._grid,vgrid); | ||||
|       conformable(source._grid,vgrid); | ||||
|       Lattice<vobj> tmp(vgrid); | ||||
|       tmp = source; | ||||
|       for(int d=0;d<Nd;d++){ | ||||
| 	if( mask[d] ) { | ||||
| 	  FFT_dim(result,tmp,d,sign); | ||||
| 	  tmp=result; | ||||
| 	} | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     template<class vobj> | ||||
|     void FFT_all_dim(Lattice<vobj> &result,const Lattice<vobj> &source,int sign){ | ||||
|       std::vector<int> mask(Nd,1); | ||||
|       FFT_dim_mask(result,source,mask,sign); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     template<class vobj> | ||||
|     void FFT_dim(Lattice<vobj> &result,const Lattice<vobj> &source,int dim, int sign){ | ||||
| #ifndef HAVE_FFTW | ||||
|       assert(0); | ||||
| #else | ||||
|       conformable(result._grid,vgrid); | ||||
|       conformable(source._grid,vgrid); | ||||
|  | ||||
|       int L = vgrid->_ldimensions[dim]; | ||||
|       int G = vgrid->_fdimensions[dim]; | ||||
|        | ||||
|       std::vector<int> layout(Nd,1); | ||||
|       std::vector<int> pencil_gd(vgrid->_fdimensions); | ||||
|        | ||||
|       pencil_gd[dim] = G*processors[dim]; | ||||
|        | ||||
|       // Pencil global vol LxLxGxLxL per node | ||||
|       GridCartesian pencil_g(pencil_gd,layout,processors); | ||||
|        | ||||
|       // Construct pencils | ||||
|       typedef typename vobj::scalar_object sobj; | ||||
|       typedef typename sobj::scalar_type   scalar; | ||||
|        | ||||
|       Lattice<sobj> pgbuf(&pencil_g); | ||||
|        | ||||
|  | ||||
|       typedef typename FFTW<scalar>::FFTW_scalar FFTW_scalar; | ||||
|       typedef typename FFTW<scalar>::FFTW_plan   FFTW_plan; | ||||
|        | ||||
|       int Ncomp = sizeof(sobj)/sizeof(scalar); | ||||
|       int Nlow  = 1; | ||||
|       for(int d=0;d<dim;d++){ | ||||
|         Nlow*=vgrid->_ldimensions[d]; | ||||
|       } | ||||
|        | ||||
|       int rank = 1;  /* 1d transforms */ | ||||
|       int n[] = {G}; /* 1d transforms of length G */ | ||||
|       int howmany = Ncomp; | ||||
|       int odist,idist,istride,ostride; | ||||
|       idist   = odist   = 1;          /* Distance between consecutive FT's */ | ||||
|       istride = ostride = Ncomp*Nlow; /* distance between two elements in the same FT */ | ||||
|       int *inembed = n, *onembed = n; | ||||
|        | ||||
|       scalar div; | ||||
| 	  if ( sign == backward ) div = 1.0/G; | ||||
| 	  else if ( sign == forward ) div = 1.0; | ||||
| 	  else assert(0); | ||||
|        | ||||
|       FFTW_plan p; | ||||
|       { | ||||
|         FFTW_scalar *in = (FFTW_scalar *)&pgbuf._odata[0]; | ||||
|         FFTW_scalar *out= (FFTW_scalar *)&pgbuf._odata[0]; | ||||
|         p = FFTW<scalar>::fftw_plan_many_dft(rank,n,howmany, | ||||
|                                              in,inembed, | ||||
|                                              istride,idist, | ||||
|                                              out,onembed, | ||||
|                                              ostride, odist, | ||||
|                                              sign,FFTW_ESTIMATE); | ||||
|       } | ||||
|        | ||||
|       // Barrel shift and collect global pencil | ||||
|       std::vector<int> lcoor(Nd), gcoor(Nd); | ||||
|       result = source; | ||||
|       for(int p=0;p<processors[dim];p++) { | ||||
|         PARALLEL_REGION | ||||
|         { | ||||
|           std::vector<int> cbuf(Nd); | ||||
|           sobj s; | ||||
|            | ||||
|           PARALLEL_FOR_LOOP_INTERN | ||||
|           for(int idx=0;idx<sgrid->lSites();idx++) { | ||||
|             sgrid->LocalIndexToLocalCoor(idx,cbuf); | ||||
|             peekLocalSite(s,result,cbuf); | ||||
|             cbuf[dim]+=p*L; | ||||
|             pokeLocalSite(s,pgbuf,cbuf); | ||||
|           } | ||||
|         } | ||||
|         if (p != processors[dim] - 1) | ||||
|         { | ||||
|           result = Cshift(result,dim,L); | ||||
|         } | ||||
|       } | ||||
|        | ||||
|       // Loop over orthog coords | ||||
|       int NN=pencil_g.lSites(); | ||||
|       GridStopWatch timer; | ||||
|       timer.Start(); | ||||
|       PARALLEL_REGION | ||||
|       { | ||||
|         std::vector<int> cbuf(Nd); | ||||
|          | ||||
|         PARALLEL_FOR_LOOP_INTERN | ||||
|         for(int idx=0;idx<NN;idx++) { | ||||
|           pencil_g.LocalIndexToLocalCoor(idx, cbuf); | ||||
|           if ( cbuf[dim] == 0 ) {  // restricts loop to plane at lcoor[dim]==0 | ||||
|             FFTW_scalar *in = (FFTW_scalar *)&pgbuf._odata[idx]; | ||||
|             FFTW_scalar *out= (FFTW_scalar *)&pgbuf._odata[idx]; | ||||
|             FFTW<scalar>::fftw_execute_dft(p,in,out); | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|       timer.Stop(); | ||||
|        | ||||
|       // performance counting | ||||
|       double add,mul,fma; | ||||
|       FFTW<scalar>::fftw_flops(p,&add,&mul,&fma); | ||||
|       flops_call = add+mul+2.0*fma; | ||||
|       usec += timer.useconds(); | ||||
|       flops+= flops_call*NN; | ||||
|        | ||||
|       // writing out result | ||||
|       int pc = processor_coor[dim]; | ||||
|       PARALLEL_REGION | ||||
|       { | ||||
|         std::vector<int> clbuf(Nd), cgbuf(Nd); | ||||
|         sobj s; | ||||
|          | ||||
|         PARALLEL_FOR_LOOP_INTERN | ||||
|         for(int idx=0;idx<sgrid->lSites();idx++) { | ||||
|           sgrid->LocalIndexToLocalCoor(idx,clbuf); | ||||
|           cgbuf = clbuf; | ||||
|           cgbuf[dim] = clbuf[dim]+L*pc; | ||||
|           peekLocalSite(s,pgbuf,cgbuf); | ||||
|           pokeLocalSite(s,result,clbuf); | ||||
|         } | ||||
|       } | ||||
|       result = result*div; | ||||
|        | ||||
|       // destroying plan | ||||
|       FFTW<scalar>::fftw_destroy_plan(p); | ||||
| #endif | ||||
|     } | ||||
|   }; | ||||
| } | ||||
|  | ||||
| #endif | ||||
| @@ -28,7 +28,6 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk> | ||||
| #ifndef  GRID_ALGORITHM_SPARSE_MATRIX_H | ||||
| #define  GRID_ALGORITHM_SPARSE_MATRIX_H | ||||
|  | ||||
| #include <Grid.h> | ||||
|  | ||||
| namespace Grid { | ||||
|  | ||||
|   | ||||
| @@ -29,8 +29,7 @@ Author: paboyle <paboyle@ph.ed.ac.uk> | ||||
| #ifndef GRID_CHEBYSHEV_H | ||||
| #define GRID_CHEBYSHEV_H | ||||
|  | ||||
| #include<Grid.h> | ||||
| #include<algorithms/LinearOperator.h> | ||||
| #include <Grid/algorithms/LinearOperator.h> | ||||
|  | ||||
| namespace Grid { | ||||
|  | ||||
|   | ||||
| @@ -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)  | ||||
|   | ||||
| @@ -18,10 +18,10 @@ | ||||
| #include <stddef.h> | ||||
| #include <Config.h> | ||||
|  | ||||
| #ifdef HAVE_GMP_H | ||||
| #include <algorithms/approx/bigfloat.h> | ||||
| #ifdef HAVE_LIBGMP | ||||
| #include "bigfloat.h" | ||||
| #else | ||||
| #include <algorithms/approx/bigfloat_double.h> | ||||
| #include "bigfloat_double.h" | ||||
| #endif | ||||
|  | ||||
| #define JMAX 10000 //Maximum number of iterations of Newton's approximation | ||||
|   | ||||
| @@ -1,150 +1,171 @@ | ||||
|     /************************************************************************************* | ||||
| /************************************************************************************* | ||||
|  | ||||
|     Grid physics library, www.github.com/paboyle/Grid  | ||||
| Grid physics library, www.github.com/paboyle/Grid | ||||
|  | ||||
|     Source file: ./lib/algorithms/iterative/ConjugateGradient.h | ||||
| Source file: ./lib/algorithms/iterative/ConjugateGradient.h | ||||
|  | ||||
|     Copyright (C) 2015 | ||||
| Copyright (C) 2015 | ||||
|  | ||||
| Author: Azusa Yamaguchi <ayamaguc@staffmail.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 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. | ||||
| 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. | ||||
| 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 */ | ||||
| See the full license in the file "LICENSE" in the top level distribution | ||||
| directory | ||||
| *************************************************************************************/ | ||||
| /*  END LEGAL */ | ||||
| #ifndef GRID_CONJUGATE_GRADIENT_H | ||||
| #define GRID_CONJUGATE_GRADIENT_H | ||||
|  | ||||
| namespace Grid { | ||||
|  | ||||
|     ///////////////////////////////////////////////////////////// | ||||
|     // Base classes for iterative processes based on operators | ||||
|     // single input vec, single output vec. | ||||
|     ///////////////////////////////////////////////////////////// | ||||
| ///////////////////////////////////////////////////////////// | ||||
| // Base classes for iterative processes based on operators | ||||
| // single input vec, single output vec. | ||||
| ///////////////////////////////////////////////////////////// | ||||
|  | ||||
|   template<class Field>  | ||||
|     class ConjugateGradient : public OperatorFunction<Field> { | ||||
| public:                                                 | ||||
|     RealD   Tolerance; | ||||
|     Integer MaxIterations; | ||||
|     ConjugateGradient(RealD tol,Integer maxit) : Tolerance(tol), MaxIterations(maxit) {  | ||||
|     }; | ||||
| template <class Field> | ||||
| class ConjugateGradient : public OperatorFunction<Field> { | ||||
|  public: | ||||
|   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 | ||||
|    | ||||
|   ConjugateGradient(RealD tol, Integer maxit, bool err_on_no_conv = true) | ||||
|       : Tolerance(tol), | ||||
|         MaxIterations(maxit), | ||||
|         ErrorOnNoConverge(err_on_no_conv){}; | ||||
|  | ||||
|   void operator()(LinearOperatorBase<Field> &Linop, const Field &src, | ||||
|                   Field &psi) { | ||||
|     psi.checkerboard = src.checkerboard; | ||||
|     conformable(psi, src); | ||||
|  | ||||
|     RealD cp, c, a, d, b, ssq, qq, b_pred; | ||||
|  | ||||
|     Field p(src); | ||||
|     Field mmp(src); | ||||
|     Field r(src); | ||||
|  | ||||
|     // Initial residual computation & set up | ||||
|     RealD guess = norm2(psi); | ||||
|     assert(std::isnan(guess) == 0); | ||||
|  | ||||
|      | ||||
|     void operator() (LinearOperatorBase<Field> &Linop,const Field &src, Field &psi){ | ||||
|     Linop.HermOpAndNorm(psi, mmp, d, b); | ||||
|      | ||||
|       psi.checkerboard = src.checkerboard; | ||||
|       conformable(psi,src); | ||||
|  | ||||
|       RealD cp,c,a,d,b,ssq,qq,b_pred; | ||||
|     r = src - mmp; | ||||
|     p = r; | ||||
|  | ||||
|       Field   p(src); | ||||
|       Field mmp(src); | ||||
|       Field   r(src); | ||||
|     a = norm2(p); | ||||
|     cp = a; | ||||
|     ssq = norm2(src); | ||||
|  | ||||
|       //Initial residual computation & set up | ||||
|       RealD guess = norm2(psi); | ||||
|       assert(std::isnan(guess)==0); | ||||
|     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; | ||||
|  | ||||
|       Linop.HermOpAndNorm(psi,mmp,d,b); | ||||
|     RealD rsq = Tolerance * Tolerance * ssq; | ||||
|  | ||||
|       r= src-mmp; | ||||
|       p= r; | ||||
|        | ||||
|       a  =norm2(p); | ||||
|       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; | ||||
|  | ||||
|       RealD rsq =  Tolerance* Tolerance*ssq; | ||||
|        | ||||
|       //Check if guess is really REALLY good :) | ||||
|       if ( cp <= rsq ) { | ||||
| 	return; | ||||
|       } | ||||
|        | ||||
|       std::cout<<GridLogIterative << std::setprecision(4)<< "ConjugateGradient: k=0 residual "<<cp<<" target "<<rsq<<std::endl; | ||||
|  | ||||
|       GridStopWatch LinalgTimer; | ||||
|       GridStopWatch MatrixTimer; | ||||
|       GridStopWatch SolverTimer; | ||||
|  | ||||
|       SolverTimer.Start(); | ||||
|       int k; | ||||
|       for (k=1;k<=MaxIterations;k++){ | ||||
| 	 | ||||
| 	c=cp; | ||||
|  | ||||
| 	MatrixTimer.Start(); | ||||
| 	Linop.HermOpAndNorm(p,mmp,d,qq); | ||||
| 	MatrixTimer.Stop(); | ||||
|  | ||||
| 	LinalgTimer.Start(); | ||||
| 	//	RealD    qqck = norm2(mmp); | ||||
| 	//	ComplexD dck  = innerProduct(p,mmp); | ||||
|        | ||||
| 	a      = c/d; | ||||
| 	b_pred = a*(a*qq-d)/c; | ||||
|  | ||||
| 	cp = axpy_norm(r,-a,mmp,r); | ||||
| 	b = cp/c; | ||||
| 	 | ||||
| 	// Fuse these loops ; should be really easy | ||||
| 	psi= a*p+psi; | ||||
| 	p  = p*b+r; | ||||
| 	   | ||||
| 	LinalgTimer.Stop(); | ||||
| 	std::cout<<GridLogIterative<<"ConjugateGradient: Iteration " <<k<<" residual "<<cp<< " target "<< rsq<<std::endl; | ||||
| 	 | ||||
| 	// Stopping condition | ||||
| 	if ( cp <= rsq ) {  | ||||
| 	   | ||||
| 	  SolverTimer.Stop(); | ||||
| 	  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 | ||||
| 		   <<" computed residual "<<sqrt(cp/ssq) | ||||
| 		   <<" true residual "    <<true_residual | ||||
| 		   <<" target "<<Tolerance<<std::endl; | ||||
| 	  std::cout<<GridLogMessage<<"Time elapsed: Total "<< SolverTimer.Elapsed() << " Matrix  "<<MatrixTimer.Elapsed() << " Linalg "<<LinalgTimer.Elapsed(); | ||||
| 	  std::cout<<std::endl; | ||||
| 	   | ||||
| 	  assert(true_residual/Tolerance < 1000.0); | ||||
|  | ||||
| 	  return; | ||||
| 	} | ||||
|       } | ||||
|       std::cout<<GridLogMessage<<"ConjugateGradient did NOT converge"<<std::endl; | ||||
|       assert(0); | ||||
|     // Check if guess is really REALLY good :) | ||||
|     if (cp <= rsq) { | ||||
|       return; | ||||
|     } | ||||
|   }; | ||||
|  | ||||
|     std::cout << GridLogIterative << std::setprecision(4) | ||||
|               << "ConjugateGradient: k=0 residual " << cp << " target " << rsq | ||||
|               << std::endl; | ||||
|  | ||||
|     GridStopWatch LinalgTimer; | ||||
|     GridStopWatch MatrixTimer; | ||||
|     GridStopWatch SolverTimer; | ||||
|  | ||||
|     SolverTimer.Start(); | ||||
|     int k; | ||||
|     for (k = 1; k <= MaxIterations; k++) { | ||||
|       c = cp; | ||||
|  | ||||
|       MatrixTimer.Start(); | ||||
|       Linop.HermOpAndNorm(p, mmp, d, qq); | ||||
|       MatrixTimer.Stop(); | ||||
|  | ||||
|       LinalgTimer.Start(); | ||||
|       //  RealD    qqck = norm2(mmp); | ||||
|       //  ComplexD dck  = innerProduct(p,mmp); | ||||
|  | ||||
|       a = c / d; | ||||
|       b_pred = a * (a * qq - d) / c; | ||||
|  | ||||
|       cp = axpy_norm(r, -a, mmp, r); | ||||
|       b = cp / c; | ||||
|  | ||||
|       // Fuse these loops ; should be really easy | ||||
|       psi = a * p + psi; | ||||
|       p = p * b + r; | ||||
|  | ||||
|       LinalgTimer.Stop(); | ||||
|       std::cout << GridLogIterative << "ConjugateGradient: Iteration " << k | ||||
|                 << " residual " << cp << " target " << rsq << std::endl; | ||||
|  | ||||
|       // Stopping condition | ||||
|       if (cp <= rsq) { | ||||
|         SolverTimer.Stop(); | ||||
|         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; | ||||
|  | ||||
|         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; | ||||
|   } | ||||
| }; | ||||
| } | ||||
| #endif | ||||
|   | ||||
							
								
								
									
										154
									
								
								lib/algorithms/iterative/ConjugateGradientMixedPrec.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								lib/algorithms/iterative/ConjugateGradientMixedPrec.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,154 @@ | ||||
|     /************************************************************************************* | ||||
|  | ||||
|     Grid physics library, www.github.com/paboyle/Grid  | ||||
|  | ||||
|     Source file: ./lib/algorithms/iterative/ConjugateGradientMixedPrec.h | ||||
|  | ||||
|     Copyright (C) 2015 | ||||
|  | ||||
| Author: Christopher Kelly <ckelly@phys.columbia.edu> | ||||
|  | ||||
|     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_CONJUGATE_GRADIENT_MIXED_PREC_H | ||||
| #define GRID_CONJUGATE_GRADIENT_MIXED_PREC_H | ||||
|  | ||||
| namespace Grid { | ||||
|  | ||||
|   //Mixed precision restarted defect correction CG | ||||
|   template<class FieldD,class FieldF, typename std::enable_if< getPrecision<FieldD>::value == 2, int>::type = 0,typename std::enable_if< getPrecision<FieldF>::value == 1, int>::type = 0>  | ||||
|   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 | ||||
|     RealD OuterLoopNormMult; //Stop the outer loop and move to a final double prec solve when the residual is OuterLoopNormMult * Tolerance | ||||
|     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), InnerTolerance(tol), MaxInnerIterations(maxinnerit), MaxOuterIterations(maxouterit), SinglePrecGrid(_sp_grid), | ||||
|       OuterLoopNormMult(100.), guesser(NULL){ }; | ||||
|  | ||||
|     void useGuesser(LinearFunction<FieldF> &g){ | ||||
|       guesser = &g; | ||||
|     } | ||||
|    | ||||
|     void operator() (const FieldD &src_d_in, FieldD &sol_d){ | ||||
|       TotalInnerIterations = 0; | ||||
| 	 | ||||
|       GridStopWatch TotalTimer; | ||||
|       TotalTimer.Start(); | ||||
|      | ||||
|       int cb = src_d_in.checkerboard; | ||||
|       sol_d.checkerboard = cb; | ||||
|      | ||||
|       RealD src_norm = norm2(src_d_in); | ||||
|       RealD stop = src_norm * Tolerance*Tolerance; | ||||
|  | ||||
|       GridBase* DoublePrecGrid = src_d_in._grid; | ||||
|       FieldD tmp_d(DoublePrecGrid); | ||||
|       tmp_d.checkerboard = cb; | ||||
|      | ||||
|       FieldD tmp2_d(DoublePrecGrid); | ||||
|       tmp2_d.checkerboard = cb; | ||||
|      | ||||
|       FieldD src_d(DoublePrecGrid); | ||||
|       src_d = src_d_in; //source for next inner iteration, computed from residual during operation | ||||
|      | ||||
|       RealD inner_tol = InnerTolerance; | ||||
|      | ||||
|       FieldF src_f(SinglePrecGrid); | ||||
|       src_f.checkerboard = cb; | ||||
|      | ||||
|       FieldF sol_f(SinglePrecGrid); | ||||
|       sol_f.checkerboard = cb; | ||||
|      | ||||
|       ConjugateGradient<FieldF> CG_f(inner_tol, MaxInnerIterations); | ||||
|       CG_f.ErrorOnNoConverge = false; | ||||
|  | ||||
|       GridStopWatch InnerCGtimer; | ||||
|  | ||||
|       GridStopWatch PrecChangeTimer; | ||||
|      | ||||
|       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 | ||||
|        | ||||
| 	std::cout<<GridLogMessage<<"MixedPrecisionConjugateGradient: Outer iteration " <<outer_iter<<" residual "<< norm<< " target "<< stop<<std::endl; | ||||
|  | ||||
| 	if(norm < OuterLoopNormMult * stop){ | ||||
| 	  std::cout<<GridLogMessage<<"MixedPrecisionConjugateGradient: Outer iteration converged on iteration " <<outer_iter <<std::endl; | ||||
| 	  break; | ||||
| 	} | ||||
| 	while(norm * inner_tol * inner_tol < stop) inner_tol *= 2;  // inner_tol = sqrt(stop/norm) ?? | ||||
|  | ||||
| 	PrecChangeTimer.Start(); | ||||
| 	precisionChange(src_f, src_d); | ||||
| 	PrecChangeTimer.Stop(); | ||||
|        | ||||
| 	zeroit(sol_f); | ||||
|  | ||||
| 	//Optionally improve inner solver guess (eg using known eigenvectors) | ||||
| 	if(guesser != NULL) | ||||
| 	  (*guesser)(src_f, sol_f); | ||||
|  | ||||
| 	//Inner CG | ||||
| 	CG_f.Tolerance = inner_tol; | ||||
| 	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(); | ||||
| 	precisionChange(tmp_d, sol_f); | ||||
| 	PrecChangeTimer.Stop(); | ||||
|        | ||||
| 	axpy(sol_d, 1.0, tmp_d, sol_d); | ||||
|       } | ||||
|      | ||||
|       //Final trial CG | ||||
|       std::cout<<GridLogMessage<<"MixedPrecisionConjugateGradient: Starting final patch-up double-precision solve"<<std::endl; | ||||
|      | ||||
|       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: 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; | ||||
|     } | ||||
|   }; | ||||
|  | ||||
| } | ||||
|  | ||||
| #endif | ||||
| @@ -243,8 +243,6 @@ void operator() (LinearOperatorBase<Field> &Linop, const Field &src, std::vector | ||||
|       if ( (!converged[s]) ){ | ||||
| 	 | ||||
| 	RealD css  = c * z[s][iz]* z[s][iz]; | ||||
|     if((k%100)==0 && (s==0) ) | ||||
| 	    std::cout<<GridLogMessage<<"ConjugateGradientMultiShift k="<<k<<" css " <<css <<std::endl; | ||||
| 	 | ||||
| 	if(css<rsq[s]){ | ||||
| 	  if ( ! converged[s] ) | ||||
|   | ||||
| @@ -130,8 +130,8 @@ DenseMatrix<T> GetSubMtx(DenseMatrix<T> &A,int row_st, int row_end, int col_st, | ||||
|  | ||||
| } | ||||
|  | ||||
| #include <algorithms/iterative/Householder.h> | ||||
| #include <algorithms/iterative/Francis.h> | ||||
| #include "Householder.h" | ||||
| #include "Francis.h" | ||||
|  | ||||
| #endif | ||||
|  | ||||
|   | ||||
| @@ -31,10 +31,14 @@ Author: paboyle <paboyle@ph.ed.ac.uk> | ||||
|  | ||||
| #include <string.h> //memset | ||||
| #ifdef USE_LAPACK | ||||
| #include <lapacke.h> | ||||
| void LAPACK_dstegr(char *jobz, char *range, int *n, double *d, double *e, | ||||
|                    double *vl, double *vu, int *il, int *iu, double *abstol, | ||||
|                    int *m, double *w, double *z, int *ldz, int *isuppz, | ||||
|                    double *work, int *lwork, int *iwork, int *liwork, | ||||
|                    int *info); | ||||
| #endif | ||||
| #include <algorithms/iterative/DenseMatrix.h> | ||||
| #include <algorithms/iterative/EigenSort.h> | ||||
| #include "DenseMatrix.h" | ||||
| #include "EigenSort.h" | ||||
|  | ||||
| namespace Grid { | ||||
|  | ||||
| @@ -1076,10 +1080,10 @@ say con = 2 | ||||
| **/ | ||||
|  | ||||
| template<class T> | ||||
| static void Lock(DenseMatrix<T> &H, 	///Hess mtx	 | ||||
| 		 DenseMatrix<T> &Q, 	///Lock Transform | ||||
| 		 T val, 		///value to be locked | ||||
| 		 int con, 	///number already locked | ||||
| static void Lock(DenseMatrix<T> &H, 	// Hess mtx	 | ||||
| 		 DenseMatrix<T> &Q, 	// Lock Transform | ||||
| 		 T val, 		// value to be locked | ||||
| 		 int con, 	// number already locked | ||||
| 		 RealD small, | ||||
| 		 int dfg, | ||||
| 		 bool herm) | ||||
|   | ||||
| @@ -36,7 +36,7 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk> | ||||
| #include <iomanip> | ||||
| #include <complex> | ||||
| #include <typeinfo> | ||||
| #include <Grid.h> | ||||
| #include <Grid/Grid.h> | ||||
|  | ||||
|  | ||||
| /** Sign function **/ | ||||
|   | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user