mirror of
				https://github.com/paboyle/Grid.git
				synced 2025-10-28 02:29:34 +00:00 
			
		
		
		
	Compare commits
	
		
			536 Commits
		
	
	
		
			feature/mp
			...
			feature/no
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 8e161152e4 | ||
|  | 3141ebac10 | ||
|  | 7ede696126 | ||
|  | bf516c3b81 | ||
|  | 441a52ee5d | ||
|  | a8db024c92 | ||
|  | a9c22d5f43 | ||
|  | 3ca41458a3 | ||
|  | 951be75292 | ||
|  | b9113ed310 | ||
|  | 42fb49d3fd | ||
|  | 2a54c9aaab | ||
|  | 0957378679 | ||
|  | 2ed6c76fc5 | ||
|  | d3b9a7fa14 | ||
|  | 75ea306ce9 | ||
|  | 4226c633c4 | ||
|  | 5a4eafbf7e | ||
|  | eb8e26018b | ||
|  | db5ea001a3 | ||
|  | 2846f079e5 | ||
|  | 1d502e4ed6 | ||
|  | 73cdf0fffe | ||
|  | 1c25773319 | ||
|  | c38400b26f | ||
|  | 9c3065b860 | ||
|  | 94eb829d08 | ||
|  | 68392ddb5b | ||
|  | cb6b81ae82 | ||
| 8ef4300412 | |||
| 98a24ebf31 | |||
|  | b12dc89d26 | ||
|  | d80d802f9d | ||
|  | 3d99b09dba | ||
|  | db5f6d3ae3 | ||
|  | 683550f116 | ||
|  | 55d0329624 | ||
|  | 86aaa35294 | ||
|  | 172d3dc93a | ||
|  | 5592f7b8c1 | ||
|  | 35da4ece0b | ||
|  | 061b15b9e9 | ||
|  | 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 | ||
| 7c8f79b147 | |||
| 462921e549 | |||
| bd6a228af6 | |||
| 63d219498b | |||
| 997fd882ff | |||
|  | a123dcd7e9 | ||
|  | 6b27c42dfe | ||
|  | f7c2aa3ba5 | ||
|  | 6e01264bb7 | ||
|  | 6f408256bc | ||
|  | 8d11681aac | ||
|  | 3d5c9a1ee9 | ||
|  | db749f103f | ||
|  | dc389e467c | ||
|  | 3619167d62 | ||
|  | 96f1d1b828 | ||
|  | 657e0a8f4d | ||
|  | 616e7cd83e | ||
|  | 6f26d2e8d4 | ||
|  | c014574504 | ||
|  | d7ce164e6e | ||
|  | c0d5b99016 | ||
|  | 09ca32d678 | ||
|  | 082ae350c6 | ||
| cb02b7088f | |||
|  | 87acd06990 | ||
|  | 9353b6edfe | ||
|  | 167cc2650e | ||
|  | 34f887ca1c | ||
|  | 7089b6d5a5 | ||
|  | 2ba7d43ddd | ||
|  | 836e929565 | ||
|  | b6713ecb60 | ||
|  | 52a39f0fcd | ||
|  | 81a7a03076 | ||
|  | 16b37b956c | ||
|  | 567b6cf23f | ||
|  | 296396646d | ||
| a034e9901b | |||
|  | 7422953e36 | ||
|  | 8535d433a7 | ||
|  | b573d1f35a | ||
|  | 0c1d7e4daf | ||
|  | 02e983a0cd | ||
|  | d15ab66aae | ||
|  | 9005b82c6d | ||
|  | 3475f45ce7 | ||
|  | 0744f38866 | ||
|  | 62febd2823 | ||
| 17c843700e | |||
| 7b56f63a5c | |||
| b1cfb4d661 | |||
| 7ff7c7d90d | |||
| a2e9430abe | |||
| 2485ef9c9c | |||
| e0b7004f96 | |||
| 75fc295f6e | |||
| 0b731b5d80 | |||
| 8e2078be71 | |||
| 1826ed06a3 | |||
| 3ff96c502b | |||
| 15a0908bfc | |||
| bb2125962b | |||
| 232fda5fe1 | |||
| 2b31bf61ff | |||
| afe5a94745 | |||
| 7ae667c767 | |||
| 07f0b69784 | |||
| 5c06e89d69 | |||
| 3d75e0f0d1 | |||
| 362f255100 | |||
| 3d78ed03ef | |||
| 835003b3c5 | |||
| 328d213c9e | |||
| 56a8d7a5bc | |||
| 78198d1b04 | |||
| 84fa2bdce6 | |||
| 29dfe99e7c | |||
| d604580e5a | |||
| 7dfdc9baa0 | |||
| 9e986654e6 | |||
| df3fbc477e | |||
| bb580ae077 | |||
| 2c226753ab | |||
| ea0cea668e | |||
| 75cd72a421 | |||
| cbe52b0659 | |||
| 3aa6463ede | |||
| 312637e5fb | |||
| 798d8f7340 | |||
| ba878724ce | |||
| b865dd9da8 | |||
| 8b313a35ac | |||
| 02ec23cdad | |||
| 6e83b6a203 | |||
| 48fcc34d72 | |||
| d08d93c44c | |||
| 0ab10cdedb | |||
| 22653edf12 | |||
| 12d2a95846 | |||
| 978cf52f6b | |||
| 63b730de80 | |||
| 7905c5b8e5 | |||
| 5e4b58ac40 | |||
| 468d8dc682 | |||
| beb11fd4ef | |||
| d7662b5175 | |||
| dc5f32e5f0 | |||
| 1869d28429 | |||
| 405b175665 | |||
| e33b0f6ff7 | |||
| 9ee54e0db7 | |||
| feae35d92c | |||
| 3834d81181 | |||
| 179e82b5ca | |||
| f2c59c8730 | |||
| fdd0848593 | |||
| 92f666905f | |||
| 5980fa8640 | |||
| a0d8eb2c24 | |||
| 1e10b4571d | |||
| 02f8b84ac9 | |||
| cfd368596d | |||
| ae682674e0 | |||
| 17c43f49ac | |||
| 30146e977c | |||
| 54eacec261 | |||
| 76c78f04e2 | |||
| 379580cd89 | |||
| 14a80733f9 | |||
| d4db009a58 | |||
| 20ce7e0270 | |||
| bb195607ab | |||
| 6f090e22c0 | |||
| 339e983172 | |||
| 4a7f3d1b7b | |||
| c4e2202550 | |||
| 538b16610b | 
							
								
								
									
										17
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										17
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -9,6 +9,7 @@ | |||||||
| ################ | ################ | ||||||
| *~ | *~ | ||||||
| *# | *# | ||||||
|  | *.sublime-* | ||||||
|  |  | ||||||
| # Precompiled Headers # | # Precompiled Headers # | ||||||
| ####################### | ####################### | ||||||
| @@ -47,7 +48,9 @@ Config.h.in | |||||||
| config.log | config.log | ||||||
| config.status | config.status | ||||||
| .deps | .deps | ||||||
| *.inc | Make.inc | ||||||
|  | eigen.inc | ||||||
|  | Eigen.inc | ||||||
|  |  | ||||||
| # http://www.gnu.org/software/autoconf # | # http://www.gnu.org/software/autoconf # | ||||||
| ######################################## | ######################################## | ||||||
| @@ -102,3 +105,15 @@ lib/fftw/* | |||||||
| ################## | ################## | ||||||
| m4/lt* | m4/lt* | ||||||
| m4/libtool.m4 | 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 | ||||||
							
								
								
									
										15
									
								
								.travis.yml
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								.travis.yml
									
									
									
									
									
								
							| @@ -7,7 +7,7 @@ cache: | |||||||
| matrix: | matrix: | ||||||
|   include: |   include: | ||||||
|     - os:        osx |     - os:        osx | ||||||
|       osx_image: xcode7.2 |       osx_image: xcode8.3 | ||||||
|       compiler: clang |       compiler: clang | ||||||
|     - compiler: gcc |     - compiler: gcc | ||||||
|       addons: |       addons: | ||||||
| @@ -73,8 +73,6 @@ before_install: | |||||||
|     - if [[ "$TRAVIS_OS_NAME" == "linux" ]] && [[ "$CC" == "clang" ]]; then export LD_LIBRARY_PATH="${GRIDDIR}/clang/lib:${LD_LIBRARY_PATH}"; fi |     - if [[ "$TRAVIS_OS_NAME" == "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 update; fi | ||||||
|     - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install libmpc; 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: | install: | ||||||
|     - export CC=$CC$VERSION |     - export CC=$CC$VERSION | ||||||
| @@ -92,15 +90,14 @@ script: | |||||||
|     - cd build |     - cd build | ||||||
|     - ../configure --enable-precision=single --enable-simd=SSE4 --enable-comms=none |     - ../configure --enable-precision=single --enable-simd=SSE4 --enable-comms=none | ||||||
|     - make -j4  |     - make -j4  | ||||||
|     - ./benchmarks/Benchmark_dwf --threads 1 |     - ./benchmarks/Benchmark_dwf --threads 1 --debug-signals | ||||||
|     - echo make clean |     - echo make clean | ||||||
|     - ../configure --enable-precision=double --enable-simd=SSE4 --enable-comms=none |     - ../configure --enable-precision=double --enable-simd=SSE4 --enable-comms=none | ||||||
|     - make -j4 |     - make -j4 | ||||||
|     - ./benchmarks/Benchmark_dwf --threads 1 |     - ./benchmarks/Benchmark_dwf --threads 1 --debug-signals | ||||||
|     - echo make clean |     - echo make clean | ||||||
|     - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then export CXXFLAGS='-DMPI_UINT32_T=MPI_UNSIGNED -DMPI_UINT64_T=MPI_UNSIGNED_LONG'; fi |     - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ../configure --enable-precision=single --enable-simd=SSE4 --enable-comms=mpi-auto CXXFLAGS='-DMPI_UINT32_T=MPI_UNSIGNED -DMPI_UINT64_T=MPI_UNSIGNED_LONG'; fi | ||||||
|     - ../configure --enable-precision=single --enable-simd=SSE4 --enable-comms=mpi-auto |     - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then make -j4; fi | ||||||
|     - make -j4 |  | ||||||
|     - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then mpirun.openmpi -n 2 ./benchmarks/Benchmark_dwf --threads 1 --mpi 2.1.1.1; fi |     - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then mpirun.openmpi -n 2 ./benchmarks/Benchmark_dwf --threads 1 --mpi 2.1.1.1; fi | ||||||
|     - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then mpirun -n 2 ./benchmarks/Benchmark_dwf --threads 1 --mpi 2.1.1.1; fi |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,5 +1,12 @@ | |||||||
| # additional include paths necessary to compile the C++ library | # additional include paths necessary to compile the C++ library | ||||||
| SUBDIRS = lib benchmarks tests | SUBDIRS = lib benchmarks tests extras | ||||||
|  |  | ||||||
|  | include $(top_srcdir)/doxygen.inc | ||||||
|  |  | ||||||
|  | tests: all | ||||||
|  | 	$(MAKE) -C tests tests | ||||||
|  |  | ||||||
|  | .PHONY: tests doxygen-run doxygen-doc $(DX_PS_GOAL) $(DX_PDF_GOAL) | ||||||
|  |  | ||||||
| AM_CXXFLAGS += -I$(top_builddir)/include | AM_CXXFLAGS += -I$(top_builddir)/include | ||||||
| ACLOCAL_AMFLAGS = -I m4 | 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 |  | ||||||
|       |  | ||||||
|       |  | ||||||
							
								
								
									
										118
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										118
									
								
								README.md
									
									
									
									
									
								
							| @@ -16,11 +16,27 @@ | |||||||
|  |  | ||||||
| **Data parallel C++ mathematical object library.** | **Data parallel C++ mathematical object library.** | ||||||
|  |  | ||||||
| Please send all pull requests to the `develop` branch. |  | ||||||
|  |  | ||||||
| License: GPL v2. | License: GPL v2. | ||||||
|  |  | ||||||
| Last update 2016/08/03. | 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 | ### Description | ||||||
| This library provides data parallel C++ container classes with internal memory layout | This library provides data parallel C++ container classes with internal memory layout | ||||||
| @@ -29,7 +45,7 @@ are provided, similar to HPF and cmfortran, and user control is given over the m | |||||||
| array indices to both MPI tasks and SIMD processing elements. | array indices to both MPI tasks and SIMD processing elements. | ||||||
|  |  | ||||||
| * Identically shaped arrays then be processed with perfect data parallelisation. | * 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 | The transformation is based on the observation that Cartesian array processing involves | ||||||
| identical processing to be performed on different regions of the Cartesian array. | identical processing to be performed on different regions of the Cartesian array. | ||||||
| @@ -42,7 +58,7 @@ optimally use MPI, OpenMP and SIMD parallelism under the hood. This is a signifi | |||||||
| for most programmers. | for most programmers. | ||||||
|  |  | ||||||
| The layout transformations are parametrised by the SIMD vector length. This adapts according to the architecture. | 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 and BG/Q QPX 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`, and `vComplexD` internal vector data types. These may be useful in themselves for other programmers. | 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`. | The corresponding scalar types are named `RealF`, `RealD`, `ComplexF` and `ComplexD`. | ||||||
| @@ -50,7 +66,7 @@ The corresponding scalar types are named `RealF`, `RealD`, `ComplexF` and `Compl | |||||||
| MPI, OpenMP, and SIMD parallelism are present in the library. | MPI, OpenMP, and SIMD parallelism are present in the library. | ||||||
| Please see https://arxiv.org/abs/1512.03487 for more detail. | Please see https://arxiv.org/abs/1512.03487 for more detail. | ||||||
|  |  | ||||||
| ### Installation | ### Quick start | ||||||
| First, start by cloning the repository: | First, start by cloning the repository: | ||||||
|  |  | ||||||
| ``` bash | ``` bash | ||||||
| @@ -71,12 +87,10 @@ mkdir build; cd build | |||||||
| ../configure --enable-precision=double --enable-simd=AVX --enable-comms=mpi-auto --prefix=<path> | ../configure --enable-precision=double --enable-simd=AVX --enable-comms=mpi-auto --prefix=<path> | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| where `--enable-precision=` set the default precision (`single` or `double`), | where `--enable-precision=` set the default precision, | ||||||
| `--enable-simd=` set the SIMD type (see possible values below), `--enable- | `--enable-simd=` set the SIMD type, `--enable- | ||||||
| comms=` set the protocol used for communications (`none`, `mpi`, `mpi-auto` or | comms=`, and `<path>` should be replaced by the prefix path where you want to | ||||||
| `shmem`), 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 | ||||||
| install Grid. The `mpi-auto` communication option set `configure` to determine |  | ||||||
| automatically how to link to MPI. Other options are available, use `configure |  | ||||||
| --help` to display them. Like with any other program using GNU autotool, the | --help` to display them. Like with any other program using GNU autotool, the | ||||||
| `CXX`, `CXXFLAGS`, `LDFLAGS`, ... environment variables can be modified to | `CXX`, `CXXFLAGS`, `LDFLAGS`, ... environment variables can be modified to | ||||||
| customise the build. | customise the build. | ||||||
| @@ -92,25 +106,91 @@ To minimise the build time, only the tests at the root of the `tests` directory | |||||||
| ``` bash | ``` bash | ||||||
| make -C tests/<subdir> tests | 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 | ### Possible SIMD types | ||||||
|  |  | ||||||
| The following options can be use with the `--enable-simd=` option to target different SIMD instruction sets: | The following options can be use with the `--enable-simd=` option to target different SIMD instruction sets: | ||||||
|  |  | ||||||
| | String      | Description                            | | | `<code>`    | Description                            | | ||||||
| | ----------- | -------------------------------------- | | | ----------- | -------------------------------------- | | ||||||
| | `GEN`       | generic portable vector code           | | | `GEN`       | generic portable vector code           | | ||||||
| | `SSE4`      | SSE 4.2 (128 bit)                      | | | `SSE4`      | SSE 4.2 (128 bit)                      | | ||||||
| | `AVX`       | AVX (256 bit)                          | | | `AVX`       | AVX (256 bit)                          | | ||||||
| | `AVXFMA4`   | AVX (256 bit) + FMA                    | | | `AVXFMA`    | AVX (256 bit) + FMA                    | | ||||||
|  | | `AVXFMA4`   | AVX (256 bit) + FMA4                   | | ||||||
| | `AVX2`      | AVX 2 (256 bit)                        | | | `AVX2`      | AVX 2 (256 bit)                        | | ||||||
| | `AVX512`    | AVX 512 bit                            | | | `AVX512`    | AVX 512 bit                            | | ||||||
| | `AVX512MIC` | AVX 512 bit for Intel MIC architecture | | | `QPX`       | QPX (256 bit)                          | | ||||||
| | `ICMI`      | Intel ICMI instructions (512 bit)      | |  | ||||||
|  |  | ||||||
| Alternatively, some CPU codenames can be directly used: | Alternatively, some CPU codenames can be directly used: | ||||||
|  |  | ||||||
| | String      | Description                            | | | `<code>`    | Description                            | | ||||||
| | ----------- | -------------------------------------- | | | ----------- | -------------------------------------- | | ||||||
| | `KNC`       | [Intel Knights Corner](http://ark.intel.com/products/codename/57721/Knights-Corner) | | | `KNC`       | [Intel Xeon Phi codename Knights Corner](http://ark.intel.com/products/codename/57721/Knights-Corner) | | ||||||
| | `KNL`       | [Intel Knights Landing](http://ark.intel.com/products/codename/48999/Knights-Landing) | | | `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 | ||||||
|  | ``` | ||||||
							
								
								
									
										63
									
								
								TODO
									
									
									
									
									
								
							
							
						
						
									
										63
									
								
								TODO
									
									
									
									
									
								
							| @@ -1,6 +1,28 @@ | |||||||
| TODO: | TODO: | ||||||
| --------------- | --------------- | ||||||
|  |  | ||||||
|  | Peter's work list: | ||||||
|  |  | ||||||
|  | -- Remove DenseVector, DenseMatrix; Use Eigen instead. <-- started | ||||||
|  | -- Merge high precision reduction into develop         <-- done | ||||||
|  | -- Precision conversion and sort out localConvert      <--  | ||||||
|  | -- Physical propagator interface | ||||||
|  |  | ||||||
|  | -- multiRHS DWF; benchmark on Cori/BNL for comms elimination | ||||||
|  |    -- slice* linalg routines for multiRHS, BlockCG        <-- started | ||||||
|  |  | ||||||
|  | -- Profile CG, BlockCG, etc... Flop count/rate | ||||||
|  | -- Binary I/O speed up & x-strips | ||||||
|  | -- Half-precision comms                                <-- started | ||||||
|  | -- GaugeFix into central location | ||||||
|  | -- FFTfix in sensible place | ||||||
|  | -- Multigrid Wilson and DWF, compare to other Multigrid implementations | ||||||
|  | -- quaternions                 -- Might not need | ||||||
|  |  | ||||||
|  |  | ||||||
|  | -- Conserved currents | ||||||
|  |  | ||||||
|  | ----- | ||||||
| * Forces; the UdSdU  term in gauge force term is half of what I think it should | * Forces; the UdSdU  term in gauge force term is half of what I think it should | ||||||
|   be. This is a consequence of taking ONLY the first term in: |   be. This is a consequence of taking ONLY the first term in: | ||||||
|  |  | ||||||
| @@ -21,16 +43,8 @@ TODO: | |||||||
|   This means we must double the force in the Test_xxx_force routines, and is the origin of the factor of two. |   This means we must double the force in the Test_xxx_force routines, and is the origin of the factor of two. | ||||||
|   This 2x is applied by hand in the fermion routines and in the Test_rect_force routine. |   This 2x is applied by hand in the fermion routines and in the Test_rect_force routine. | ||||||
|  |  | ||||||
|  |  | ||||||
| Policies: |  | ||||||
|  |  | ||||||
| * Link smearing/boundary conds; Policy class based implementation ; framework more in place |  | ||||||
|  |  | ||||||
| * Support different boundary conditions (finite temp, chem. potential ... ) | * Support different boundary conditions (finite temp, chem. potential ... ) | ||||||
|  |  | ||||||
| * Support different fermion representations?  |  | ||||||
|   - contained entirely within the integrator presently |  | ||||||
|  |  | ||||||
| - Sign of force term. | - Sign of force term. | ||||||
|  |  | ||||||
| - Reversibility test. | - Reversibility test. | ||||||
| @@ -41,11 +55,6 @@ Policies: | |||||||
|  |  | ||||||
| - Audit oIndex usage for cb behaviour | - Audit oIndex usage for cb behaviour | ||||||
|  |  | ||||||
| - Rectangle gauge actions. |  | ||||||
|   Iwasaki, |  | ||||||
|   Symanzik, |  | ||||||
|   ... etc... |  | ||||||
|  |  | ||||||
| - Prepare multigrid for HMC. - Alternate setup schemes. | - Prepare multigrid for HMC. - Alternate setup schemes. | ||||||
|  |  | ||||||
| - Support for ILDG --- ugly, not done | - Support for ILDG --- ugly, not done | ||||||
| @@ -55,9 +64,11 @@ Policies: | |||||||
| - FFTnD ? | - FFTnD ? | ||||||
|  |  | ||||||
| - Gparity; hand opt use template specialisation elegance to enable the optimised paths ? | - Gparity; hand opt use template specialisation elegance to enable the optimised paths ? | ||||||
|  |  | ||||||
| - Gparity force term; Gparity (R)HMC. | - Gparity force term; Gparity (R)HMC. | ||||||
| - Random number state save restore |  | ||||||
| - Mobius implementation clean up to rmove #if 0 stale code sequences | - Mobius implementation clean up to rmove #if 0 stale code sequences | ||||||
|  |  | ||||||
| - CG -- profile carefully, kernel fusion, whole CG performance measurements. | - CG -- profile carefully, kernel fusion, whole CG performance measurements. | ||||||
|  |  | ||||||
| ================================================================ | ================================================================ | ||||||
| @@ -90,6 +101,7 @@ Insert/Extract | |||||||
| Not sure of status of this -- reverify. Things are working nicely now though. | Not sure of status of this -- reverify. Things are working nicely now though. | ||||||
|  |  | ||||||
| * Make the Tensor types and Complex etc... play more nicely. | * Make the Tensor types and Complex etc... play more nicely. | ||||||
|  |  | ||||||
|   - TensorRemove is a hack, come up with a long term rationalised approach to Complex vs. Scalar<Scalar<Scalar<Complex > > > |   - TensorRemove is a hack, come up with a long term rationalised approach to Complex vs. Scalar<Scalar<Scalar<Complex > > > | ||||||
|     QDP forces use of "toDouble" to get back to non tensor scalar. This role is presently taken TensorRemove, but I |     QDP forces use of "toDouble" to get back to non tensor scalar. This role is presently taken TensorRemove, but I | ||||||
|     want to introduce a syntax that does not require this. |     want to introduce a syntax that does not require this. | ||||||
| @@ -112,6 +124,8 @@ Not sure of status of this -- reverify. Things are working nicely now though. | |||||||
| RECENT | RECENT | ||||||
| --------------- | --------------- | ||||||
|  |  | ||||||
|  |   - Support different fermion representations? -- DONE | ||||||
|  |   - contained entirely within the integrator presently | ||||||
|   - Clean up HMC                                                             -- DONE |   - Clean up HMC                                                             -- DONE | ||||||
|   - LorentzScalar<GaugeField> gets Gauge link type (cleaner).                -- DONE |   - LorentzScalar<GaugeField> gets Gauge link type (cleaner).                -- DONE | ||||||
|   - Simplified the integrators a bit.                                        -- DONE |   - Simplified the integrators a bit.                                        -- DONE | ||||||
| @@ -123,6 +137,26 @@ RECENT | |||||||
|   - Parallel io improvements                                  -- DONE |   - Parallel io improvements                                  -- DONE | ||||||
|   - Plaquette and link trace checks into nersc reader from the Grid_nersc_io.cc test. -- DONE |   - Plaquette and link trace checks into nersc reader from the Grid_nersc_io.cc test. -- DONE | ||||||
|  |  | ||||||
|  |  | ||||||
|  | DONE: | ||||||
|  | - MultiArray -- MultiRHS done | ||||||
|  | - ConjugateGradientMultiShift -- DONE | ||||||
|  | - MCR                         -- DONE | ||||||
|  | - Remez -- Mike or Boost?     -- DONE | ||||||
|  | - Proto (ET)                  -- DONE | ||||||
|  | - uBlas                       -- DONE ; Eigen | ||||||
|  | - Potentially Useful Boost libraries -- DONE ; Eigen | ||||||
|  | - Aligned allocator; memory pool -- DONE | ||||||
|  | - Multiprecision              -- DONE | ||||||
|  | - Serialization               -- DONE | ||||||
|  | - Regex -- Not needed | ||||||
|  | - Tokenize -- Why? | ||||||
|  |  | ||||||
|  | - Random number state save restore -- DONE | ||||||
|  | - Rectangle gauge actions. -- DONE | ||||||
|  |   Iwasaki, | ||||||
|  |   Symanzik, | ||||||
|  |   ... etc... | ||||||
| Done: Cayley, Partial , ContFrac force terms. | Done: Cayley, Partial , ContFrac force terms. | ||||||
|  |  | ||||||
| DONE | DONE | ||||||
| @@ -207,6 +241,7 @@ Done | |||||||
| FUNCTIONALITY: it pleases me to keep track of things I have done (keeps me arguably sane) | FUNCTIONALITY: it pleases me to keep track of things I have done (keeps me arguably sane) | ||||||
| ====================================================================================================== | ====================================================================================================== | ||||||
|  |  | ||||||
|  | * Link smearing/boundary conds; Policy class based implementation ; framework more in place -- DONE | ||||||
| * Command line args for geometry, simd, etc. layout. Is it necessary to have -- DONE | * Command line args for geometry, simd, etc. layout. Is it necessary to have -- DONE | ||||||
|   user pass these? Is this a QCD specific? |   user pass these? Is this a QCD specific? | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										4
									
								
								VERSION
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								VERSION
									
									
									
									
									
								
							| @@ -1,4 +1,6 @@ | |||||||
| Version : 0.5.0 | Version : 0.6.0 | ||||||
|  |  | ||||||
| - AVX512, AVX2, AVX, SSE good | - AVX512, AVX2, AVX, SSE good | ||||||
| - Clang 3.5 and above, ICPC v16 and above, GCC 4.9 and above | - Clang 3.5 and above, ICPC v16 and above, GCC 4.9 and above | ||||||
|  | - MPI and MPI3 | ||||||
|  | - HiRep, Smearing, Generic gauge group | ||||||
|   | |||||||
| @@ -42,16 +42,15 @@ int main (int argc, char ** argv) | |||||||
|  |  | ||||||
|   int Nloop=10; |   int Nloop=10; | ||||||
|   int nmu=0; |   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 << "===================================================================================================="<<std::endl; | ||||||
|   std::cout<<GridLogMessage << "= Benchmarking concurrent halo exchange in "<<nmu<<" dimensions"<<std::endl; |   std::cout<<GridLogMessage << "= Benchmarking concurrent halo exchange in "<<nmu<<" dimensions"<<std::endl; | ||||||
|   std::cout<<GridLogMessage << "===================================================================================================="<<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; |   std::cout<<GridLogMessage << "  L  "<<"\t\t"<<" Ls  "<<"\t\t"<<"bytes"<<"\t\t"<<"MB/s uni"<<"\t\t"<<"MB/s bidi"<<std::endl; | ||||||
|  |   int maxlat=24; | ||||||
|  |   for(int lat=4;lat<=maxlat;lat+=4){ | ||||||
|  |     for(int Ls=8;Ls<=32;Ls*=2){ | ||||||
|   for(int lat=4;lat<=32;lat+=2){ |  | ||||||
|     for(int Ls=1;Ls<=16;Ls*=2){ |  | ||||||
|  |  | ||||||
|       std::vector<int> latt_size  ({lat*mpi_layout[0], |       std::vector<int> latt_size  ({lat*mpi_layout[0], | ||||||
|       				    lat*mpi_layout[1], |       				    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; |   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 lat=4;lat<=maxlat;lat+=4){ | ||||||
|     for(int Ls=1;Ls<=16;Ls*=2){ |     for(int Ls=8;Ls<=32;Ls*=2){ | ||||||
|  |  | ||||||
|       std::vector<int> latt_size  ({lat,lat,lat,lat}); |       std::vector<int> latt_size  ({lat,lat,lat,lat}); | ||||||
|  |  | ||||||
| @@ -194,128 +193,169 @@ int main (int argc, char ** argv) | |||||||
|     } |     } | ||||||
|   }   |   }   | ||||||
|  |  | ||||||
| #if 0 |  | ||||||
|  |  | ||||||
|  |   Nloop=10; | ||||||
|   std::cout<<GridLogMessage << "===================================================================================================="<<std::endl; |   std::cout<<GridLogMessage << "===================================================================================================="<<std::endl; | ||||||
|   std::cout<<GridLogMessage << "= Benchmarking sequential persistent halo exchange in "<<nmu<<" dimensions"<<std::endl; |   std::cout<<GridLogMessage << "= Benchmarking concurrent STENCIL halo exchange in "<<nmu<<" dimensions"<<std::endl; | ||||||
|   std::cout<<GridLogMessage << "===================================================================================================="<<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; |   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){ | ||||||
|  |  | ||||||
|   for(int lat=4;lat<=32;lat+=2){ |       std::vector<int> latt_size  ({lat*mpi_layout[0], | ||||||
|     for(int Ls=1;Ls<=16;Ls*=2){ |       				    lat*mpi_layout[1], | ||||||
|  |       				    lat*mpi_layout[2], | ||||||
|       std::vector<int> latt_size  ({lat,lat,lat,lat}); |       				    lat*mpi_layout[3]}); | ||||||
|  |  | ||||||
|       GridCartesian     Grid(latt_size,simd_layout,mpi_layout); |       GridCartesian     Grid(latt_size,simd_layout,mpi_layout); | ||||||
|  |  | ||||||
|       std::vector<std::vector<HalfSpinColourVectorD> > xbuf(8,std::vector<HalfSpinColourVectorD>(lat*lat*lat*Ls)); |       std::vector<HalfSpinColourVectorD *> xbuf(8); | ||||||
|       std::vector<std::vector<HalfSpinColourVectorD> > rbuf(8,std::vector<HalfSpinColourVectorD>(lat*lat*lat*Ls)); |       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 ncomm; | ||||||
|       int bytes=lat*lat*lat*Ls*sizeof(HalfSpinColourVectorD); |       int bytes=lat*lat*lat*Ls*sizeof(HalfSpinColourVectorD); | ||||||
|  |  | ||||||
|  |       double start=usecond(); | ||||||
|  |       for(int i=0;i<Nloop;i++){ | ||||||
|  |  | ||||||
|       std::vector<CartesianCommunicator::CommsRequest_t> empty; | 	std::vector<CartesianCommunicator::CommsRequest_t> requests; | ||||||
|       std::vector<std::vector<CartesianCommunicator::CommsRequest_t> > requests_fwd(Nd,empty); |  | ||||||
|       std::vector<std::vector<CartesianCommunicator::CommsRequest_t> > requests_bwd(Nd,empty); |  | ||||||
|  |  | ||||||
|       for(int mu=0;mu<4;mu++){ |  | ||||||
| 	ncomm=0; | 	ncomm=0; | ||||||
| 	if (mpi_layout[mu]>1 ) { | 	for(int mu=0;mu<4;mu++){ | ||||||
| 	  ncomm++; |  | ||||||
| 	 | 	 | ||||||
| 	  int comm_proc; | 	  if (mpi_layout[mu]>1 ) { | ||||||
| 	  int xmit_to_rank; |  | ||||||
| 	  int recv_from_rank; |  | ||||||
| 	   | 	   | ||||||
| 	  comm_proc=1; | 	    ncomm++; | ||||||
| 	  Grid.ShiftedRanks(mu,comm_proc,xmit_to_rank,recv_from_rank); | 	    int comm_proc=1; | ||||||
| 	  Grid.SendToRecvFromInit(requests_fwd[mu], | 	    int xmit_to_rank; | ||||||
| 				  (void *)&xbuf[mu][0], | 	    int recv_from_rank; | ||||||
| 				  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.ShiftedRanks(mu,comm_proc,xmit_to_rank,recv_from_rank); | 	    Grid.StencilSendToRecvFromBegin(requests, | ||||||
| 	  Grid.SendToRecvFromInit(requests_bwd[mu], | 					    (void *)&xbuf[mu][0], | ||||||
| 				  (void *)&xbuf[mu+4][0], | 					    xmit_to_rank, | ||||||
| 				  xmit_to_rank, | 					    (void *)&rbuf[mu][0], | ||||||
| 				  (void *)&rbuf[mu+4][0], | 					    recv_from_rank, | ||||||
| 				  recv_from_rank, | 					    bytes); | ||||||
| 				  bytes); |  | ||||||
| 	 | 	 | ||||||
| 	} | 	    comm_proc = mpi_layout[mu]-1; | ||||||
|       } |  | ||||||
| 	   | 	   | ||||||
|       { | 	    Grid.ShiftedRanks(mu,comm_proc,xmit_to_rank,recv_from_rank); | ||||||
| 	double start=usecond(); | 	    Grid.StencilSendToRecvFromBegin(requests, | ||||||
| 	for(int i=0;i<Nloop;i++){ | 					    (void *)&xbuf[mu+4][0], | ||||||
|  | 					    xmit_to_rank, | ||||||
|  | 					    (void *)&rbuf[mu+4][0], | ||||||
|  | 					    recv_from_rank, | ||||||
|  | 					    bytes); | ||||||
| 	   | 	   | ||||||
| 	  for(int mu=0;mu<4;mu++){ |  | ||||||
| 	     |  | ||||||
| 	    if (mpi_layout[mu]>1 ) { |  | ||||||
| 	       |  | ||||||
| 	      Grid.SendToRecvFromBegin(requests_fwd[mu]); |  | ||||||
| 	      Grid.SendToRecvFromComplete(requests_fwd[mu]); |  | ||||||
| 	      Grid.SendToRecvFromBegin(requests_bwd[mu]); |  | ||||||
| 	      Grid.SendToRecvFromComplete(requests_bwd[mu]); |  | ||||||
| 	    } |  | ||||||
| 	  } | 	  } | ||||||
| 	  Grid.Barrier(); |  | ||||||
| 	} | 	} | ||||||
| 	 | 	Grid.StencilSendToRecvFromComplete(requests); | ||||||
| 	double stop=usecond(); | 	Grid.Barrier(); | ||||||
| 	 |  | ||||||
| 	double dbytes    = bytes; |  | ||||||
| 	double xbytes    = Nloop*dbytes*2.0*ncomm; |  | ||||||
| 	double rbytes    = xbytes; |  | ||||||
| 	double bidibytes = xbytes+rbytes; |  | ||||||
| 	 |  | ||||||
| 	double time = stop-start; |  | ||||||
| 	 |  | ||||||
| 	std::cout<<GridLogMessage << lat<<"\t\t"<<Ls<<"\t\t"<<bytes<<"\t\t"<<xbytes/time<<"\t\t"<<bidibytes/time<<std::endl; |  | ||||||
|  |  | ||||||
|       } |       } | ||||||
|  |       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 | ||||||
| 	double start=usecond(); |  | ||||||
| 	for(int i=0;i<Nloop;i++){ |  | ||||||
| 	   |  | ||||||
| 	  for(int mu=0;mu<4;mu++){ |  | ||||||
| 	     |  | ||||||
| 	    if (mpi_layout[mu]>1 ) { |  | ||||||
| 	       |  | ||||||
| 	      Grid.SendToRecvFromBegin(requests_fwd[mu]); |  | ||||||
| 	      Grid.SendToRecvFromBegin(requests_bwd[mu]); |  | ||||||
| 	      Grid.SendToRecvFromComplete(requests_fwd[mu]); |  | ||||||
| 	      Grid.SendToRecvFromComplete(requests_bwd[mu]); |  | ||||||
| 	    } |  | ||||||
| 	  } |  | ||||||
| 	  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; |  | ||||||
| 	 |  | ||||||
| 	std::cout<<GridLogMessage << lat<<"\t\t"<<Ls<<"\t\t"<<bytes<<"\t\t"<<xbytes/time<<"\t\t"<<bidibytes/time<<std::endl; |  | ||||||
|  |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|  |       std::cout<<GridLogMessage << lat<<"\t\t"<<Ls<<"\t\t"<<bytes<<"\t\t"<<xbytes/time<<"\t\t"<<bidibytes/time<<std::endl; | ||||||
|     } |     } | ||||||
|   }     |   }     | ||||||
|  |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
|  |   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(); |   Grid_finalize(); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -37,26 +37,21 @@ struct scal { | |||||||
|   d internal; |   d internal; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   Gamma::GammaMatrix Gmu [] = { |   Gamma::Algebra Gmu [] = { | ||||||
|     Gamma::GammaX, |     Gamma::Algebra::GammaX, | ||||||
|     Gamma::GammaY, |     Gamma::Algebra::GammaY, | ||||||
|     Gamma::GammaZ, |     Gamma::Algebra::GammaZ, | ||||||
|     Gamma::GammaT |     Gamma::Algebra::GammaT | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
| bool overlapComms = false; |  | ||||||
| typedef WilsonFermion5D<DomainWallVec5dImplR> WilsonFermion5DR; | typedef WilsonFermion5D<DomainWallVec5dImplR> WilsonFermion5DR; | ||||||
| typedef WilsonFermion5D<DomainWallVec5dImplF> WilsonFermion5DF; | typedef WilsonFermion5D<DomainWallVec5dImplF> WilsonFermion5DF; | ||||||
| typedef WilsonFermion5D<DomainWallVec5dImplD> WilsonFermion5DD; | typedef WilsonFermion5D<DomainWallVec5dImplD> WilsonFermion5DD; | ||||||
|  |  | ||||||
|  |  | ||||||
| int main (int argc, char ** argv) | int main (int argc, char ** argv) | ||||||
| { | { | ||||||
|   Grid_init(&argc,&argv); |   Grid_init(&argc,&argv); | ||||||
|  |  | ||||||
|   if( GridCmdOptionExists(argv,argv+argc,"--asynch") ){ |  | ||||||
|     overlapComms = true; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   int threads = GridThread::GetThreads(); |   int threads = GridThread::GetThreads(); | ||||||
|   std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl; |   std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl; | ||||||
| @@ -77,34 +72,65 @@ int main (int argc, char ** argv) | |||||||
|   std::vector<int> seeds4({1,2,3,4}); |   std::vector<int> seeds4({1,2,3,4}); | ||||||
|   std::vector<int> seeds5({5,6,7,8}); |   std::vector<int> seeds5({5,6,7,8}); | ||||||
|    |    | ||||||
|  |   std::cout << GridLogMessage << "Initialising 4d RNG" << std::endl; | ||||||
|   GridParallelRNG          RNG4(UGrid);  RNG4.SeedFixedIntegers(seeds4); |   GridParallelRNG          RNG4(UGrid);  RNG4.SeedFixedIntegers(seeds4); | ||||||
|  |   std::cout << GridLogMessage << "Initialising 5d RNG" << std::endl; | ||||||
|   GridParallelRNG          RNG5(FGrid);  RNG5.SeedFixedIntegers(seeds5); |   GridParallelRNG          RNG5(FGrid);  RNG5.SeedFixedIntegers(seeds5); | ||||||
|  |   std::cout << GridLogMessage << "Initialised RNGs" << std::endl; | ||||||
|  |  | ||||||
|   LatticeFermion src   (FGrid); random(RNG5,src); |   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 result(FGrid); result=zero; | ||||||
|   LatticeFermion    ref(FGrid);    ref=zero; |   LatticeFermion    ref(FGrid);    ref=zero; | ||||||
|   LatticeFermion    tmp(FGrid); |   LatticeFermion    tmp(FGrid); | ||||||
|   LatticeFermion    err(FGrid); |   LatticeFermion    err(FGrid); | ||||||
|  |  | ||||||
|  |   std::cout << GridLogMessage << "Drawing gauge field" << std::endl; | ||||||
|   LatticeGaugeField Umu(UGrid);  |   LatticeGaugeField Umu(UGrid);  | ||||||
|   random(RNG4,Umu); |   SU3::HotConfiguration(RNG4,Umu);  | ||||||
|  |   std::cout << GridLogMessage << "Random gauge initialised " << std::endl; | ||||||
|   LatticeGaugeField Umu5d(FGrid);  | #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 |   // replicate across fifth dimension | ||||||
|  |   LatticeGaugeField Umu5d(FGrid);  | ||||||
|  |   std::vector<LatticeColourMatrix> U(4,FGrid); | ||||||
|   for(int ss=0;ss<Umu._grid->oSites();ss++){ |   for(int ss=0;ss<Umu._grid->oSites();ss++){ | ||||||
|     for(int s=0;s<Ls;s++){ |     for(int s=0;s<Ls;s++){ | ||||||
|       Umu5d._odata[Ls*ss+s] = Umu._odata[ss]; |       Umu5d._odata[Ls*ss+s] = Umu._odata[ss]; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   //////////////////////////////////// |  | ||||||
|   // Naive wilson implementation |  | ||||||
|   //////////////////////////////////// |  | ||||||
|   std::vector<LatticeColourMatrix> U(4,FGrid); |  | ||||||
|   for(int mu=0;mu<Nd;mu++){ |   for(int mu=0;mu<Nd;mu++){ | ||||||
|     U[mu] = PeekIndex<LorentzIndex>(Umu5d,mu); |     U[mu] = PeekIndex<LorentzIndex>(Umu5d,mu); | ||||||
|   } |   } | ||||||
|  |   std::cout << GridLogMessage << "Setting up Cshift based reference " << std::endl; | ||||||
|  |  | ||||||
|   if (1) |   if (1) | ||||||
|   { |   { | ||||||
| @@ -126,18 +152,27 @@ int main (int argc, char ** argv) | |||||||
|  |  | ||||||
|   RealD NP = UGrid->_Nprocessors; |   RealD NP = UGrid->_Nprocessors; | ||||||
|  |  | ||||||
|   for(int doasm=1;doasm<2;doasm++){ |   std::cout << GridLogMessage << "Creating action operator " << std::endl; | ||||||
|  |  | ||||||
|     QCD::WilsonKernelsStatic::AsmOpt=doasm; |  | ||||||
|  |  | ||||||
|   DomainWallFermionR Dw(Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5); |   DomainWallFermionR Dw(Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5); | ||||||
|  |  | ||||||
|   std::cout<<GridLogMessage << "Naive wilson implementation "<<std::endl; |   std::cout << GridLogMessage<< "*****************************************************************" <<std::endl; | ||||||
|   std::cout << GridLogMessage<< "Calling Dw"<<std::endl; |   std::cout << GridLogMessage<< "* Kernel options --dslash-generic, --dslash-unroll, --dslash-asm" <<std::endl; | ||||||
|   int ncall =100; |   std::cout << GridLogMessage<< "*****************************************************************" <<std::endl; | ||||||
|   if (1) { |   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.ZeroCounters(); | ||||||
|  |     Dw.Dhop(src,result,0); | ||||||
|     double t0=usecond(); |     double t0=usecond(); | ||||||
|     for(int i=0;i<ncall;i++){ |     for(int i=0;i<ncall;i++){ | ||||||
|       __SSC_START; |       __SSC_START; | ||||||
| @@ -145,23 +180,45 @@ int main (int argc, char ** argv) | |||||||
|       __SSC_STOP; |       __SSC_STOP; | ||||||
|     } |     } | ||||||
|     double t1=usecond(); |     double t1=usecond(); | ||||||
|  |     FGrid->Barrier(); | ||||||
|      |      | ||||||
|     double volume=Ls;  for(int mu=0;mu<Nd;mu++) volume=volume*latt4[mu]; |     double volume=Ls;  for(int mu=0;mu<Nd;mu++) volume=volume*latt4[mu]; | ||||||
|     double flops=1344*volume*ncall; |     double flops=1344*volume*ncall; | ||||||
|  |  | ||||||
|     std::cout<<GridLogMessage << "Called Dw "<<ncall<<" times in "<<t1-t0<<" us"<<std::endl; |     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 result "<< norm2(result)<<std::endl; | ||||||
|     std::cout<<GridLogMessage << "norm ref    "<< norm2(ref)<<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 =   "<< flops/(t1-t0)<<std::endl; | ||||||
|     std::cout<<GridLogMessage << "mflop/s per rank =  "<< flops/(t1-t0)/NP<<std::endl; |     std::cout<<GridLogMessage << "mflop/s per rank =  "<< flops/(t1-t0)/NP<<std::endl; | ||||||
|     err = ref-result;  |     err = ref-result;  | ||||||
|     std::cout<<GridLogMessage << "norm diff   "<< norm2(err)<<std::endl; |     std::cout<<GridLogMessage << "norm diff   "<< norm2(err)<<std::endl; | ||||||
|     assert (norm2(err)< 1.0e-5 ); |  | ||||||
|  |     /* | ||||||
|  |     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(); |     Dw.Report(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   if (1) |   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; |     typedef WilsonFermion5D<DomainWallVec5dImplR> WilsonFermion5DR; | ||||||
|     LatticeFermion ssrc(sFGrid); |     LatticeFermion ssrc(sFGrid); | ||||||
|     LatticeFermion sref(sFGrid); |     LatticeFermion sref(sFGrid); | ||||||
| @@ -169,71 +226,66 @@ int main (int argc, char ** argv) | |||||||
|  |  | ||||||
|     WilsonFermion5DR sDw(Umu,*sFGrid,*sFrbGrid,*sUGrid,*sUrbGrid,M5); |     WilsonFermion5DR sDw(Umu,*sFGrid,*sFrbGrid,*sUGrid,*sUrbGrid,M5); | ||||||
|  |  | ||||||
|     for(int x=0;x<latt4[0];x++){ |     localConvert(src,ssrc); | ||||||
|     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); |  | ||||||
|     }}}}} |  | ||||||
|     std::cout<<GridLogMessage<< "src norms "<< norm2(src)<<" " <<norm2(ssrc)<<std::endl; |     std::cout<<GridLogMessage<< "src norms "<< norm2(src)<<" " <<norm2(ssrc)<<std::endl; | ||||||
|     double t0=usecond(); |     FGrid->Barrier(); | ||||||
|  |     sDw.Dhop(ssrc,sresult,0); | ||||||
|     sDw.ZeroCounters(); |     sDw.ZeroCounters(); | ||||||
|  |     double t0=usecond(); | ||||||
|     for(int i=0;i<ncall;i++){ |     for(int i=0;i<ncall;i++){ | ||||||
|       __SSC_START; |       __SSC_START; | ||||||
|       sDw.Dhop(ssrc,sresult,0); |       sDw.Dhop(ssrc,sresult,0); | ||||||
|       __SSC_STOP; |       __SSC_STOP; | ||||||
|     } |     } | ||||||
|     double t1=usecond(); |     double t1=usecond(); | ||||||
|  |     FGrid->Barrier(); | ||||||
|     double volume=Ls;  for(int mu=0;mu<Nd;mu++) volume=volume*latt4[mu]; |     double volume=Ls;  for(int mu=0;mu<Nd;mu++) volume=volume*latt4[mu]; | ||||||
|     double flops=1344*volume*ncall; |     double flops=1344*volume*ncall; | ||||||
|  |  | ||||||
|     std::cout<<GridLogMessage << "Called Dw s_inner "<<ncall<<" times in "<<t1-t0<<" us"<<std::endl; |     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 =   "<< flops/(t1-t0)<<std::endl; | ||||||
|     std::cout<<GridLogMessage << "mflop/s per rank =  "<< flops/(t1-t0)/NP<<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(); |     sDw.Report(); | ||||||
|    |  | ||||||
|     if(0){ |  | ||||||
|       for(int i=0;i< PerformanceCounter::NumTypes(); i++ ){ |  | ||||||
|   sDw.Dhop(ssrc,sresult,0); |  | ||||||
|   PerformanceCounter Counter(i); |  | ||||||
|   Counter.Start(); |  | ||||||
|   sDw.Dhop(ssrc,sresult,0); |  | ||||||
|   Counter.Stop(); |  | ||||||
|   Counter.Report(); |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     std::cout<<GridLogMessage<< "res norms "<< norm2(result)<<" " <<norm2(sresult)<<std::endl; |  | ||||||
|  |  | ||||||
|     RealD sum=0; |     RealD sum=0; | ||||||
|     for(int x=0;x<latt4[0];x++){ |  | ||||||
|     for(int y=0;y<latt4[1];y++){ |  | ||||||
|     for(int z=0;z<latt4[2];z++){ |  | ||||||
|     for(int t=0;t<latt4[3];t++){ |  | ||||||
|     for(int s=0;s<Ls;s++){ |  | ||||||
|       std::vector<int> site({s,x,y,z,t}); |  | ||||||
|       SpinColourVector normal, simd; |  | ||||||
|       peekSite(normal,result,site); |  | ||||||
|       peekSite(simd,sresult,site); |  | ||||||
|       sum=sum+norm2(normal-simd); |  | ||||||
|       if (norm2(normal-simd) > 1.0e-6 ) { |  | ||||||
| 	std::cout << "site "<<x<<","<<y<<","<<z<<","<<t<<","<<s<<" "<<norm2(normal-simd)<<std::endl; |  | ||||||
| 	std::cout << "site "<<x<<","<<y<<","<<z<<","<<t<<","<<s<<" normal "<<normal<<std::endl; |  | ||||||
| 	std::cout << "site "<<x<<","<<y<<","<<z<<","<<t<<","<<s<<" simd   "<<simd<<std::endl; |  | ||||||
|       } |  | ||||||
|     }}}}} |  | ||||||
|     std::cout<<GridLogMessage<<" difference between normal and simd is "<<sum<<std::endl; |  | ||||||
|     assert (sum< 1.0e-5 ); |  | ||||||
|  |  | ||||||
|  |     err=zero; | ||||||
|  |     localConvert(sresult,err); | ||||||
|  |     err = err - ref; | ||||||
|  |     sum = norm2(err); | ||||||
|  |     std::cout<<GridLogMessage<<" difference between normal ref and simd is "<<sum<<std::endl; | ||||||
|  |     if(sum > 1.0e-4 ){ | ||||||
|  |       std::cout<< "sD REF\n " <<ref << std::endl; | ||||||
|  |       std::cout<< "sD ERR   \n " <<err  <<std::endl; | ||||||
|  |     } | ||||||
|  |     //    assert(sum < 1.0e-4); | ||||||
|  |  | ||||||
|     if (1) { |     err=zero; | ||||||
|  |     localConvert(sresult,err); | ||||||
|  |     err = err - result; | ||||||
|  |     sum = norm2(err); | ||||||
|  |     std::cout<<GridLogMessage<<" difference between normal result and simd is "<<sum<<std::endl; | ||||||
|  |     if(sum > 1.0e-4 ){ | ||||||
|  |       std::cout<< "sD REF\n " <<result << std::endl; | ||||||
|  |       std::cout<< "sD ERR   \n " << err  <<std::endl; | ||||||
|  |     } | ||||||
|  |     assert(sum < 1.0e-4); | ||||||
|  |      | ||||||
|  |     if(1){ | ||||||
|  |       std::cout << GridLogMessage<< "*********************************************************" <<std::endl; | ||||||
|  |       std::cout << GridLogMessage<< "* Benchmarking WilsonFermion5D<DomainWallVec5dImplR>::DhopEO "<<std::endl; | ||||||
|  |       std::cout << GridLogMessage<< "* Vectorising fifth dimension by "<<vComplex::Nsimd()<<std::endl; | ||||||
|  |       if ( sizeof(Real)==4 )   std::cout << GridLogMessage<< "* SINGLE precision "<<std::endl; | ||||||
|  |       if ( sizeof(Real)==8 )   std::cout << GridLogMessage<< "* DOUBLE precision "<<std::endl; | ||||||
|  |       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 sr_eo(sFGrid); | ||||||
|  |  | ||||||
|       LatticeFermion ssrc_e (sFrbGrid); |       LatticeFermion ssrc_e (sFrbGrid); | ||||||
|       LatticeFermion ssrc_o (sFrbGrid); |       LatticeFermion ssrc_o (sFrbGrid); | ||||||
|       LatticeFermion sr_e   (sFrbGrid); |       LatticeFermion sr_e   (sFrbGrid); | ||||||
| @@ -241,21 +293,23 @@ int main (int argc, char ** argv) | |||||||
|  |  | ||||||
|       pickCheckerboard(Even,ssrc_e,ssrc); |       pickCheckerboard(Even,ssrc_e,ssrc); | ||||||
|       pickCheckerboard(Odd,ssrc_o,ssrc); |       pickCheckerboard(Odd,ssrc_o,ssrc); | ||||||
|  |       //      setCheckerboard(sr_eo,ssrc_o); | ||||||
|       setCheckerboard(sr_eo,ssrc_o); |       //      setCheckerboard(sr_eo,ssrc_e); | ||||||
|       setCheckerboard(sr_eo,ssrc_e); |  | ||||||
|  |  | ||||||
|       sr_e = zero; |       sr_e = zero; | ||||||
|       sr_o = zero; |       sr_o = zero; | ||||||
|  |  | ||||||
|  |       FGrid->Barrier(); | ||||||
|  |       sDw.DhopEO(ssrc_o, sr_e, DaggerNo); | ||||||
|       sDw.ZeroCounters(); |       sDw.ZeroCounters(); | ||||||
|       sDw.stat.init("DhopEO"); |       //      sDw.stat.init("DhopEO"); | ||||||
|       double t0=usecond(); |       double t0=usecond(); | ||||||
|       for (int i = 0; i < ncall; i++) { |       for (int i = 0; i < ncall; i++) { | ||||||
|         sDw.DhopEO(ssrc_o, sr_e, DaggerNo); |         sDw.DhopEO(ssrc_o, sr_e, DaggerNo); | ||||||
|       } |       } | ||||||
|       double t1=usecond(); |       double t1=usecond(); | ||||||
|       sDw.stat.print(); |       FGrid->Barrier(); | ||||||
|  |       //      sDw.stat.print(); | ||||||
|  |  | ||||||
|       double volume=Ls;  for(int mu=0;mu<Nd;mu++) volume=volume*latt4[mu]; |       double volume=Ls;  for(int mu=0;mu<Nd;mu++) volume=volume*latt4[mu]; | ||||||
|       double flops=(1344.0*volume*ncall)/2; |       double flops=(1344.0*volume*ncall)/2; | ||||||
| @@ -270,22 +324,26 @@ int main (int argc, char ** argv) | |||||||
|  |  | ||||||
|       pickCheckerboard(Even,ssrc_e,sresult); |       pickCheckerboard(Even,ssrc_e,sresult); | ||||||
|       pickCheckerboard(Odd ,ssrc_o,sresult); |       pickCheckerboard(Odd ,ssrc_o,sresult); | ||||||
|  |  | ||||||
|       ssrc_e = ssrc_e - sr_e; |       ssrc_e = ssrc_e - sr_e; | ||||||
|       RealD error = norm2(ssrc_e); |       RealD error = norm2(ssrc_e); | ||||||
|  |  | ||||||
|       std::cout<<GridLogMessage << "sE norm diff   "<< norm2(ssrc_e)<< "  vec nrm"<<norm2(sr_e) <<std::endl; |       std::cout<<GridLogMessage << "sE norm diff   "<< norm2(ssrc_e)<< "  vec nrm"<<norm2(sr_e) <<std::endl; | ||||||
|       ssrc_o = ssrc_o - sr_o; |  | ||||||
|  |  | ||||||
|  |       ssrc_o = ssrc_o - sr_o; | ||||||
|       error+= norm2(ssrc_o); |       error+= norm2(ssrc_o); | ||||||
|       std::cout<<GridLogMessage << "sO norm diff   "<< norm2(ssrc_o)<< "  vec nrm"<<norm2(sr_o) <<std::endl; |       std::cout<<GridLogMessage << "sO norm diff   "<< norm2(ssrc_o)<< "  vec nrm"<<norm2(sr_o) <<std::endl; | ||||||
|       if(error>1.0e-5) {  |  | ||||||
|  |       if(( error>1.0e-4) ) {  | ||||||
| 	setCheckerboard(ssrc,ssrc_o); | 	setCheckerboard(ssrc,ssrc_o); | ||||||
| 	setCheckerboard(ssrc,ssrc_e); | 	setCheckerboard(ssrc,ssrc_e); | ||||||
| 	std::cout<< ssrc << std::endl; | 	std::cout<< "DIFF\n " <<ssrc << std::endl; | ||||||
|  | 	setCheckerboard(ssrc,sr_o); | ||||||
|  | 	setCheckerboard(ssrc,sr_e); | ||||||
|  | 	std::cout<< "CBRESULT\n " <<ssrc << std::endl; | ||||||
|  | 	std::cout<< "RESULT\n " <<sresult<< std::endl; | ||||||
|       } |       } | ||||||
|  |       assert(error<1.0e-4); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   if (1) |   if (1) | ||||||
| @@ -293,28 +351,33 @@ int main (int argc, char ** argv) | |||||||
|     ref = zero; |     ref = zero; | ||||||
|     for(int mu=0;mu<Nd;mu++){ |     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); |       tmp = U[mu]*Cshift(src,mu+1,1); | ||||||
|       for(int i=0;i<ref._odata.size();i++){ |       for(int i=0;i<ref._odata.size();i++){ | ||||||
|   ref._odata[i]+= tmp._odata[i] + Gamma(Gmu[mu])*tmp._odata[i]; ; | 	ref._odata[i]+= tmp._odata[i] + Gamma(Gmu[mu])*tmp._odata[i]; ; | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       tmp =adj(U[mu])*src; |       tmp =adj(U[mu])*src; | ||||||
|       tmp =Cshift(tmp,mu+1,-1); |       tmp =Cshift(tmp,mu+1,-1); | ||||||
|       for(int i=0;i<ref._odata.size();i++){ |       for(int i=0;i<ref._odata.size();i++){ | ||||||
|   ref._odata[i]+= tmp._odata[i] - Gamma(Gmu[mu])*tmp._odata[i]; ; | 	ref._odata[i]+= tmp._odata[i] - Gamma(Gmu[mu])*tmp._odata[i]; ; | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|     ref = -0.5*ref; |     ref = -0.5*ref; | ||||||
|   } |   } | ||||||
|  |   //  dump=1; | ||||||
|   Dw.Dhop(src,result,1); |   Dw.Dhop(src,result,1); | ||||||
|   std::cout << GridLogMessage << "Naive wilson implementation Dag" << std::endl; |   std::cout << GridLogMessage << "Compare to naive wilson implementation Dag to verify correctness" << std::endl; | ||||||
|   std::cout<<GridLogMessage << "Called DwDag"<<std::endl; |   std::cout<<GridLogMessage << "Called DwDag"<<std::endl; | ||||||
|   std::cout<<GridLogMessage << "norm result "<< norm2(result)<<std::endl; |   std::cout<<GridLogMessage << "norm dag result "<< norm2(result)<<std::endl; | ||||||
|   std::cout<<GridLogMessage << "norm ref    "<< norm2(ref)<<std::endl; |   std::cout<<GridLogMessage << "norm dag ref    "<< norm2(ref)<<std::endl; | ||||||
|   err = ref-result;  |   err = ref-result;  | ||||||
|   std::cout<<GridLogMessage << "norm diff   "<< norm2(err)<<std::endl; |   std::cout<<GridLogMessage << "norm dag diff   "<< norm2(err)<<std::endl; | ||||||
|   assert(norm2(err)<1.0e-5); |   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_e (FrbGrid); | ||||||
|   LatticeFermion src_o (FrbGrid); |   LatticeFermion src_o (FrbGrid); | ||||||
|   LatticeFermion r_e   (FrbGrid); |   LatticeFermion r_e   (FrbGrid); | ||||||
| @@ -322,20 +385,37 @@ int main (int argc, char ** argv) | |||||||
|   LatticeFermion r_eo  (FGrid); |   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(Even,src_e,src); | ||||||
|   pickCheckerboard(Odd,src_o,src); |   pickCheckerboard(Odd,src_o,src); | ||||||
|  |  | ||||||
|   std::cout<<GridLogMessage << "src_e"<<norm2(src_e)<<std::endl; |   std::cout<<GridLogMessage << "src_e"<<norm2(src_e)<<std::endl; | ||||||
|   std::cout<<GridLogMessage << "src_o"<<norm2(src_o)<<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(); |     Dw.ZeroCounters(); | ||||||
|  |     FGrid->Barrier(); | ||||||
|  |     Dw.DhopEO(src_o,r_e,DaggerNo); | ||||||
|     double t0=usecond(); |     double t0=usecond(); | ||||||
|     for(int i=0;i<ncall;i++){ |     for(int i=0;i<ncall;i++){ | ||||||
|       Dw.DhopEO(src_o,r_e,DaggerNo); |       Dw.DhopEO(src_o,r_e,DaggerNo); | ||||||
|     } |     } | ||||||
|     double t1=usecond(); |     double t1=usecond(); | ||||||
|  |     FGrid->Barrier(); | ||||||
|      |      | ||||||
|     double volume=Ls;  for(int mu=0;mu<Nd;mu++) volume=volume*latt4[mu]; |     double volume=Ls;  for(int mu=0;mu<Nd;mu++) volume=volume*latt4[mu]; | ||||||
|     double flops=(1344.0*volume*ncall)/2; |     double flops=(1344.0*volume*ncall)/2; | ||||||
| @@ -357,17 +437,19 @@ int main (int argc, char ** argv) | |||||||
|  |  | ||||||
|   err = r_eo-result;  |   err = r_eo-result;  | ||||||
|   std::cout<<GridLogMessage << "norm diff   "<< norm2(err)<<std::endl; |   std::cout<<GridLogMessage << "norm diff   "<< norm2(err)<<std::endl; | ||||||
|   assert(norm2(err)<1.0e-5); |   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(Even,src_e,err); | ||||||
|   pickCheckerboard(Odd,src_o,err); |   pickCheckerboard(Odd,src_o,err); | ||||||
|   std::cout<<GridLogMessage << "norm diff even  "<< norm2(src_e)<<std::endl; |   std::cout<<GridLogMessage << "norm diff even  "<< norm2(src_e)<<std::endl; | ||||||
|   std::cout<<GridLogMessage << "norm diff odd   "<< norm2(src_o)<<std::endl; |   std::cout<<GridLogMessage << "norm diff odd   "<< norm2(src_o)<<std::endl; | ||||||
|   assert(norm2(src_e)<1.0e-5); |  | ||||||
|   assert(norm2(src_o)<1.0e-5); |  | ||||||
|  |  | ||||||
|  |   //assert(norm2(src_e)<1.0e-4); | ||||||
|   } |   //assert(norm2(src_o)<1.0e-4); | ||||||
|  |  | ||||||
|   Grid_finalize(); |   Grid_finalize(); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,153 +0,0 @@ | |||||||
|     /************************************************************************************* |  | ||||||
|  |  | ||||||
|     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::GammaMatrix Gmu [] = { |  | ||||||
|     Gamma::GammaX, |  | ||||||
|     Gamma::GammaY, |  | ||||||
|     Gamma::GammaZ, |  | ||||||
|     Gamma::GammaT |  | ||||||
|   }; |  | ||||||
|  |  | ||||||
| bool overlapComms = false; |  | ||||||
|  |  | ||||||
|  |  | ||||||
| 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=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::vector<int> seeds4({1,2,3,4}); |  | ||||||
|   std::vector<int> seeds5({5,6,7,8}); |  | ||||||
|  |  | ||||||
|   GridParallelRNG          RNG4(UGrid);  RNG4.SeedFixedIntegers(seeds4); |  | ||||||
|   GridParallelRNG          RNG5(FGrid);  RNG5.SeedFixedIntegers(seeds5); |  | ||||||
|  |  | ||||||
|   LatticeFermion src   (FGrid); random(RNG5,src); |  | ||||||
|   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);  |  | ||||||
|  |  | ||||||
|   // 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); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   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; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   RealD mass=0.1; |  | ||||||
|   RealD M5  =1.8; |  | ||||||
|  |  | ||||||
|   typename DomainWallFermionR::ImplParams params;  |  | ||||||
|   params.overlapCommsCompute = overlapComms; |  | ||||||
|    |  | ||||||
|   RealD NP = UGrid->_Nprocessors; |  | ||||||
|  |  | ||||||
|  |  | ||||||
|   QCD::WilsonKernelsStatic::AsmOpt=1; |  | ||||||
|  |  | ||||||
|   DomainWallFermionR Dw(Umu,*FGrid,*FrbGrid,*UGrid,*UrbGrid,mass,M5,params); |  | ||||||
|    |  | ||||||
|   std::cout<<GridLogMessage << "Calling Dw"<<std::endl; |  | ||||||
|   int ncall =50; |  | ||||||
|   if (1) { |  | ||||||
|  |  | ||||||
|     double t0=usecond(); |  | ||||||
|     for(int i=0;i<ncall;i++){ |  | ||||||
|       Dw.Dhop(src,result,0); |  | ||||||
|     } |  | ||||||
|     double t1=usecond(); |  | ||||||
|      |  | ||||||
|     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 << "mflop/s =   "<< flops/(t1-t0)<<std::endl; |  | ||||||
|     std::cout<<GridLogMessage << "mflop/s per node =  "<< flops/(t1-t0)/NP<<std::endl; |  | ||||||
|     err = ref-result;  |  | ||||||
|     std::cout<<GridLogMessage << "norm diff   "<< norm2(err)<<std::endl; |  | ||||||
|     //    Dw.Report(); |  | ||||||
|   } |  | ||||||
|   Grid_finalize(); |  | ||||||
| } |  | ||||||
| @@ -37,11 +37,11 @@ struct scal { | |||||||
|   d internal; |   d internal; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   Gamma::GammaMatrix Gmu [] = { |   Gamma::Algebra Gmu [] = { | ||||||
|     Gamma::GammaX, |     Gamma::Algebra::GammaX, | ||||||
|     Gamma::GammaY, |     Gamma::Algebra::GammaY, | ||||||
|     Gamma::GammaZ, |     Gamma::Algebra::GammaZ, | ||||||
|     Gamma::GammaT |     Gamma::Algebra::GammaT | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
| void benchDw(std::vector<int> & L, int Ls, int threads, int report =0 ); | void benchDw(std::vector<int> & L, int Ls, int threads, int report =0 ); | ||||||
| @@ -51,24 +51,26 @@ int main (int argc, char ** argv) | |||||||
| { | { | ||||||
|   Grid_init(&argc,&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; |   const int Ls=8; | ||||||
|   int threads = GridThread::GetThreads(); |   int threads = GridThread::GetThreads(); | ||||||
|   std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl; |   std::cout<<GridLogMessage << "Grid is setup to use "<<threads<<" threads"<<std::endl; | ||||||
|  |  | ||||||
|   if ( getenv("ASMOPT") )  { |  | ||||||
|     QCD::WilsonKernelsStatic::AsmOpt=1; |  | ||||||
|   } else {  |  | ||||||
|     QCD::WilsonKernelsStatic::AsmOpt=0; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   std::cout<<GridLogMessage << "=========================================================================="<<std::endl; |   std::cout<<GridLogMessage << "=========================================================================="<<std::endl; | ||||||
|   std::cout<<GridLogMessage << "= Benchmarking DWF"<<std::endl; |   std::cout<<GridLogMessage << "= Benchmarking DWF"<<std::endl; | ||||||
|   std::cout<<GridLogMessage << "=========================================================================="<<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 << "Volume \t\t\tProcs \t Dw \t eoDw \t sDw \t eosDw (Mflop/s)  "<<std::endl; | ||||||
|   std::cout<<GridLogMessage << "=========================================================================="<<std::endl; |   std::cout<<GridLogMessage << "=========================================================================="<<std::endl; | ||||||
|  |  | ||||||
|   int Lmax=32; |   int Lmax=16; | ||||||
|   int dmin=0; |   int dmin=2; | ||||||
|   if ( getenv("LMAX") ) Lmax=atoi(getenv("LMAX")); |   if ( getenv("LMAX") ) Lmax=atoi(getenv("LMAX")); | ||||||
|   if ( getenv("DMIN") ) dmin=atoi(getenv("DMIN")); |   if ( getenv("DMIN") ) dmin=atoi(getenv("DMIN")); | ||||||
|   for (int L=8;L<=Lmax;L*=2){ |   for (int L=8;L<=Lmax;L*=2){ | ||||||
|   | |||||||
| @@ -66,7 +66,8 @@ int main (int argc, char ** argv) | |||||||
|  |  | ||||||
|     Vec tsum; tsum = zero; |     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); |     std::vector<double> stop(threads); | ||||||
|     Vector<Vec> sum(threads); |     Vector<Vec> sum(threads); | ||||||
| @@ -77,8 +78,7 @@ int main (int argc, char ** argv) | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     double start=usecond(); |     double start=usecond(); | ||||||
| PARALLEL_FOR_LOOP |     parallel_for(int t=0;t<threads;t++){ | ||||||
|     for(int t=0;t<threads;t++){ |  | ||||||
|  |  | ||||||
|       sum[t] = x[t]._odata[0]; |       sum[t] = x[t]._odata[0]; | ||||||
|       for(int i=0;i<Nloop;i++){ |       for(int i=0;i<Nloop;i++){ | ||||||
|   | |||||||
| @@ -65,7 +65,7 @@ int main (int argc, char ** argv) | |||||||
|  |  | ||||||
|       uint64_t Nloop=NLOOP; |       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 z(&Grid); //random(pRNG,z); | ||||||
|       LatticeVec x(&Grid); //random(pRNG,x); |       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]; |       int vol = latt_size[0]*latt_size[1]*latt_size[2]*latt_size[3]; | ||||||
|       GridCartesian     Grid(latt_size,simd_layout,mpi_layout); |       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 z(&Grid); //random(pRNG,z); | ||||||
|       LatticeVec x(&Grid); //random(pRNG,x); |       LatticeVec x(&Grid); //random(pRNG,x); | ||||||
| @@ -138,7 +138,7 @@ int main (int argc, char ** argv) | |||||||
|  |  | ||||||
|       GridCartesian     Grid(latt_size,simd_layout,mpi_layout); |       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 z(&Grid); //random(pRNG,z); | ||||||
|       LatticeVec x(&Grid); //random(pRNG,x); |       LatticeVec x(&Grid); //random(pRNG,x); | ||||||
| @@ -173,7 +173,7 @@ int main (int argc, char ** argv) | |||||||
|       uint64_t Nloop=NLOOP; |       uint64_t Nloop=NLOOP; | ||||||
|       GridCartesian     Grid(latt_size,simd_layout,mpi_layout); |       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 z(&Grid); //random(pRNG,z); | ||||||
|       LatticeVec x(&Grid); //random(pRNG,x); |       LatticeVec x(&Grid); //random(pRNG,x); | ||||||
|       LatticeVec y(&Grid); //random(pRNG,y); |       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(); | ||||||
|  | } | ||||||
| @@ -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]}); |       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]; |       int vol = latt_size[0]*latt_size[1]*latt_size[2]*latt_size[3]; | ||||||
|       GridCartesian     Grid(latt_size,simd_layout,mpi_layout); |       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 z(&Grid);// random(pRNG,z); | ||||||
|       LatticeColourMatrix x(&Grid);// random(pRNG,x); |       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]; |       int vol = latt_size[0]*latt_size[1]*latt_size[2]*latt_size[3]; | ||||||
|  |  | ||||||
|       GridCartesian     Grid(latt_size,simd_layout,mpi_layout); |       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 z(&Grid); //random(pRNG,z); | ||||||
|       LatticeColourMatrix x(&Grid); //random(pRNG,x); |       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]; |       int vol = latt_size[0]*latt_size[1]*latt_size[2]*latt_size[3]; | ||||||
|  |  | ||||||
|       GridCartesian     Grid(latt_size,simd_layout,mpi_layout); |       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 z(&Grid); //random(pRNG,z); | ||||||
|       LatticeColourMatrix x(&Grid); //random(pRNG,x); |       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]; |       int vol = latt_size[0]*latt_size[1]*latt_size[2]*latt_size[3]; | ||||||
|  |  | ||||||
|       GridCartesian     Grid(latt_size,simd_layout,mpi_layout); |       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 z(&Grid); //random(pRNG,z); | ||||||
|       LatticeColourMatrix x(&Grid); //random(pRNG,x); |       LatticeColourMatrix x(&Grid); //random(pRNG,x); | ||||||
|   | |||||||
| @@ -37,11 +37,11 @@ struct scal { | |||||||
|   d internal; |   d internal; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   Gamma::GammaMatrix Gmu [] = { |   Gamma::Algebra Gmu [] = { | ||||||
|     Gamma::GammaX, |     Gamma::Algebra::GammaX, | ||||||
|     Gamma::GammaY, |     Gamma::Algebra::GammaY, | ||||||
|     Gamma::GammaZ, |     Gamma::Algebra::GammaZ, | ||||||
|     Gamma::GammaT |     Gamma::Algebra::GammaT | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
| bool overlapComms = false; | bool overlapComms = false; | ||||||
| @@ -69,7 +69,7 @@ int main (int argc, char ** argv) | |||||||
|   std::vector<int> seeds({1,2,3,4}); |   std::vector<int> seeds({1,2,3,4}); | ||||||
|   GridParallelRNG          pRNG(&Grid); |   GridParallelRNG          pRNG(&Grid); | ||||||
|   pRNG.SeedFixedIntegers(seeds); |   pRNG.SeedFixedIntegers(seeds); | ||||||
|   //  pRNG.SeedRandomDevice(); |   //  pRNG.SeedFixedIntegers(std::vector<int>({45,12,81,9}); | ||||||
|  |  | ||||||
|   LatticeFermion src   (&Grid); random(pRNG,src); |   LatticeFermion src   (&Grid); random(pRNG,src); | ||||||
|   LatticeFermion result(&Grid); result=zero; |   LatticeFermion result(&Grid); result=zero; | ||||||
| @@ -106,7 +106,7 @@ int main (int argc, char ** argv) | |||||||
|   { // Naive wilson implementation |   { // Naive wilson implementation | ||||||
|     ref = zero; |     ref = zero; | ||||||
|     for(int mu=0;mu<Nd;mu++){ |     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); |       tmp = U[mu]*Cshift(src,mu,1); | ||||||
|       for(int i=0;i<ref._odata.size();i++){ |       for(int i=0;i<ref._odata.size();i++){ | ||||||
| 	ref._odata[i]+= tmp._odata[i] - Gamma(Gmu[mu])*tmp._odata[i]; ; | 	ref._odata[i]+= tmp._odata[i] - Gamma(Gmu[mu])*tmp._odata[i]; ; | ||||||
| @@ -159,7 +159,7 @@ int main (int argc, char ** argv) | |||||||
|     ref = zero; |     ref = zero; | ||||||
|     for(int mu=0;mu<Nd;mu++){ |     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); |       tmp = U[mu]*Cshift(src,mu,1); | ||||||
|       for(int i=0;i<ref._odata.size();i++){ |       for(int i=0;i<ref._odata.size();i++){ | ||||||
| 	ref._odata[i]+= tmp._odata[i] + Gamma(Gmu[mu])*tmp._odata[i]; ; | 	ref._odata[i]+= tmp._odata[i] + Gamma(Gmu[mu])*tmp._odata[i]; ; | ||||||
|   | |||||||
| @@ -30,11 +30,11 @@ struct scal { | |||||||
|   d internal; |   d internal; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| Gamma::GammaMatrix Gmu [] = { | Gamma::Algebra Gmu [] = { | ||||||
|   Gamma::GammaX, |     Gamma::Algebra::GammaX, | ||||||
|   Gamma::GammaY, |     Gamma::Algebra::GammaY, | ||||||
|   Gamma::GammaZ, |     Gamma::Algebra::GammaZ, | ||||||
|   Gamma::GammaT |     Gamma::Algebra::GammaT | ||||||
| }; | }; | ||||||
|  |  | ||||||
| bool overlapComms = false; | bool overlapComms = false; | ||||||
| @@ -58,6 +58,19 @@ int main (int argc, char ** argv) | |||||||
|   std::vector<int> seeds({1,2,3,4}); |   std::vector<int> seeds({1,2,3,4}); | ||||||
|   RealD mass = 0.1; |   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 << "============================================================================="<< std::endl; | ||||||
|   std::cout<<GridLogMessage << "= Benchmarking Wilson" << std::endl; |   std::cout<<GridLogMessage << "= Benchmarking Wilson" << std::endl; | ||||||
|   std::cout<<GridLogMessage << "============================================================================="<< std::endl; |   std::cout<<GridLogMessage << "============================================================================="<< std::endl; | ||||||
|   | |||||||
| @@ -1,175 +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/Grid.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; |  | ||||||
|   std::cout<<GridLogMessage << "====================================================================="<<std::endl; |  | ||||||
|   std::cout<<GridLogMessage << "= Benchmarking ZMM"<<std::endl; |  | ||||||
|   std::cout<<GridLogMessage << "====================================================================="<<std::endl; |  | ||||||
|   std::cout<<GridLogMessage << "Volume \t\t\t\tC++DW/MFLOPs\tASM-DW/MFLOPs\tdiff"<<std::endl; |  | ||||||
|   std::cout<<GridLogMessage << "====================================================================="<<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}); |  | ||||||
|   std::cout << GridLogMessage <<"\t"; |  | ||||||
| 	for(int i=0;i<4;i++) {  |  | ||||||
| 	  std::cout << grid[i]<<"x"; |  | ||||||
| 	} |  | ||||||
| 	std::cout << Ls<<"\t\t"; |  | ||||||
| 	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); |  | ||||||
|  |  | ||||||
|   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<<mfc<<"\t\t"; |  | ||||||
|  |  | ||||||
|   QCD::WilsonKernelsStatic::AsmOpt=1; |  | ||||||
|   t0=usecond(); |  | ||||||
|   for(int i=0;i<ncall;i++){ |  | ||||||
|     Dw.DhopOE(srce,resulta,0); |  | ||||||
|   } |  | ||||||
|   t1=usecond(); |  | ||||||
|   mfa = flops*ncall/(t1-t0); |  | ||||||
|   std::cout<<mfa<<"\t\t"; |  | ||||||
|   /* |  | ||||||
|   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<<norm2(diff)<<std::endl; |  | ||||||
|   return 0; |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -1 +1,11 @@ | |||||||
| include Make.inc | 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 |     See the full license in the file "LICENSE" in the top level distribution directory | ||||||
|     *************************************************************************************/ |     *************************************************************************************/ | ||||||
|     /*  END LEGAL */ |     /*  END LEGAL */ | ||||||
| #include <Grid.h> | #include <Grid/Grid.h> | ||||||
|  |  | ||||||
| using namespace std; | using namespace std; | ||||||
| using namespace Grid; | 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 |     See the full license in the file "LICENSE" in the top level distribution directory | ||||||
|     *************************************************************************************/ |     *************************************************************************************/ | ||||||
|     /*  END LEGAL */ |     /*  END LEGAL */ | ||||||
| #include <Grid.h> | #include <Grid/Grid.h> | ||||||
|  |  | ||||||
| using namespace std; | using namespace std; | ||||||
| using namespace Grid; | using namespace Grid; | ||||||
|   | |||||||
| @@ -1,18 +1,12 @@ | |||||||
| #!/usr/bin/env bash | #!/usr/bin/env bash | ||||||
|  |  | ||||||
| EIGEN_URL='http://bitbucket.org/eigen/eigen/get/3.2.9.tar.bz2' | EIGEN_URL='http://bitbucket.org/eigen/eigen/get/3.2.9.tar.bz2' | ||||||
| FFTW_URL=http://www.fftw.org/fftw-3.3.4.tar.gz |  | ||||||
|  |  | ||||||
| echo "-- deploying Eigen source..." | echo "-- deploying Eigen source..." | ||||||
| wget ${EIGEN_URL} --no-check-certificate | wget ${EIGEN_URL} --no-check-certificate | ||||||
| ./scripts/update_eigen.sh `basename ${EIGEN_URL}` | ./scripts/update_eigen.sh `basename ${EIGEN_URL}` | ||||||
| rm `basename ${EIGEN_URL}` | rm `basename ${EIGEN_URL}` | ||||||
|  |  | ||||||
| echo "-- copying fftw prototypes..." |  | ||||||
| wget ${FFTW_URL} |  | ||||||
| ./scripts/update_fftw.sh `basename ${FFTW_URL}` |  | ||||||
| rm `basename ${FFTW_URL}` |  | ||||||
|  |  | ||||||
| echo '-- generating Make.inc files...' | echo '-- generating Make.inc files...' | ||||||
| ./scripts/filelist | ./scripts/filelist | ||||||
| echo '-- generating configure script...' | echo '-- generating configure script...' | ||||||
|   | |||||||
							
								
								
									
										355
									
								
								configure.ac
									
									
									
									
									
								
							
							
						
						
									
										355
									
								
								configure.ac
									
									
									
									
									
								
							| @@ -1,30 +1,41 @@ | |||||||
| AC_PREREQ([2.63]) | AC_PREREQ([2.63]) | ||||||
| AC_INIT([Grid], [0.5.1-dev], [https://github.com/paboyle/Grid], [Grid]) | AC_INIT([Grid], [0.6.0], [https://github.com/paboyle/Grid], [Grid]) | ||||||
| AC_CANONICAL_BUILD | AC_CANONICAL_BUILD | ||||||
| AC_CANONICAL_HOST | AC_CANONICAL_HOST | ||||||
| AC_CANONICAL_TARGET | AC_CANONICAL_TARGET | ||||||
| AM_INIT_AUTOMAKE(subdir-objects) | AM_INIT_AUTOMAKE(subdir-objects) | ||||||
| AC_CONFIG_MACRO_DIR([m4]) | AC_CONFIG_MACRO_DIR([m4]) | ||||||
| AC_CONFIG_SRCDIR([lib/Grid.h]) | 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])]) | m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) | ||||||
|  |  | ||||||
|  |  | ||||||
| ############### Checks for programs | ############### Checks for programs | ||||||
| AC_LANG(C++) |  | ||||||
| CXXFLAGS="-O3 $CXXFLAGS" | CXXFLAGS="-O3 $CXXFLAGS" | ||||||
| AC_PROG_CXX | AC_PROG_CXX | ||||||
| AC_PROG_RANLIB | AC_PROG_RANLIB | ||||||
|  |  | ||||||
| ############ openmp  ############### | ############### 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 typedefs, structures, and compiler characteristics | ||||||
|  | AC_TYPE_SIZE_T | ||||||
|  | AC_TYPE_UINT32_T | ||||||
|  | AC_TYPE_UINT64_T | ||||||
|  |  | ||||||
|  | ############### OpenMP  | ||||||
| AC_OPENMP | AC_OPENMP | ||||||
|  |  | ||||||
| ac_openmp=no | ac_openmp=no | ||||||
|  |  | ||||||
| if test "${OPENMP_CXXFLAGS}X" != "X"; then | if test "${OPENMP_CXXFLAGS}X" != "X"; then | ||||||
| ac_openmp=yes |   ac_openmp=yes | ||||||
| AM_CXXFLAGS="$OPENMP_CXXFLAGS $AM_CXXFLAGS" |   AM_CXXFLAGS="$OPENMP_CXXFLAGS $AM_CXXFLAGS" | ||||||
| AM_LDFLAGS="$OPENMP_CXXFLAGS $AM_LDFLAGS" |   AM_LDFLAGS="$OPENMP_CXXFLAGS $AM_LDFLAGS" | ||||||
| fi | fi | ||||||
|  |  | ||||||
| ############### Checks for header files | ############### Checks for header files | ||||||
| @@ -37,12 +48,7 @@ AC_CHECK_HEADERS(execinfo.h) | |||||||
| AC_CHECK_DECLS([ntohll],[], [], [[#include <arpa/inet.h>]]) | AC_CHECK_DECLS([ntohll],[], [], [[#include <arpa/inet.h>]]) | ||||||
| AC_CHECK_DECLS([be64toh],[], [], [[#include <arpa/inet.h>]]) | AC_CHECK_DECLS([be64toh],[], [], [[#include <arpa/inet.h>]]) | ||||||
|  |  | ||||||
| ############### Checks for typedefs, structures, and compiler characteristics | ############### GMP and MPFR | ||||||
| AC_TYPE_SIZE_T |  | ||||||
| AC_TYPE_UINT32_T |  | ||||||
| AC_TYPE_UINT64_T |  | ||||||
|  |  | ||||||
| ############### GMP and MPFR ################# |  | ||||||
| AC_ARG_WITH([gmp], | AC_ARG_WITH([gmp], | ||||||
|     [AS_HELP_STRING([--with-gmp=prefix], |     [AS_HELP_STRING([--with-gmp=prefix], | ||||||
|     [try this for a non-standard install prefix of the GMP library])], |     [try this for a non-standard install prefix of the GMP library])], | ||||||
| @@ -54,10 +60,17 @@ AC_ARG_WITH([mpfr], | |||||||
|     [AM_CXXFLAGS="-I$with_mpfr/include $AM_CXXFLAGS"] |     [AM_CXXFLAGS="-I$with_mpfr/include $AM_CXXFLAGS"] | ||||||
|     [AM_LDFLAGS="-L$with_mpfr/lib $AM_LDFLAGS"]) |     [AM_LDFLAGS="-L$with_mpfr/lib $AM_LDFLAGS"]) | ||||||
|  |  | ||||||
| ################## lapack #################### | ############### 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_ARG_ENABLE([lapack], | ||||||
|     [AC_HELP_STRING([--enable-lapack=yes|no|prefix], [enable LAPACK])],  |     [AC_HELP_STRING([--enable-lapack=yes|no|prefix], [enable LAPACK])],  | ||||||
|     [ac_LAPACK=${enable_lapack}],[ac_LAPACK=no]) |     [ac_LAPACK=${enable_lapack}], [ac_LAPACK=no]) | ||||||
|  |  | ||||||
| case ${ac_LAPACK} in | case ${ac_LAPACK} in | ||||||
|     no) |     no) | ||||||
| @@ -67,10 +80,46 @@ case ${ac_LAPACK} in | |||||||
|     *) |     *) | ||||||
|         AM_CXXFLAGS="-I$ac_LAPACK/include $AM_CXXFLAGS" |         AM_CXXFLAGS="-I$ac_LAPACK/include $AM_CXXFLAGS" | ||||||
|         AM_LDFLAGS="-L$ac_LAPACK/lib $AM_LDFLAGS" |         AM_LDFLAGS="-L$ac_LAPACK/lib $AM_LDFLAGS" | ||||||
|         AC_DEFINE([USE_LAPACK],[1],[use LAPACK]) |         AC_DEFINE([USE_LAPACK],[1],[use LAPACK]);; | ||||||
| esac | esac | ||||||
|  |  | ||||||
| ################## first-touch #################### | ############### FP16 conversions | ||||||
|  | AC_ARG_ENABLE([fp16], | ||||||
|  |     [AC_HELP_STRING([--enable-fp16=yes|no], [enable fp16 comms])],  | ||||||
|  |     [ac_FP16=${enable_fp16}], [ac_FP16=no]) | ||||||
|  | case ${ac_FP16} in | ||||||
|  |     no) | ||||||
|  |         ;; | ||||||
|  |     yes) | ||||||
|  |         AC_DEFINE([USE_FP16],[1],[conversion to fp16]);; | ||||||
|  |     *) | ||||||
|  | 	;; | ||||||
|  | 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_ARG_ENABLE([numa], | ||||||
|     [AC_HELP_STRING([--enable-numa=yes|no|prefix], [enable first touch numa opt])],  |     [AC_HELP_STRING([--enable-numa=yes|no|prefix], [enable first touch numa opt])],  | ||||||
|     [ac_NUMA=${enable_NUMA}],[ac_NUMA=no]) |     [ac_NUMA=${enable_NUMA}],[ac_NUMA=no]) | ||||||
| @@ -84,56 +133,56 @@ case ${ac_NUMA} in | |||||||
|         AC_DEFINE([GRID_NUMA],[1],[First touch numa locality]);; |         AC_DEFINE([GRID_NUMA],[1],[First touch numa locality]);; | ||||||
| esac | esac | ||||||
|  |  | ||||||
| ################## 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"]) |  | ||||||
|  |  | ||||||
| ################ 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 library functions | ############### Checks for library functions | ||||||
| CXXFLAGS_CPY=$CXXFLAGS | CXXFLAGS_CPY=$CXXFLAGS | ||||||
| LDFLAGS_CPY=$LDFLAGS | LDFLAGS_CPY=$LDFLAGS | ||||||
| CXXFLAGS="$AM_CXXFLAGS $CXXFLAGS" | CXXFLAGS="$AM_CXXFLAGS $CXXFLAGS" | ||||||
| LDFLAGS="$AM_LDFLAGS $LDFLAGS" | LDFLAGS="$AM_LDFLAGS $LDFLAGS" | ||||||
|  |  | ||||||
| AC_CHECK_FUNCS([gettimeofday]) | AC_CHECK_FUNCS([gettimeofday]) | ||||||
| AC_CHECK_LIB([gmp],[__gmpf_init], |  | ||||||
|              [AC_CHECK_LIB([mpfr],[mpfr_init], | if test "${ac_MKL}x" != "nox"; then | ||||||
|                  [AC_DEFINE([HAVE_LIBMPFR], [1], [Define to 1 if you have the `MPFR' library (-lmpfr).])] |     AC_SEARCH_LIBS([mkl_set_interface_layer], [mkl_rt], [], | ||||||
|                  [have_mpfr=true] |                    [AC_MSG_ERROR("MKL enabled but library not found")]) | ||||||
|                  [LIBS="$LIBS -lmpfr"], | fi | ||||||
|                  [AC_MSG_ERROR([MPFR library not found])])] |  | ||||||
|    	     [AC_DEFINE([HAVE_LIBGMP], [1], [Define to 1 if you have the `GMP' library (-lgmp).])] | AC_SEARCH_LIBS([__gmpf_init], [gmp], | ||||||
|              [have_gmp=true] |                [AC_SEARCH_LIBS([mpfr_init], [mpfr],  | ||||||
|              [LIBS="$LIBS -lgmp"], |                                [AC_DEFINE([HAVE_LIBMPFR], [1],  | ||||||
|              [AC_MSG_WARN([**** GMP library not found, Grid can still compile but RHMC will not work ****])]) |                                           [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]) | ||||||
|  |  | ||||||
| if test "${ac_LAPACK}x" != "nox"; then | if test "${ac_LAPACK}x" != "nox"; then | ||||||
|     AC_CHECK_LIB([lapack],[LAPACKE_sbdsdc],[], |     AC_SEARCH_LIBS([LAPACKE_sbdsdc], [lapack], [], | ||||||
|                  [AC_MSG_ERROR("LAPACK enabled but library not found")]) |                    [AC_MSG_ERROR("LAPACK enabled but library not found")]) | ||||||
| fi    | fi    | ||||||
| AC_CHECK_LIB([fftw3],[fftw_execute], |  | ||||||
|   [AC_DEFINE([HAVE_FFTW],[1],[Define to 1 if you have the `FFTW' library (-lfftw3).])] | AC_SEARCH_LIBS([fftw_execute], [fftw3], | ||||||
|   [have_fftw=true] |                [AC_SEARCH_LIBS([fftwf_execute], [fftw3f], [], | ||||||
|   [LIBS="$LIBS -lfftw3 -lfftw3f"], |                                [AC_MSG_ERROR("single precision FFTW library not found")])] | ||||||
|   [AC_MSG_WARN([**** FFTW library not found, Grid can still compile but FFT-based routines will not work ****])]) |                [AC_DEFINE([HAVE_FFTW], [1], [Define to 1 if you have the `FFTW' library])] | ||||||
|  |                [have_fftw=true]) | ||||||
|  |  | ||||||
|  | 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 | CXXFLAGS=$CXXFLAGS_CPY | ||||||
| LDFLAGS=$LDFLAGS_CPY | LDFLAGS=$LDFLAGS_CPY | ||||||
|  |  | ||||||
| ############### SIMD instruction selection | ############### SIMD instruction selection | ||||||
| AC_ARG_ENABLE([simd],[AC_HELP_STRING([--enable-simd=SSE4|AVX|AVXFMA4|AVXFMA|AVX2|AVX512|AVX512MIC|IMCI|KNL|KNC],\ | AC_ARG_ENABLE([simd],[AC_HELP_STRING([--enable-simd=code], | ||||||
| 	[Select instructions to be SSE4.0, AVX 1.0, AVX 2.0+FMA, AVX 512, IMCI])],\ |               [select SIMD target (cf. README.md)])], [ac_SIMD=${enable_simd}], [ac_SIMD=GEN]) | ||||||
| 	[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 | case ${ax_cv_cxx_compiler_vendor} in | ||||||
|   clang|gnu) |   clang|gnu) | ||||||
| @@ -143,24 +192,30 @@ case ${ax_cv_cxx_compiler_vendor} in | |||||||
|         SIMD_FLAGS='-msse4.2';; |         SIMD_FLAGS='-msse4.2';; | ||||||
|       AVX) |       AVX) | ||||||
|         AC_DEFINE([AVX1],[1],[AVX intrinsics]) |         AC_DEFINE([AVX1],[1],[AVX intrinsics]) | ||||||
|         SIMD_FLAGS='-mavx';; |         SIMD_FLAGS='-mavx -mf16c';; | ||||||
|       AVXFMA4) |       AVXFMA4) | ||||||
|         AC_DEFINE([AVXFMA4],[1],[AVX intrinsics with FMA4]) |         AC_DEFINE([AVXFMA4],[1],[AVX intrinsics with FMA4]) | ||||||
|         SIMD_FLAGS='-mavx -mfma4';; |         SIMD_FLAGS='-mavx -mfma4 -mf16c';; | ||||||
|       AVXFMA) |       AVXFMA) | ||||||
|         AC_DEFINE([AVXFMA],[1],[AVX intrinsics with FMA3]) |         AC_DEFINE([AVXFMA],[1],[AVX intrinsics with FMA3]) | ||||||
|         SIMD_FLAGS='-mavx -mfma';; |         SIMD_FLAGS='-mavx -mfma -mf16c';; | ||||||
|       AVX2) |       AVX2) | ||||||
|         AC_DEFINE([AVX2],[1],[AVX2 intrinsics]) |         AC_DEFINE([AVX2],[1],[AVX2 intrinsics]) | ||||||
|         SIMD_FLAGS='-mavx2 -mfma';; |         SIMD_FLAGS='-mavx2 -mfma -mf16c';; | ||||||
|       AVX512|AVX512MIC|KNL) |       AVX512) | ||||||
|         AC_DEFINE([AVX512],[1],[AVX512 intrinsics]) |         AC_DEFINE([AVX512],[1],[AVX512 intrinsics]) | ||||||
|         SIMD_FLAGS='-mavx512f -mavx512pf -mavx512er -mavx512cd';; |         SIMD_FLAGS='-mavx512f -mavx512pf -mavx512er -mavx512cd';; | ||||||
|       IMCI|KNC) |       KNC) | ||||||
|         AC_DEFINE([IMCI],[1],[IMCI intrinsics for Knights Corner]) |         AC_DEFINE([IMCI],[1],[IMCI intrinsics for Knights Corner]) | ||||||
|         SIMD_FLAGS='';; |         SIMD_FLAGS='';; | ||||||
|  |       KNL) | ||||||
|  |         AC_DEFINE([AVX512],[1],[AVX512 intrinsics]) | ||||||
|  |         SIMD_FLAGS='-march=knl';; | ||||||
|       GEN) |       GEN) | ||||||
|         AC_DEFINE([GENERIC_VEC],[1],[generic vector code]) |         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='';; |         SIMD_FLAGS='';; | ||||||
|       QPX|BGQ) |       QPX|BGQ) | ||||||
|         AC_DEFINE([QPX],[1],[QPX intrinsics for BG/Q]) |         AC_DEFINE([QPX],[1],[QPX intrinsics for BG/Q]) | ||||||
| @@ -176,26 +231,26 @@ case ${ax_cv_cxx_compiler_vendor} in | |||||||
|       AVX) |       AVX) | ||||||
|         AC_DEFINE([AVX1],[1],[AVX intrinsics]) |         AC_DEFINE([AVX1],[1],[AVX intrinsics]) | ||||||
|         SIMD_FLAGS='-mavx -xavx';; |         SIMD_FLAGS='-mavx -xavx';; | ||||||
|       AVXFMA4) |  | ||||||
|         AC_DEFINE([AVXFMA4],[1],[AVX intrinsics with FMA4]) |  | ||||||
|         SIMD_FLAGS='-mavx -mfma';; |  | ||||||
|       AVXFMA) |       AVXFMA) | ||||||
|         AC_DEFINE([AVXFMA],[1],[AVX intrinsics with FMA4]) |         AC_DEFINE([AVXFMA],[1],[AVX intrinsics with FMA3]) | ||||||
|         SIMD_FLAGS='-mavx -mfma';; |         SIMD_FLAGS='-mavx -fma';; | ||||||
|       AVX2) |       AVX2) | ||||||
|         AC_DEFINE([AVX2],[1],[AVX2 intrinsics]) |         AC_DEFINE([AVX2],[1],[AVX2 intrinsics]) | ||||||
|         SIMD_FLAGS='-march=core-avx2 -xcore-avx2';; |         SIMD_FLAGS='-march=core-avx2 -xcore-avx2';; | ||||||
|       AVX512) |       AVX512) | ||||||
|         AC_DEFINE([AVX512],[1],[AVX512 intrinsics]) |         AC_DEFINE([AVX512],[1],[AVX512 intrinsics]) | ||||||
|         SIMD_FLAGS='-xcore-avx512';; |         SIMD_FLAGS='-xcore-avx512';; | ||||||
|       AVX512MIC|KNL) |       KNC) | ||||||
|         AC_DEFINE([AVX512],[1],[AVX512 intrinsics for Knights Landing]) |  | ||||||
|         SIMD_FLAGS='-xmic-avx512';; |  | ||||||
|       IMCI|KNC) |  | ||||||
|         AC_DEFINE([IMCI],[1],[IMCI Intrinsics for Knights Corner]) |         AC_DEFINE([IMCI],[1],[IMCI Intrinsics for Knights Corner]) | ||||||
|         SIMD_FLAGS='';; |         SIMD_FLAGS='';; | ||||||
|  |       KNL) | ||||||
|  |         AC_DEFINE([AVX512],[1],[AVX512 intrinsics for Knights Landing]) | ||||||
|  |         SIMD_FLAGS='-xmic-avx512';; | ||||||
|       GEN) |       GEN) | ||||||
|         AC_DEFINE([GENERIC_VEC],[1],[generic vector code]) |         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='';; |         SIMD_FLAGS='';; | ||||||
|       *) |       *) | ||||||
|         AC_MSG_ERROR(["SIMD option ${ac_SIMD} not supported by the Intel compiler"]);; |         AC_MSG_ERROR(["SIMD option ${ac_SIMD} not supported by the Intel compiler"]);; | ||||||
| @@ -208,14 +263,18 @@ AM_CXXFLAGS="$SIMD_FLAGS $AM_CXXFLAGS" | |||||||
| AM_CFLAGS="$SIMD_FLAGS $AM_CFLAGS" | AM_CFLAGS="$SIMD_FLAGS $AM_CFLAGS" | ||||||
|  |  | ||||||
| case ${ac_SIMD} in | case ${ac_SIMD} in | ||||||
|   AVX512|AVX512MIC|KNL) |   AVX512|KNL) | ||||||
|     AC_DEFINE([TEST_ZMM],[1],[compile ZMM test]);; |     AC_DEFINE([TEST_ZMM],[1],[compile ZMM test]);; | ||||||
|   *) |   *) | ||||||
| 	;; | 	;; | ||||||
| esac | esac | ||||||
|  |  | ||||||
| ############### precision selection | ############### 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]) | 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 | case ${ac_PRECISION} in | ||||||
|      single) |      single) | ||||||
|        AC_DEFINE([GRID_DEFAULT_PRECISION_SINGLE],[1],[GRID_DEFAULT_PRECISION is SINGLE] ) |        AC_DEFINE([GRID_DEFAULT_PRECISION_SINGLE],[1],[GRID_DEFAULT_PRECISION is SINGLE] ) | ||||||
| @@ -226,43 +285,56 @@ case ${ac_PRECISION} in | |||||||
| esac | esac | ||||||
|  |  | ||||||
| ############### communication type selection | ############### communication type selection | ||||||
| AC_ARG_ENABLE([comms],[AC_HELP_STRING([--enable-comms=none|mpi|mpi-auto|shmem],[Select communications])],[ac_COMMS=${enable_comms}],[ac_COMMS=none]) | 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 | case ${ac_COMMS} in | ||||||
|      none) |      none) | ||||||
|        AC_DEFINE([GRID_COMMS_NONE],[1],[GRID_COMMS_NONE] ) |         AC_DEFINE([GRID_COMMS_NONE],[1],[GRID_COMMS_NONE] ) | ||||||
|  |         comms_type='none' | ||||||
|      ;; |      ;; | ||||||
|      mpi-auto) |      mpi3l*) | ||||||
|        AC_DEFINE([GRID_COMMS_MPI],[1],[GRID_COMMS_MPI] ) |        AC_DEFINE([GRID_COMMS_MPI3L],[1],[GRID_COMMS_MPI3L] ) | ||||||
|        LX_FIND_MPI |        comms_type='mpi3l' | ||||||
|        if test "x$have_CXX_mpi" = 'xno'; then AC_MSG_ERROR(["MPI not found"]); 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" |  | ||||||
|      ;; |      ;; | ||||||
|      mpi) |      mpi3*) | ||||||
|        AC_DEFINE([GRID_COMMS_MPI],[1],[GRID_COMMS_MPI] ) |         AC_DEFINE([GRID_COMMS_MPI3],[1],[GRID_COMMS_MPI3] ) | ||||||
|  |         comms_type='mpi3' | ||||||
|      ;; |      ;; | ||||||
|      mpi3) |      mpi*) | ||||||
|        AC_DEFINE([GRID_COMMS_MPI3],[1],[GRID_COMMS_MPI3] ) |         AC_DEFINE([GRID_COMMS_MPI],[1],[GRID_COMMS_MPI] ) | ||||||
|  |         comms_type='mpi' | ||||||
|      ;; |      ;; | ||||||
|      shmem) |      shmem) | ||||||
|        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 | esac | ||||||
| AM_CONDITIONAL(BUILD_COMMS_SHMEM,[ test "X${ac_COMMS}X" == "XshmemX" ]) | case ${ac_COMMS} in | ||||||
| AM_CONDITIONAL(BUILD_COMMS_MPI,[ test "X${ac_COMMS}X" == "XmpiX" || test "X${ac_COMMS}X" == "Xmpi-autoX" ]) |     *-auto) | ||||||
| AM_CONDITIONAL(BUILD_COMMS_MPI3,[ test "X${ac_COMMS}X" == "Xmpi3X"] ) |         LX_FIND_MPI | ||||||
| AM_CONDITIONAL(BUILD_COMMS_NONE,[ test "X${ac_COMMS}X" == "XnoneX" ]) |         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 "${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 | ############### RNG selection | ||||||
| AC_ARG_ENABLE([rng],[AC_HELP_STRING([--enable-rng=ranlux48|mt19937],\ | AC_ARG_ENABLE([rng],[AC_HELP_STRING([--enable-rng=ranlux48|mt19937|sitmo],\ | ||||||
| 	[Select Random Number Generator to be used])],\ | 	            [Select Random Number Generator to be used])],\ | ||||||
| 	[ac_RNG=${enable_rng}],[ac_RNG=ranlux48]) | 	            [ac_RNG=${enable_rng}],[ac_RNG=sitmo]) | ||||||
|  |  | ||||||
| case ${ac_RNG} in | case ${ac_RNG} in | ||||||
|      ranlux48) |      ranlux48) | ||||||
| @@ -271,15 +343,19 @@ case ${ac_RNG} in | |||||||
|      mt19937) |      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 | esac | ||||||
|  |  | ||||||
| ############### timer option | ############### Timer option | ||||||
| AC_ARG_ENABLE([timers],[AC_HELP_STRING([--enable-timers],\ | AC_ARG_ENABLE([timers],[AC_HELP_STRING([--enable-timers],\ | ||||||
| 	[Enable system dependent high res timers])],\ | 	            [Enable system dependent high res timers])],\ | ||||||
| 	[ac_TIMERS=${enable_timers}],[ac_TIMERS=yes]) | 	            [ac_TIMERS=${enable_timers}],[ac_TIMERS=yes]) | ||||||
|  |  | ||||||
| case ${ac_TIMERS} in | case ${ac_TIMERS} in | ||||||
|      yes) |      yes) | ||||||
|       AC_DEFINE([TIMERS_ON],[1],[TIMERS_ON] ) |       AC_DEFINE([TIMERS_ON],[1],[TIMERS_ON] ) | ||||||
| @@ -293,7 +369,9 @@ case ${ac_TIMERS} in | |||||||
| esac | esac | ||||||
|  |  | ||||||
| ############### Chroma regression test | ############### Chroma regression test | ||||||
| AC_ARG_ENABLE([chroma],[AC_HELP_STRING([--enable-chroma],[Expect chroma compiled under c++11 ])],ac_CHROMA=yes,ac_CHROMA=no) | 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 | case ${ac_CHROMA} in | ||||||
|      yes|no) |      yes|no) | ||||||
|      ;; |      ;; | ||||||
| @@ -301,15 +379,21 @@ case ${ac_CHROMA} in | |||||||
|        AC_MSG_ERROR([${ac_CHROMA} unsupported --enable-chroma option]);  |        AC_MSG_ERROR([${ac_CHROMA} unsupported --enable-chroma option]);  | ||||||
|      ;; |      ;; | ||||||
| esac | esac | ||||||
|  |  | ||||||
| AM_CONDITIONAL(BUILD_CHROMA_REGRESSION,[ test "X${ac_CHROMA}X" == "XyesX" ]) | AM_CONDITIONAL(BUILD_CHROMA_REGRESSION,[ test "X${ac_CHROMA}X" == "XyesX" ]) | ||||||
|  |  | ||||||
| ############### Doxygen | ############### Doxygen | ||||||
| AC_PROG_DOXYGEN | DX_DOXYGEN_FEATURE([OFF]) | ||||||
|  | DX_DOT_FEATURE([OFF]) | ||||||
| if test -n "$DOXYGEN" | DX_HTML_FEATURE([ON]) | ||||||
| then | DX_CHM_FEATURE([OFF]) | ||||||
| AC_CONFIG_FILES([docs/doxy.cfg]) | DX_CHI_FEATURE([OFF]) | ||||||
| fi | 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]) | ||||||
|  |  | ||||||
| ############### Ouput | ############### Ouput | ||||||
| cwd=`pwd -P`; cd ${srcdir}; abs_srcdir=`pwd -P`; cd ${cwd} | cwd=`pwd -P`; cd ${srcdir}; abs_srcdir=`pwd -P`; cd ${cwd} | ||||||
| @@ -326,41 +410,46 @@ AC_CONFIG_FILES(tests/IO/Makefile) | |||||||
| AC_CONFIG_FILES(tests/core/Makefile) | AC_CONFIG_FILES(tests/core/Makefile) | ||||||
| AC_CONFIG_FILES(tests/debug/Makefile) | AC_CONFIG_FILES(tests/debug/Makefile) | ||||||
| AC_CONFIG_FILES(tests/forces/Makefile) | AC_CONFIG_FILES(tests/forces/Makefile) | ||||||
|  | AC_CONFIG_FILES(tests/hadrons/Makefile) | ||||||
| AC_CONFIG_FILES(tests/hmc/Makefile) | AC_CONFIG_FILES(tests/hmc/Makefile) | ||||||
| AC_CONFIG_FILES(tests/solver/Makefile) | AC_CONFIG_FILES(tests/solver/Makefile) | ||||||
| AC_CONFIG_FILES(tests/qdpxx/Makefile) | AC_CONFIG_FILES(tests/qdpxx/Makefile) | ||||||
|  | AC_CONFIG_FILES(tests/testu01/Makefile) | ||||||
| AC_CONFIG_FILES(benchmarks/Makefile) | AC_CONFIG_FILES(benchmarks/Makefile) | ||||||
|  | AC_CONFIG_FILES(extras/Makefile) | ||||||
|  | AC_CONFIG_FILES(extras/Hadrons/Makefile) | ||||||
| AC_OUTPUT | AC_OUTPUT | ||||||
|  |  | ||||||
| echo " | echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |  | ||||||
| Summary of configuration for $PACKAGE v$VERSION | Summary of configuration for $PACKAGE v$VERSION | ||||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||||
|  |  | ||||||
| ----- PLATFORM ---------------------------------------- | ----- PLATFORM ---------------------------------------- | ||||||
| - architecture (build)          : $build_cpu | architecture (build)        : $build_cpu | ||||||
| - os (build)                    : $build_os | os (build)                  : $build_os | ||||||
| - architecture (target)         : $target_cpu | architecture (target)       : $target_cpu | ||||||
| - os (target)                   : $target_os | os (target)                 : $target_os | ||||||
| - compiler vendor               : ${ax_cv_cxx_compiler_vendor} | compiler vendor             : ${ax_cv_cxx_compiler_vendor} | ||||||
| - compiler version              : ${ax_cv_gxx_version} | compiler version            : ${ax_cv_gxx_version} | ||||||
| ----- BUILD OPTIONS ----------------------------------- | ----- BUILD OPTIONS ----------------------------------- | ||||||
| - SIMD                          : ${ac_SIMD} | SIMD                        : ${ac_SIMD}${SIMD_GEN_WIDTH_MSG} | ||||||
| - Threading                     : ${ac_openmp}  | Threading                   : ${ac_openmp}  | ||||||
| - Communications type           : ${ac_COMMS} | Communications type         : ${comms_type} | ||||||
| - Default precision             : ${ac_PRECISION} | Default precision           : ${ac_PRECISION} | ||||||
| - RNG choice                    : ${ac_RNG}  | RNG choice                  : ${ac_RNG}  | ||||||
| - GMP                           : `if test "x$have_gmp" = xtrue; then echo yes; else echo no; fi` | GMP                         : `if test "x$have_gmp" = xtrue; then echo yes; else echo no; fi` | ||||||
| - LAPACK                        : ${ac_LAPACK} | LAPACK                      : ${ac_LAPACK} | ||||||
| - FFTW                          : `if test "x$have_fftw" = xtrue; then echo yes; else echo no; fi` | FFTW                        : `if test "x$have_fftw" = xtrue; then echo yes; else echo no; fi` | ||||||
| - build DOXYGEN documentation   : `if test "x$enable_doc" = xyes; then echo yes; else echo no; fi` | HDF5                        : `if test "x$have_hdf5" = xtrue; then echo yes; else echo no; fi` | ||||||
| - graphs and diagrams           : `if test "x$enable_dot" = xyes; 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 ------------------------------------- | ----- BUILD FLAGS ------------------------------------- | ||||||
| - CXXFLAGS: | CXXFLAGS: | ||||||
| `echo ${AM_CXXFLAGS} ${CXXFLAGS} | tr ' ' '\n' | sed 's/^-/    -/g'` | `echo ${AM_CXXFLAGS} ${CXXFLAGS} | tr ' ' '\n' | sed 's/^-/    -/g'` | ||||||
| - LDFLAGS: | LDFLAGS: | ||||||
| `echo ${AM_LDFLAGS} ${LDFLAGS} | tr ' ' '\n' | sed 's/^-/    -/g'` | `echo ${AM_LDFLAGS} ${LDFLAGS} | tr ' ' '\n' | sed 's/^-/    -/g'` | ||||||
| - LIBS: | LIBS: | ||||||
| `echo ${LIBS} | tr ' ' '\n' | sed 's/^-/    -/g'` | `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 | ||||||
							
								
								
									
										53
									
								
								lib/Grid.h
									
									
									
									
									
								
							
							
						
						
									
										53
									
								
								lib/Grid.h
									
									
									
									
									
								
							| @@ -38,53 +38,10 @@ Author: paboyle <paboyle@ph.ed.ac.uk> | |||||||
| #ifndef GRID_H | #ifndef GRID_H | ||||||
| #define GRID_H | #define GRID_H | ||||||
|  |  | ||||||
| /////////////////// | #include <Grid/GridCore.h> | ||||||
| // Std C++ dependencies | #include <Grid/GridQCDcore.h> | ||||||
| /////////////////// | #include <Grid/qcd/action/Action.h> | ||||||
| #include <cassert> | #include <Grid/qcd/smearing/Smearing.h> | ||||||
| #include <complex> | #include <Grid/qcd/hmc/HMC_aggregate.h> | ||||||
| #include <vector> |  | ||||||
| #include <iostream> |  | ||||||
| #include <iomanip> |  | ||||||
| #include <random> |  | ||||||
| #include <functional> |  | ||||||
| #include <stdio.h> |  | ||||||
| #include <stdlib.h> |  | ||||||
| #include <stdio.h> |  | ||||||
| #include <signal.h> |  | ||||||
| #include <ctime> |  | ||||||
| #include <sys/time.h> |  | ||||||
| #include <chrono> |  | ||||||
|  |  | ||||||
| /////////////////// |  | ||||||
| // Grid headers |  | ||||||
| /////////////////// |  | ||||||
| #include <Grid/serialisation/Serialisation.h> |  | ||||||
| #include "Config.h" |  | ||||||
| #include <Grid/Timer.h> |  | ||||||
| #include <Grid/PerfCount.h> |  | ||||||
| #include <Grid/Log.h> |  | ||||||
| #include <Grid/AlignedAllocator.h> |  | ||||||
| #include <Grid/Simd.h> |  | ||||||
| #include <Grid/Threads.h> |  | ||||||
| #include <Grid/Lexicographic.h> |  | ||||||
| #include <Grid/Init.h> |  | ||||||
| #include <Grid/Communicator.h>  |  | ||||||
| #include <Grid/Cartesian.h>     |  | ||||||
| #include <Grid/Tensors.h>       |  | ||||||
| #include <Grid/Lattice.h>       |  | ||||||
| #include <Grid/Cshift.h>        |  | ||||||
| #include <Grid/Stencil.h>       |  | ||||||
| #include <Grid/Algorithms.h>    |  | ||||||
| #include <Grid/parallelIO/BinaryIO.h> |  | ||||||
| #include <Grid/qcd/QCD.h> |  | ||||||
| #include <Grid/parallelIO/NerscIO.h> |  | ||||||
|  |  | ||||||
| #include <Grid/FFT.h> |  | ||||||
|  |  | ||||||
| #include <Grid/qcd/hmc/NerscCheckpointer.h> |  | ||||||
| #include <Grid/qcd/hmc/HmcRunner.h> |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| #endif | #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  |     Grid physics library, www.github.com/paboyle/Grid  | ||||||
| 
 | 
 | ||||||
|     Source file: ./lib/qcd/hmc/HMC.cc |     Source file: ./lib/Grid.h | ||||||
| 
 | 
 | ||||||
|     Copyright (C) 2015 |     Copyright (C) 2015 | ||||||
| 
 | 
 | ||||||
| Author: Peter Boyle <paboyle@ph.ed.ac.uk> | 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> | Author: paboyle <paboyle@ph.ed.ac.uk> | ||||||
| 
 | 
 | ||||||
|     This program is free software; you can redistribute it and/or modify |     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 |     See the full license in the file "LICENSE" in the top level distribution directory | ||||||
|     *************************************************************************************/ |     *************************************************************************************/ | ||||||
|     /*  END LEGAL */ |     /*  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 | ||||||
| @@ -1,4 +1,5 @@ | |||||||
| extra_sources= | extra_sources= | ||||||
|  | extra_headers= | ||||||
| if BUILD_COMMS_MPI | if BUILD_COMMS_MPI | ||||||
|   extra_sources+=communicator/Communicator_mpi.cc |   extra_sources+=communicator/Communicator_mpi.cc | ||||||
|   extra_sources+=communicator/Communicator_base.cc |   extra_sources+=communicator/Communicator_base.cc | ||||||
| @@ -9,6 +10,11 @@ if BUILD_COMMS_MPI3 | |||||||
|   extra_sources+=communicator/Communicator_base.cc |   extra_sources+=communicator/Communicator_base.cc | ||||||
| endif | endif | ||||||
|  |  | ||||||
|  | if BUILD_COMMS_MPI3L | ||||||
|  |   extra_sources+=communicator/Communicator_mpi3_leader.cc | ||||||
|  |   extra_sources+=communicator/Communicator_base.cc | ||||||
|  | endif | ||||||
|  |  | ||||||
| if BUILD_COMMS_SHMEM | if BUILD_COMMS_SHMEM | ||||||
|   extra_sources+=communicator/Communicator_shmem.cc |   extra_sources+=communicator/Communicator_shmem.cc | ||||||
|   extra_sources+=communicator/Communicator_base.cc |   extra_sources+=communicator/Communicator_base.cc | ||||||
| @@ -19,6 +25,12 @@ if BUILD_COMMS_NONE | |||||||
|   extra_sources+=communicator/Communicator_base.cc |   extra_sources+=communicator/Communicator_base.cc | ||||||
| endif | endif | ||||||
|  |  | ||||||
|  | if BUILD_HDF5 | ||||||
|  |   extra_sources+=serialisation/Hdf5IO.cc  | ||||||
|  |   extra_headers+=serialisation/Hdf5IO.h | ||||||
|  |   extra_headers+=serialisation/Hdf5Type.h | ||||||
|  | endif | ||||||
|  |  | ||||||
| # | # | ||||||
| # Libraries | # Libraries | ||||||
| # | # | ||||||
| @@ -27,6 +39,9 @@ include Eigen.inc | |||||||
|  |  | ||||||
| lib_LIBRARIES = libGrid.a | lib_LIBRARIES = libGrid.a | ||||||
|  |  | ||||||
| libGrid_a_SOURCES              = $(CCFILES) $(extra_sources) | CCFILES += $(extra_sources) | ||||||
|  | HFILES  += $(extra_headers) | ||||||
|  |  | ||||||
|  | libGrid_a_SOURCES              = $(CCFILES) | ||||||
| libGrid_adir                   = $(pkgincludedir) | libGrid_adir                   = $(pkgincludedir) | ||||||
| nobase_dist_pkginclude_HEADERS = $(HFILES) $(eigen_files) Config.h | nobase_dist_pkginclude_HEADERS = $(HFILES) $(eigen_files) Config.h | ||||||
|   | |||||||
										
											Binary file not shown.
										
									
								
							| @@ -1,154 +0,0 @@ | |||||||
|     /************************************************************************************* |  | ||||||
|  |  | ||||||
|     Grid physics library, www.github.com/paboyle/Grid  |  | ||||||
|  |  | ||||||
|     Source file: ./lib/Old/Tensor_peek.h |  | ||||||
|  |  | ||||||
|     Copyright (C) 2015 |  | ||||||
|  |  | ||||||
| Author: Peter Boyle <paboyle@ph.ed.ac.uk> |  | ||||||
|  |  | ||||||
|     This program is free software; you can redistribute it and/or modify |  | ||||||
|     it under the terms of the GNU General Public License as published by |  | ||||||
|     the Free Software Foundation; either version 2 of the License, or |  | ||||||
|     (at your option) any later version. |  | ||||||
|  |  | ||||||
|     This program is distributed in the hope that it will be useful, |  | ||||||
|     but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
|     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the |  | ||||||
|     GNU General Public License for more details. |  | ||||||
|  |  | ||||||
|     You should have received a copy of the GNU General Public License along |  | ||||||
|     with this program; if not, write to the Free Software Foundation, Inc., |  | ||||||
|     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |  | ||||||
|  |  | ||||||
|     See the full license in the file "LICENSE" in the top level distribution directory |  | ||||||
|     *************************************************************************************/ |  | ||||||
|     /*  END LEGAL */ |  | ||||||
| #ifndef GRID_MATH_PEEK_H |  | ||||||
| #define GRID_MATH_PEEK_H |  | ||||||
| namespace Grid { |  | ||||||
|  |  | ||||||
| ////////////////////////////////////////////////////////////////////////////// |  | ||||||
| // Peek on a specific index; returns a scalar in that index, tensor inherits rest |  | ||||||
| ////////////////////////////////////////////////////////////////////////////// |  | ||||||
| // If we hit the right index, return scalar with no further recursion |  | ||||||
|  |  | ||||||
| //template<int Level> inline ComplexF peekIndex(const ComplexF arg) { return arg;} |  | ||||||
| //template<int Level> inline ComplexD peekIndex(const ComplexD arg) { return arg;} |  | ||||||
| //template<int Level> inline RealF peekIndex(const RealF arg) { return arg;} |  | ||||||
| //template<int Level> inline RealD peekIndex(const RealD arg) { return arg;} |  | ||||||
| #if 0 |  | ||||||
| // Scalar peek, no indices |  | ||||||
| template<int Level,class vtype,typename std::enable_if< iScalar<vtype>::TensorLevel == Level >::type * =nullptr> inline  |  | ||||||
|   auto peekIndex(const iScalar<vtype> &arg) ->  iScalar<vtype>  |  | ||||||
| { |  | ||||||
|   return arg; |  | ||||||
| } |  | ||||||
| // Vector peek, one index |  | ||||||
| template<int Level,class vtype,int N,typename std::enable_if< iScalar<vtype>::TensorLevel == Level >::type * =nullptr> inline  |  | ||||||
|   auto peekIndex(const iVector<vtype,N> &arg,int i) -> iScalar<vtype> // Index matches |  | ||||||
| { |  | ||||||
|   iScalar<vtype> ret;                              // return scalar |  | ||||||
|   ret._internal = arg._internal[i]; |  | ||||||
|   return ret; |  | ||||||
| } |  | ||||||
| // Matrix peek, two indices |  | ||||||
| template<int Level,class vtype,int N,typename std::enable_if< iScalar<vtype>::TensorLevel == Level >::type * =nullptr> inline  |  | ||||||
|   auto peekIndex(const iMatrix<vtype,N> &arg,int i,int j) ->  iScalar<vtype> |  | ||||||
| { |  | ||||||
|   iScalar<vtype> ret;                              // return scalar |  | ||||||
|   ret._internal = arg._internal[i][j]; |  | ||||||
|   return ret; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| ///////////// |  | ||||||
| // No match peek for scalar,vector,matrix must forward on either 0,1,2 args. Must have 9 routines with notvalue |  | ||||||
| ///////////// |  | ||||||
| // scalar |  | ||||||
| template<int Level,class vtype,typename std::enable_if< iScalar<vtype>::TensorLevel != Level >::type * =nullptr> inline  |  | ||||||
|   auto peekIndex(const iScalar<vtype> &arg) -> iScalar<decltype(peekIndex<Level>(arg._internal))> |  | ||||||
| { |  | ||||||
|   iScalar<decltype(peekIndex<Level>(arg._internal))> ret; |  | ||||||
|   ret._internal= peekIndex<Level>(arg._internal); |  | ||||||
|   return ret; |  | ||||||
| } |  | ||||||
| template<int Level,class vtype, typename std::enable_if< iScalar<vtype>::TensorLevel != Level >::type * =nullptr> inline  |  | ||||||
|   auto peekIndex(const iScalar<vtype> &arg,int i) ->  iScalar<decltype(peekIndex<Level>(arg._internal,i))>  |  | ||||||
| { |  | ||||||
|   iScalar<decltype(peekIndex<Level>(arg._internal,i))> ret; |  | ||||||
|   ret._internal=peekIndex<Level>(arg._internal,i); |  | ||||||
|   return ret; |  | ||||||
| } |  | ||||||
| template<int Level,class vtype, typename std::enable_if< iScalar<vtype>::TensorLevel != Level >::type * =nullptr> inline  |  | ||||||
|   auto peekIndex(const iScalar<vtype> &arg,int i,int j) ->  iScalar<decltype(peekIndex<Level>(arg._internal,i,j))> |  | ||||||
| { |  | ||||||
|   iScalar<decltype(peekIndex<Level>(arg._internal,i,j))> ret; |  | ||||||
|   ret._internal=peekIndex<Level>(arg._internal,i,j); |  | ||||||
|   return ret; |  | ||||||
| } |  | ||||||
| // vector |  | ||||||
| template<int Level,class vtype,int N, typename std::enable_if< iScalar<vtype>::TensorLevel != Level >::type * =nullptr> inline  |  | ||||||
| auto peekIndex(const iVector<vtype,N> &arg) ->   iVector<decltype(peekIndex<Level>(arg._internal[0])),N> |  | ||||||
| { |  | ||||||
|   iVector<decltype(peekIndex<Level>(arg._internal[0])),N> ret; |  | ||||||
|   for(int ii=0;ii<N;ii++){ |  | ||||||
|     ret._internal[ii]=peekIndex<Level>(arg._internal[ii]); |  | ||||||
|   } |  | ||||||
|   return ret; |  | ||||||
| } |  | ||||||
| template<int Level,class vtype,int N, typename std::enable_if< iScalar<vtype>::TensorLevel != Level >::type * =nullptr> inline  |  | ||||||
|   auto peekIndex(const iVector<vtype,N> &arg,int i) ->  iVector<decltype(peekIndex<Level>(arg._internal[0],i)),N> |  | ||||||
| { |  | ||||||
|   iVector<decltype(peekIndex<Level>(arg._internal[0],i)),N> ret; |  | ||||||
|   for(int ii=0;ii<N;ii++){ |  | ||||||
|     ret._internal[ii]=peekIndex<Level>(arg._internal[ii],i); |  | ||||||
|   } |  | ||||||
|   return ret; |  | ||||||
| } |  | ||||||
| template<int Level,class vtype,int N, typename std::enable_if< iScalar<vtype>::TensorLevel != Level >::type * =nullptr> inline  |  | ||||||
|   auto peekIndex(const iVector<vtype,N> &arg,int i,int j) ->  iVector<decltype(peekIndex<Level>(arg._internal[0],i,j)),N>  |  | ||||||
| { |  | ||||||
|   iVector<decltype(peekIndex<Level>(arg._internal[0],i,j)),N> ret; |  | ||||||
|   for(int ii=0;ii<N;ii++){ |  | ||||||
|     ret._internal[ii]=peekIndex<Level>(arg._internal[ii],i,j); |  | ||||||
|   } |  | ||||||
|   return ret; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // matrix |  | ||||||
| template<int Level,class vtype,int N, typename std::enable_if< iScalar<vtype>::TensorLevel != Level >::type * =nullptr> inline  |  | ||||||
| auto peekIndex(const iMatrix<vtype,N> &arg) ->   iMatrix<decltype(peekIndex<Level>(arg._internal[0][0])),N>  |  | ||||||
| { |  | ||||||
|   iMatrix<decltype(peekIndex<Level>(arg._internal[0][0])),N> ret; |  | ||||||
|   for(int ii=0;ii<N;ii++){ |  | ||||||
|   for(int jj=0;jj<N;jj++){ |  | ||||||
|     ret._internal[ii][jj]=peekIndex<Level>(arg._internal[ii][jj]);// Could avoid this because peeking a scalar is dumb |  | ||||||
|   }} |  | ||||||
|   return ret; |  | ||||||
| } |  | ||||||
| template<int Level,class vtype,int N, typename std::enable_if< iScalar<vtype>::TensorLevel != Level >::type * =nullptr> inline  |  | ||||||
|   auto peekIndex(const iMatrix<vtype,N> &arg,int i) ->   iMatrix<decltype(peekIndex<Level>(arg._internal[0][0],i)),N> |  | ||||||
| { |  | ||||||
|   iMatrix<decltype(peekIndex<Level>(arg._internal[0][0],i)),N> ret; |  | ||||||
|   for(int ii=0;ii<N;ii++){ |  | ||||||
|   for(int jj=0;jj<N;jj++){ |  | ||||||
|     ret._internal[ii][jj]=peekIndex<Level>(arg._internal[ii][jj],i); |  | ||||||
|   }} |  | ||||||
|   return ret; |  | ||||||
| } |  | ||||||
| template<int Level,class vtype,int N, typename std::enable_if< iScalar<vtype>::TensorLevel != Level >::type * =nullptr> inline  |  | ||||||
|   auto peekIndex(const iMatrix<vtype,N> &arg,int i,int j) ->   iMatrix<decltype(peekIndex<Level>(arg._internal[0][0],i,j)),N> |  | ||||||
| { |  | ||||||
|   iMatrix<decltype(peekIndex<Level>(arg._internal[0][0],i,j)),N> ret; |  | ||||||
|   for(int ii=0;ii<N;ii++){ |  | ||||||
|   for(int jj=0;jj<N;jj++){ |  | ||||||
|     ret._internal[ii][jj]=peekIndex<Level>(arg._internal[ii][jj],i,j); |  | ||||||
|   }} |  | ||||||
|   return ret; |  | ||||||
| } |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
|  |  | ||||||
| } |  | ||||||
| #endif |  | ||||||
| @@ -1,127 +0,0 @@ | |||||||
|     /************************************************************************************* |  | ||||||
|  |  | ||||||
|     Grid physics library, www.github.com/paboyle/Grid  |  | ||||||
|  |  | ||||||
|     Source file: ./lib/Old/Tensor_poke.h |  | ||||||
|  |  | ||||||
|     Copyright (C) 2015 |  | ||||||
|  |  | ||||||
| Author: Peter Boyle <paboyle@ph.ed.ac.uk> |  | ||||||
|  |  | ||||||
|     This program is free software; you can redistribute it and/or modify |  | ||||||
|     it under the terms of the GNU General Public License as published by |  | ||||||
|     the Free Software Foundation; either version 2 of the License, or |  | ||||||
|     (at your option) any later version. |  | ||||||
|  |  | ||||||
|     This program is distributed in the hope that it will be useful, |  | ||||||
|     but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
|     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the |  | ||||||
|     GNU General Public License for more details. |  | ||||||
|  |  | ||||||
|     You should have received a copy of the GNU General Public License along |  | ||||||
|     with this program; if not, write to the Free Software Foundation, Inc., |  | ||||||
|     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |  | ||||||
|  |  | ||||||
|     See the full license in the file "LICENSE" in the top level distribution directory |  | ||||||
|     *************************************************************************************/ |  | ||||||
|     /*  END LEGAL */ |  | ||||||
| #ifndef GRID_MATH_POKE_H |  | ||||||
| #define GRID_MATH_POKE_H |  | ||||||
| namespace Grid { |  | ||||||
|  |  | ||||||
| ////////////////////////////////////////////////////////////////////////////// |  | ||||||
| // Poke a specific index;  |  | ||||||
| ////////////////////////////////////////////////////////////////////////////// |  | ||||||
| #if 0 |  | ||||||
| // Scalar poke |  | ||||||
| template<int Level,class vtype,typename std::enable_if< iScalar<vtype>::TensorLevel == Level >::type * =nullptr> inline  |  | ||||||
|   void pokeIndex(iScalar<vtype> &ret, const iScalar<vtype> &arg) |  | ||||||
| { |  | ||||||
|   ret._internal = arg._internal; |  | ||||||
| } |  | ||||||
| // Vector poke, one index |  | ||||||
| template<int Level,class vtype,int N,typename std::enable_if< iScalar<vtype>::TensorLevel == Level >::type * =nullptr> inline  |  | ||||||
|   void pokeIndex(iVector<vtype,N> &ret, const iScalar<vtype> &arg,int i) |  | ||||||
| { |  | ||||||
|   ret._internal[i] = arg._internal; |  | ||||||
| } |  | ||||||
| //Matrix poke, two indices |  | ||||||
| template<int Level,class vtype,int N,typename std::enable_if< iScalar<vtype>::TensorLevel == Level >::type * =nullptr> inline  |  | ||||||
|   void pokeIndex(iMatrix<vtype,N> &ret, const iScalar<vtype> &arg,int i,int j) |  | ||||||
| { |  | ||||||
|   ret._internal[i][j] = arg._internal; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| ///////////// |  | ||||||
| // No match poke for scalar,vector,matrix must forward on either 0,1,2 args. Must have 9 routines with notvalue |  | ||||||
| ///////////// |  | ||||||
| // scalar |  | ||||||
| template<int Level,class vtype,typename std::enable_if< iScalar<vtype>::TensorLevel != Level >::type * =nullptr> inline  |  | ||||||
| void pokeIndex(iScalar<vtype> &ret, const iScalar<decltype(peekIndex<Level>(ret._internal))>  &arg) |  | ||||||
| { |  | ||||||
|   pokeIndex<Level>(ret._internal,arg._internal); |  | ||||||
| } |  | ||||||
| template<int Level,class vtype,typename std::enable_if< iScalar<vtype>::TensorLevel != Level >::type * =nullptr> inline  |  | ||||||
|   void pokeIndex(iScalar<vtype> &ret, const iScalar<decltype(peekIndex<Level>(ret._internal,0))> &arg, int i) |  | ||||||
| 		  |  | ||||||
| { |  | ||||||
|   pokeIndex<Level>(ret._internal,arg._internal,i); |  | ||||||
| } |  | ||||||
| template<int Level,class vtype,typename std::enable_if< iScalar<vtype>::TensorLevel != Level >::type * =nullptr> inline  |  | ||||||
|   void pokeIndex(iScalar<vtype> &ret, const iScalar<decltype(peekIndex<Level>(ret._internal,0,0))> &arg,int i,int j) |  | ||||||
| { |  | ||||||
|   pokeIndex<Level>(ret._internal,arg._internal,i,j); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Vector |  | ||||||
| template<int Level,class vtype,int N,typename std::enable_if< iScalar<vtype>::TensorLevel != Level >::type * =nullptr> inline  |  | ||||||
|   void pokeIndex(iVector<vtype,N> &ret, iVector<decltype(peekIndex<Level>(ret._internal)),N>  &arg) |  | ||||||
| { |  | ||||||
|   for(int ii=0;ii<N;ii++){ |  | ||||||
|     pokeIndex<Level>(ret._internal[ii],arg._internal[ii]); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| template<int Level,class vtype,int N,typename std::enable_if< iScalar<vtype>::TensorLevel != Level >::type * =nullptr> inline  |  | ||||||
|   void pokeIndex(iVector<vtype,N> &ret, const iVector<decltype(peekIndex<Level>(ret._internal,0)),N> &arg,int i) |  | ||||||
| { |  | ||||||
|   for(int ii=0;ii<N;ii++){ |  | ||||||
|     pokeIndex<Level>(ret._internal[ii],arg._internal[ii],i); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| template<int Level,class vtype,int N,typename std::enable_if< iScalar<vtype>::TensorLevel != Level >::type * =nullptr> inline  |  | ||||||
|   void pokeIndex(iVector<vtype,N> &ret, const iVector<decltype(peekIndex<Level>(ret._internal,0,0)),N> &arg,int i,int j) |  | ||||||
| { |  | ||||||
|   for(int ii=0;ii<N;ii++){ |  | ||||||
|     pokeIndex<Level>(ret._internal[ii],arg._internal[ii],i,j); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Matrix |  | ||||||
| template<int Level,class vtype,int N,typename std::enable_if< iScalar<vtype>::TensorLevel != Level >::type * =nullptr> inline  |  | ||||||
|   void pokeIndex(iMatrix<vtype,N> &ret, const iMatrix<decltype(peekIndex<Level>(ret._internal)),N> &arg)		  |  | ||||||
| { |  | ||||||
|   for(int ii=0;ii<N;ii++){ |  | ||||||
|   for(int jj=0;jj<N;jj++){ |  | ||||||
|     pokeIndex<Level>(ret._internal[ii][jj],arg._internal[ii][jj]); |  | ||||||
|   }} |  | ||||||
| } |  | ||||||
| template<int Level,class vtype,int N,typename std::enable_if< iScalar<vtype>::TensorLevel != Level >::type * =nullptr> inline  |  | ||||||
|   void pokeIndex(iMatrix<vtype,N> &ret, const iMatrix<decltype(peekIndex<Level>(ret._internal,0)),N> &arg,int i) |  | ||||||
| { |  | ||||||
|   for(int ii=0;ii<N;ii++){ |  | ||||||
|   for(int jj=0;jj<N;jj++){ |  | ||||||
|     pokeIndex<Level>(ret._internal[ii][jj],arg._internal[ii][jj],i); |  | ||||||
|   }} |  | ||||||
| } |  | ||||||
| template<int Level,class vtype,int N,typename std::enable_if< iScalar<vtype>::TensorLevel != Level >::type * =nullptr> inline  |  | ||||||
|   void pokeIndex(iMatrix<vtype,N> &ret, const iMatrix<decltype(peekIndex<Level>(ret._internal,0,0)),N> &arg, int i,int j) |  | ||||||
| { |  | ||||||
|   for(int ii=0;ii<N;ii++){ |  | ||||||
|   for(int jj=0;jj<N;jj++){ |  | ||||||
|     pokeIndex<Level>(ret._internal[ii][jj],arg._internal[ii][jj],i,j); |  | ||||||
|   }} |  | ||||||
| } |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| } |  | ||||||
| #endif |  | ||||||
| @@ -42,15 +42,14 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk> | |||||||
| #include <Grid/algorithms/iterative/ConjugateResidual.h> | #include <Grid/algorithms/iterative/ConjugateResidual.h> | ||||||
| #include <Grid/algorithms/iterative/NormalEquations.h> | #include <Grid/algorithms/iterative/NormalEquations.h> | ||||||
| #include <Grid/algorithms/iterative/SchurRedBlack.h> | #include <Grid/algorithms/iterative/SchurRedBlack.h> | ||||||
| 
 |  | ||||||
| #include <Grid/algorithms/iterative/ConjugateGradientMultiShift.h> | #include <Grid/algorithms/iterative/ConjugateGradientMultiShift.h> | ||||||
| #include <Grid/algorithms/iterative/ConjugateGradientMixedPrec.h> | #include <Grid/algorithms/iterative/ConjugateGradientMixedPrec.h> | ||||||
| 
 | 
 | ||||||
| // Lanczos support
 | // Lanczos support
 | ||||||
| #include <Grid/algorithms/iterative/MatrixUtils.h> | //#include <Grid/algorithms/iterative/MatrixUtils.h>
 | ||||||
| #include <Grid/algorithms/iterative/ImplicitlyRestartedLanczos.h> | #include <Grid/algorithms/iterative/ImplicitlyRestartedLanczos.h> | ||||||
| 
 |  | ||||||
| #include <Grid/algorithms/CoarsenedMatrix.h> | #include <Grid/algorithms/CoarsenedMatrix.h> | ||||||
|  | #include <Grid/algorithms/FFT.h> | ||||||
| 
 | 
 | ||||||
| // Eigen/lanczos
 | // Eigen/lanczos
 | ||||||
| // EigCg
 | // EigCg
 | ||||||
| @@ -267,8 +267,7 @@ namespace Grid { | |||||||
|       SimpleCompressor<siteVector> compressor; |       SimpleCompressor<siteVector> compressor; | ||||||
|       Stencil.HaloExchange(in,compressor); |       Stencil.HaloExchange(in,compressor); | ||||||
|  |  | ||||||
| PARALLEL_FOR_LOOP |       parallel_for(int ss=0;ss<Grid()->oSites();ss++){ | ||||||
|       for(int ss=0;ss<Grid()->oSites();ss++){ |  | ||||||
|         siteVector res = zero; |         siteVector res = zero; | ||||||
| 	siteVector nbr; | 	siteVector nbr; | ||||||
| 	int ptype; | 	int ptype; | ||||||
| @@ -282,7 +281,7 @@ PARALLEL_FOR_LOOP | |||||||
| 	  } else if(SE->_is_local) {  | 	  } else if(SE->_is_local) {  | ||||||
| 	    nbr = in._odata[SE->_offset]; | 	    nbr = in._odata[SE->_offset]; | ||||||
| 	  } else { | 	  } else { | ||||||
| 	    nbr = Stencil.comm_buf[SE->_offset]; | 	    nbr = Stencil.CommBuf()[SE->_offset]; | ||||||
| 	  } | 	  } | ||||||
| 	  res = res + A[point]._odata[ss]*nbr; | 	  res = res + A[point]._odata[ss]*nbr; | ||||||
| 	} | 	} | ||||||
| @@ -380,8 +379,7 @@ PARALLEL_FOR_LOOP | |||||||
| 	  Subspace.ProjectToSubspace(oProj,oblock); | 	  Subspace.ProjectToSubspace(oProj,oblock); | ||||||
| 	  //	  blockProject(iProj,iblock,Subspace.subspace); | 	  //	  blockProject(iProj,iblock,Subspace.subspace); | ||||||
| 	  //	  blockProject(oProj,oblock,Subspace.subspace); | 	  //	  blockProject(oProj,oblock,Subspace.subspace); | ||||||
| PARALLEL_FOR_LOOP | 	  parallel_for(int ss=0;ss<Grid()->oSites();ss++){ | ||||||
| 	  for(int ss=0;ss<Grid()->oSites();ss++){ |  | ||||||
| 	    for(int j=0;j<nbasis;j++){ | 	    for(int j=0;j<nbasis;j++){ | ||||||
| 	      if( disp!= 0 ) { | 	      if( disp!= 0 ) { | ||||||
| 		A[p]._odata[ss](j,i) = oProj._odata[ss](j); | 		A[p]._odata[ss](j,i) = oProj._odata[ss](j); | ||||||
| @@ -427,7 +425,7 @@ PARALLEL_FOR_LOOP | |||||||
| 	A[p]=zero; | 	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); |       Lattice<iScalar<CComplex> > val(Grid()); random(RNG,val); | ||||||
|  |  | ||||||
|       Complex one(1.0); |       Complex one(1.0); | ||||||
|   | |||||||
| @@ -30,8 +30,14 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk> | |||||||
| #define _GRID_FFT_H_ | #define _GRID_FFT_H_ | ||||||
| 
 | 
 | ||||||
| #ifdef HAVE_FFTW | #ifdef HAVE_FFTW | ||||||
|  | #ifdef USE_MKL | ||||||
|  | #include <fftw/fftw3.h> | ||||||
|  | #else | ||||||
| #include <fftw3.h> | #include <fftw3.h> | ||||||
| #endif | #endif | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| namespace Grid { | namespace Grid { | ||||||
| 
 | 
 | ||||||
|   template<class scalar> struct FFTW { }; |   template<class scalar> struct FFTW { }; | ||||||
| @@ -120,13 +126,14 @@ namespace Grid { | |||||||
|      |      | ||||||
|     double Flops(void) {return flops;} |     double Flops(void) {return flops;} | ||||||
|     double MFlops(void) {return flops/usec;} |     double MFlops(void) {return flops/usec;} | ||||||
|  |     double USec(void)   {return (double)usec;}     | ||||||
| 
 | 
 | ||||||
|     FFT ( GridCartesian * grid ) : |     FFT ( GridCartesian * grid ) : | ||||||
|       vgrid(grid), |     vgrid(grid), | ||||||
|       Nd(grid->_ndimension), |     Nd(grid->_ndimension), | ||||||
|       dimensions(grid->_fdimensions), |     dimensions(grid->_fdimensions), | ||||||
|       processors(grid->_processors), |     processors(grid->_processors), | ||||||
|       processor_coor(grid->_processor_coor) |     processor_coor(grid->_processor_coor) | ||||||
|     { |     { | ||||||
|       flops=0; |       flops=0; | ||||||
|       usec =0; |       usec =0; | ||||||
| @@ -139,10 +146,34 @@ namespace Grid { | |||||||
|     } |     } | ||||||
|      |      | ||||||
|     template<class vobj> |     template<class vobj> | ||||||
|     void FFT_dim(Lattice<vobj> &result,const Lattice<vobj> &source,int dim, int inverse){ |     void FFT_dim_mask(Lattice<vobj> &result,const Lattice<vobj> &source,std::vector<int> mask,int sign){ | ||||||
| 
 | 
 | ||||||
|       conformable(result._grid,vgrid); |       conformable(result._grid,vgrid); | ||||||
|       conformable(source._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 L = vgrid->_ldimensions[dim]; | ||||||
|       int G = vgrid->_fdimensions[dim]; |       int G = vgrid->_fdimensions[dim]; | ||||||
| @@ -159,113 +190,116 @@ namespace Grid { | |||||||
|       typedef typename vobj::scalar_object sobj; |       typedef typename vobj::scalar_object sobj; | ||||||
|       typedef typename sobj::scalar_type   scalar; |       typedef typename sobj::scalar_type   scalar; | ||||||
|        |        | ||||||
|       Lattice<vobj> ssource(vgrid); ssource =source; |       Lattice<sobj> pgbuf(&pencil_g); | ||||||
|       Lattice<sobj> pgsource(&pencil_g); |        | ||||||
|       Lattice<sobj> pgresult(&pencil_g); pgresult=zero; |  | ||||||
| 
 | 
 | ||||||
| #ifndef HAVE_FFTW	 |  | ||||||
|       assert(0); |  | ||||||
| #else  |  | ||||||
|       typedef typename FFTW<scalar>::FFTW_scalar FFTW_scalar; |       typedef typename FFTW<scalar>::FFTW_scalar FFTW_scalar; | ||||||
|       typedef typename FFTW<scalar>::FFTW_plan   FFTW_plan; |       typedef typename FFTW<scalar>::FFTW_plan   FFTW_plan; | ||||||
|        |        | ||||||
|       { |       int Ncomp = sizeof(sobj)/sizeof(scalar); | ||||||
| 	int Ncomp = sizeof(sobj)/sizeof(scalar); |       int Nlow  = 1; | ||||||
| 	int Nlow  = 1; |       for(int d=0;d<dim;d++){ | ||||||
| 	for(int d=0;d<dim;d++){ |         Nlow*=vgrid->_ldimensions[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; |  | ||||||
| 
 |  | ||||||
| 	 |  | ||||||
| 	int sign = FFTW_FORWARD; |  | ||||||
| 	if (inverse) sign = FFTW_BACKWARD; |  | ||||||
| 
 |  | ||||||
| 	FFTW_plan p; |  | ||||||
| 	{ |  | ||||||
| 	  FFTW_scalar *in = (FFTW_scalar *)&pgsource._odata[0]; |  | ||||||
| 	  FFTW_scalar *out= (FFTW_scalar *)&pgresult._odata[0]; |  | ||||||
| 	  p = FFTW<scalar>::fftw_plan_many_dft(rank,n,howmany, |  | ||||||
| 					       in,inembed, |  | ||||||
| 					       istride,idist, |  | ||||||
| 					       out,onembed, |  | ||||||
| 					       ostride, odist, |  | ||||||
| 					       sign,FFTW_ESTIMATE); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
|     std::vector<int> lcoor(Nd), gcoor(Nd); |  | ||||||
| 
 |  | ||||||
| 	// Barrel shift and collect global pencil
 |  | ||||||
| 	for(int p=0;p<processors[dim];p++) {  |  | ||||||
| 
 |  | ||||||
| 	  for(int idx=0;idx<sgrid->lSites();idx++) {  |  | ||||||
| 
 |  | ||||||
| 	     |  | ||||||
|     	    sgrid->LocalIndexToLocalCoor(idx,lcoor); |  | ||||||
| 
 |  | ||||||
| 	    sobj s; |  | ||||||
| 
 |  | ||||||
| 	    peekLocalSite(s,ssource,lcoor); |  | ||||||
| 
 |  | ||||||
| 	    lcoor[dim]+=p*L; |  | ||||||
| 	    |  | ||||||
| 	    pokeLocalSite(s,pgsource,lcoor); |  | ||||||
| 	  } |  | ||||||
| 
 |  | ||||||
| 	  ssource = Cshift(ssource,dim,L); |  | ||||||
| 	} |  | ||||||
| 	 |  | ||||||
| 	// Loop over orthog coords
 |  | ||||||
| 	int NN=pencil_g.lSites(); |  | ||||||
| 	GridStopWatch timer; |  | ||||||
| 	timer.Start(); |  | ||||||
| 
 |  | ||||||
| PARALLEL_FOR_LOOP |  | ||||||
| 	for(int idx=0;idx<NN;idx++) { |  | ||||||
| 	  pencil_g.LocalIndexToLocalCoor(idx,lcoor); |  | ||||||
| 
 |  | ||||||
| 	  if ( lcoor[dim] == 0 ) {  // restricts loop to plane at lcoor[dim]==0
 |  | ||||||
| 	    FFTW_scalar *in = (FFTW_scalar *)&pgsource._odata[idx]; |  | ||||||
| 	    FFTW_scalar *out= (FFTW_scalar *)&pgresult._odata[idx]; |  | ||||||
| 	    FFTW<scalar>::fftw_execute_dft(p,in,out); |  | ||||||
| 	  } |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
|         timer.Stop(); |  | ||||||
| 
 |  | ||||||
|           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; |  | ||||||
|         int pc = processor_coor[dim]; |  | ||||||
|         for(int idx=0;idx<sgrid->lSites();idx++) { |  | ||||||
| 	  sgrid->LocalIndexToLocalCoor(idx,lcoor); |  | ||||||
| 	  gcoor = lcoor; |  | ||||||
| 	  // extract the result
 |  | ||||||
| 	  sobj s; |  | ||||||
| 	  gcoor[dim] = lcoor[dim]+L*pc; |  | ||||||
| 	  peekLocalSite(s,pgresult,gcoor); |  | ||||||
| 	  pokeLocalSite(s,result,lcoor); |  | ||||||
| 	} |  | ||||||
|       	   |  | ||||||
| 	FFTW<scalar>::fftw_destroy_plan(p); |  | ||||||
|       } |       } | ||||||
|  |        | ||||||
|  |       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 | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     } |     } | ||||||
| 
 |  | ||||||
|   }; |   }; | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #endif | #endif | ||||||
| @@ -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 |     See the full license in the file "LICENSE" in the top level distribution directory | ||||||
|     *************************************************************************************/ |     *************************************************************************************/ | ||||||
|     /*  END LEGAL */ |     /*  END LEGAL */ | ||||||
| #include <Grid.h> | #include <Grid/GridCore.h> | ||||||
|  |  | ||||||
| namespace Grid { | namespace Grid { | ||||||
| double MultiShiftFunction::approx(double x) | double MultiShiftFunction::approx(double x) | ||||||
|   | |||||||
| @@ -20,7 +20,7 @@ | |||||||
| #include<iomanip> | #include<iomanip> | ||||||
| #include<cassert> | #include<cassert> | ||||||
|  |  | ||||||
| #include<algorithms/approx/Remez.h> | #include<Grid/algorithms/approx/Remez.h> | ||||||
|  |  | ||||||
| // Constructor | // Constructor | ||||||
| AlgRemez::AlgRemez(double lower, double upper, long precision)  | AlgRemez::AlgRemez(double lower, double upper, long precision)  | ||||||
|   | |||||||
							
								
								
									
										366
									
								
								lib/algorithms/iterative/BlockConjugateGradient.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										366
									
								
								lib/algorithms/iterative/BlockConjugateGradient.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,366 @@ | |||||||
|  | /************************************************************************************* | ||||||
|  |  | ||||||
|  | Grid physics library, www.github.com/paboyle/Grid | ||||||
|  |  | ||||||
|  | Source file: ./lib/algorithms/iterative/BlockConjugateGradient.h | ||||||
|  |  | ||||||
|  | Copyright (C) 2017 | ||||||
|  |  | ||||||
|  | Author: Azusa Yamaguchi <ayamaguc@staffmail.ed.ac.uk> | ||||||
|  | Author: Peter Boyle <paboyle@ph.ed.ac.uk> | ||||||
|  |  | ||||||
|  | This program is free software; you can redistribute it and/or modify | ||||||
|  | it under the terms of the GNU General Public License as published by | ||||||
|  | the Free Software Foundation; either version 2 of the License, or | ||||||
|  | (at your option) any later version. | ||||||
|  |  | ||||||
|  | This program is distributed in the hope that it will be useful, | ||||||
|  | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  | GNU General Public License for more details. | ||||||
|  |  | ||||||
|  | You should have received a copy of the GNU General Public License along | ||||||
|  | with this program; if not, write to the Free Software Foundation, Inc., | ||||||
|  | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||||||
|  |  | ||||||
|  | See the full license in the file "LICENSE" in the top level distribution | ||||||
|  | directory | ||||||
|  | *************************************************************************************/ | ||||||
|  | /*  END LEGAL */ | ||||||
|  | #ifndef GRID_BLOCK_CONJUGATE_GRADIENT_H | ||||||
|  | #define GRID_BLOCK_CONJUGATE_GRADIENT_H | ||||||
|  |  | ||||||
|  |  | ||||||
|  | namespace Grid { | ||||||
|  |  | ||||||
|  | ////////////////////////////////////////////////////////////////////////// | ||||||
|  | // Block conjugate gradient. Dimension zero should be the block direction | ||||||
|  | ////////////////////////////////////////////////////////////////////////// | ||||||
|  | template <class Field> | ||||||
|  | class BlockConjugateGradient : public OperatorFunction<Field> { | ||||||
|  |  public: | ||||||
|  |  | ||||||
|  |   typedef typename Field::scalar_type scomplex; | ||||||
|  |  | ||||||
|  |   const int blockDim = 0; | ||||||
|  |  | ||||||
|  |   int Nblock; | ||||||
|  |   bool ErrorOnNoConverge;  // throw an assert when the CG fails to converge. | ||||||
|  |                            // Defaults true. | ||||||
|  |   RealD Tolerance; | ||||||
|  |   Integer MaxIterations; | ||||||
|  |   Integer IterationsToComplete; //Number of iterations the CG took to finish. Filled in upon completion | ||||||
|  |    | ||||||
|  |   BlockConjugateGradient(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)  | ||||||
|  | { | ||||||
|  |   int Orthog = 0; // First dimension is block dim | ||||||
|  |   Nblock = Src._grid->_fdimensions[Orthog]; | ||||||
|  |  | ||||||
|  |   std::cout<<GridLogMessage<<" Block Conjugate Gradient : Orthog "<<Orthog<<" Nblock "<<Nblock<<std::endl; | ||||||
|  |  | ||||||
|  |   Psi.checkerboard = Src.checkerboard; | ||||||
|  |   conformable(Psi, Src); | ||||||
|  |  | ||||||
|  |   Field P(Src); | ||||||
|  |   Field AP(Src); | ||||||
|  |   Field R(Src); | ||||||
|  |    | ||||||
|  |   Eigen::MatrixXcd m_pAp    = Eigen::MatrixXcd::Identity(Nblock,Nblock); | ||||||
|  |   Eigen::MatrixXcd m_pAp_inv= Eigen::MatrixXcd::Identity(Nblock,Nblock); | ||||||
|  |   Eigen::MatrixXcd m_rr     = Eigen::MatrixXcd::Zero(Nblock,Nblock); | ||||||
|  |   Eigen::MatrixXcd m_rr_inv = Eigen::MatrixXcd::Zero(Nblock,Nblock); | ||||||
|  |  | ||||||
|  |   Eigen::MatrixXcd m_alpha      = Eigen::MatrixXcd::Zero(Nblock,Nblock); | ||||||
|  |   Eigen::MatrixXcd m_beta   = Eigen::MatrixXcd::Zero(Nblock,Nblock); | ||||||
|  |  | ||||||
|  |   // Initial residual computation & set up | ||||||
|  |   std::vector<RealD> residuals(Nblock); | ||||||
|  |   std::vector<RealD> ssq(Nblock); | ||||||
|  |  | ||||||
|  |   sliceNorm(ssq,Src,Orthog); | ||||||
|  |   RealD sssum=0; | ||||||
|  |   for(int b=0;b<Nblock;b++) sssum+=ssq[b]; | ||||||
|  |  | ||||||
|  |   sliceNorm(residuals,Src,Orthog); | ||||||
|  |   for(int b=0;b<Nblock;b++){ assert(std::isnan(residuals[b])==0); } | ||||||
|  |  | ||||||
|  |   sliceNorm(residuals,Psi,Orthog); | ||||||
|  |   for(int b=0;b<Nblock;b++){ assert(std::isnan(residuals[b])==0); } | ||||||
|  |  | ||||||
|  |   // Initial search dir is guess | ||||||
|  |   Linop.HermOp(Psi, AP); | ||||||
|  |    | ||||||
|  |  | ||||||
|  |   /************************************************************************ | ||||||
|  |    * Block conjugate gradient (Stephen Pickles, thesis 1995, pp 71, O Leary 1980) | ||||||
|  |    ************************************************************************ | ||||||
|  |    * O'Leary : R = B - A X | ||||||
|  |    * O'Leary : P = M R ; preconditioner M = 1 | ||||||
|  |    * O'Leary : alpha = PAP^{-1} RMR | ||||||
|  |    * O'Leary : beta  = RMR^{-1}_old RMR_new | ||||||
|  |    * O'Leary : X=X+Palpha | ||||||
|  |    * O'Leary : R_new=R_old-AP alpha | ||||||
|  |    * O'Leary : P=MR_new+P beta | ||||||
|  |    */ | ||||||
|  |  | ||||||
|  |   R = Src - AP;   | ||||||
|  |   P = R; | ||||||
|  |   sliceInnerProductMatrix(m_rr,R,R,Orthog); | ||||||
|  |  | ||||||
|  |   GridStopWatch sliceInnerTimer; | ||||||
|  |   GridStopWatch sliceMaddTimer; | ||||||
|  |   GridStopWatch MatrixTimer; | ||||||
|  |   GridStopWatch SolverTimer; | ||||||
|  |   SolverTimer.Start(); | ||||||
|  |  | ||||||
|  |   int k; | ||||||
|  |   for (k = 1; k <= MaxIterations; k++) { | ||||||
|  |  | ||||||
|  |     RealD rrsum=0; | ||||||
|  |     for(int b=0;b<Nblock;b++) rrsum+=real(m_rr(b,b)); | ||||||
|  |  | ||||||
|  |     std::cout << GridLogIterative << "\titeration "<<k<<" rr_sum "<<rrsum<<" ssq_sum "<< sssum | ||||||
|  | 	      <<" / "<<std::sqrt(rrsum/sssum) <<std::endl; | ||||||
|  |  | ||||||
|  |     MatrixTimer.Start(); | ||||||
|  |     Linop.HermOp(P, AP); | ||||||
|  |     MatrixTimer.Stop(); | ||||||
|  |  | ||||||
|  |     // Alpha | ||||||
|  |     sliceInnerTimer.Start(); | ||||||
|  |     sliceInnerProductMatrix(m_pAp,P,AP,Orthog); | ||||||
|  |     sliceInnerTimer.Stop(); | ||||||
|  |     m_pAp_inv = m_pAp.inverse(); | ||||||
|  |     m_alpha   = m_pAp_inv * m_rr ; | ||||||
|  |  | ||||||
|  |     // Psi, R update | ||||||
|  |     sliceMaddTimer.Start(); | ||||||
|  |     sliceMaddMatrix(Psi,m_alpha, P,Psi,Orthog);     // add alpha *  P to psi | ||||||
|  |     sliceMaddMatrix(R  ,m_alpha,AP,  R,Orthog,-1.0);// sub alpha * AP to resid | ||||||
|  |     sliceMaddTimer.Stop(); | ||||||
|  |  | ||||||
|  |     // Beta | ||||||
|  |     m_rr_inv = m_rr.inverse(); | ||||||
|  |     sliceInnerTimer.Start(); | ||||||
|  |     sliceInnerProductMatrix(m_rr,R,R,Orthog); | ||||||
|  |     sliceInnerTimer.Stop(); | ||||||
|  |     m_beta = m_rr_inv *m_rr; | ||||||
|  |  | ||||||
|  |     // Search update | ||||||
|  |     sliceMaddTimer.Start(); | ||||||
|  |     sliceMaddMatrix(AP,m_beta,P,R,Orthog); | ||||||
|  |     sliceMaddTimer.Stop(); | ||||||
|  |     P= AP; | ||||||
|  |  | ||||||
|  |     /********************* | ||||||
|  |      * convergence monitor | ||||||
|  |      ********************* | ||||||
|  |      */ | ||||||
|  |     RealD max_resid=0; | ||||||
|  |     for(int b=0;b<Nblock;b++){ | ||||||
|  |       RealD rr = real(m_rr(b,b))/ssq[b]; | ||||||
|  |       if ( rr > max_resid ) max_resid = rr; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     if ( max_resid < Tolerance*Tolerance ) {  | ||||||
|  |  | ||||||
|  |       SolverTimer.Stop(); | ||||||
|  |  | ||||||
|  |       std::cout << GridLogMessage<<"BlockCG converged in "<<k<<" iterations"<<std::endl; | ||||||
|  |       for(int b=0;b<Nblock;b++){ | ||||||
|  | 	std::cout << GridLogMessage<< "\t\tblock "<<b<<" resid "<< std::sqrt(real(m_rr(b,b))/ssq[b])<<std::endl; | ||||||
|  |       } | ||||||
|  |       std::cout << GridLogMessage<<"\tMax residual is "<<std::sqrt(max_resid)<<std::endl; | ||||||
|  |  | ||||||
|  |       Linop.HermOp(Psi, AP); | ||||||
|  |       AP = AP-Src; | ||||||
|  |       std::cout << GridLogMessage <<"\tTrue residual is " << std::sqrt(norm2(AP)/norm2(Src)) <<std::endl; | ||||||
|  |  | ||||||
|  |       std::cout << GridLogMessage << "Time Breakdown "<<std::endl; | ||||||
|  |       std::cout << GridLogMessage << "\tElapsed    " << SolverTimer.Elapsed()     <<std::endl; | ||||||
|  |       std::cout << GridLogMessage << "\tMatrix     " << MatrixTimer.Elapsed()     <<std::endl; | ||||||
|  |       std::cout << GridLogMessage << "\tInnerProd  " << sliceInnerTimer.Elapsed() <<std::endl; | ||||||
|  |       std::cout << GridLogMessage << "\tMaddMatrix " << sliceMaddTimer.Elapsed()  <<std::endl; | ||||||
|  | 	     | ||||||
|  |       IterationsToComplete = k; | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   } | ||||||
|  |   std::cout << GridLogMessage << "BlockConjugateGradient did NOT converge" << std::endl; | ||||||
|  |  | ||||||
|  |   if (ErrorOnNoConverge) assert(0); | ||||||
|  |   IterationsToComplete = k; | ||||||
|  | } | ||||||
|  | }; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | ////////////////////////////////////////////////////////////////////////// | ||||||
|  | // multiRHS conjugate gradient. Dimension zero should be the block direction | ||||||
|  | ////////////////////////////////////////////////////////////////////////// | ||||||
|  | template <class Field> | ||||||
|  | class MultiRHSConjugateGradient : public OperatorFunction<Field> { | ||||||
|  |  public: | ||||||
|  |  | ||||||
|  |   typedef typename Field::scalar_type scomplex; | ||||||
|  |  | ||||||
|  |   const int blockDim = 0; | ||||||
|  |  | ||||||
|  |   int Nblock; | ||||||
|  |   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 | ||||||
|  |    | ||||||
|  |    MultiRHSConjugateGradient(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)  | ||||||
|  | { | ||||||
|  |   int Orthog = 0; // First dimension is block dim | ||||||
|  |   Nblock = Src._grid->_fdimensions[Orthog]; | ||||||
|  |  | ||||||
|  |   std::cout<<GridLogMessage<<"MultiRHS Conjugate Gradient : Orthog "<<Orthog<<" Nblock "<<Nblock<<std::endl; | ||||||
|  |  | ||||||
|  |   Psi.checkerboard = Src.checkerboard; | ||||||
|  |   conformable(Psi, Src); | ||||||
|  |  | ||||||
|  |   Field P(Src); | ||||||
|  |   Field AP(Src); | ||||||
|  |   Field R(Src); | ||||||
|  |    | ||||||
|  |   std::vector<ComplexD> v_pAp(Nblock); | ||||||
|  |   std::vector<RealD> v_rr (Nblock); | ||||||
|  |   std::vector<RealD> v_rr_inv(Nblock); | ||||||
|  |   std::vector<RealD> v_alpha(Nblock); | ||||||
|  |   std::vector<RealD> v_beta(Nblock); | ||||||
|  |  | ||||||
|  |   // Initial residual computation & set up | ||||||
|  |   std::vector<RealD> residuals(Nblock); | ||||||
|  |   std::vector<RealD> ssq(Nblock); | ||||||
|  |  | ||||||
|  |   sliceNorm(ssq,Src,Orthog); | ||||||
|  |   RealD sssum=0; | ||||||
|  |   for(int b=0;b<Nblock;b++) sssum+=ssq[b]; | ||||||
|  |  | ||||||
|  |   sliceNorm(residuals,Src,Orthog); | ||||||
|  |   for(int b=0;b<Nblock;b++){ assert(std::isnan(residuals[b])==0); } | ||||||
|  |  | ||||||
|  |   sliceNorm(residuals,Psi,Orthog); | ||||||
|  |   for(int b=0;b<Nblock;b++){ assert(std::isnan(residuals[b])==0); } | ||||||
|  |  | ||||||
|  |   // Initial search dir is guess | ||||||
|  |   Linop.HermOp(Psi, AP); | ||||||
|  |  | ||||||
|  |   R = Src - AP;   | ||||||
|  |   P = R; | ||||||
|  |   sliceNorm(v_rr,R,Orthog); | ||||||
|  |  | ||||||
|  |   GridStopWatch sliceInnerTimer; | ||||||
|  |   GridStopWatch sliceMaddTimer; | ||||||
|  |   GridStopWatch sliceNormTimer; | ||||||
|  |   GridStopWatch MatrixTimer; | ||||||
|  |   GridStopWatch SolverTimer; | ||||||
|  |  | ||||||
|  |   SolverTimer.Start(); | ||||||
|  |   int k; | ||||||
|  |   for (k = 1; k <= MaxIterations; k++) { | ||||||
|  |  | ||||||
|  |     RealD rrsum=0; | ||||||
|  |     for(int b=0;b<Nblock;b++) rrsum+=real(v_rr[b]); | ||||||
|  |  | ||||||
|  |     std::cout << GridLogIterative << "\titeration "<<k<<" rr_sum "<<rrsum<<" ssq_sum "<< sssum | ||||||
|  | 	      <<" / "<<std::sqrt(rrsum/sssum) <<std::endl; | ||||||
|  |  | ||||||
|  |     MatrixTimer.Start(); | ||||||
|  |     Linop.HermOp(P, AP); | ||||||
|  |     MatrixTimer.Stop(); | ||||||
|  |  | ||||||
|  |     // Alpha | ||||||
|  |     //    sliceInnerProductVectorTest(v_pAp_test,P,AP,Orthog); | ||||||
|  |     sliceInnerTimer.Start(); | ||||||
|  |     sliceInnerProductVector(v_pAp,P,AP,Orthog); | ||||||
|  |     sliceInnerTimer.Stop(); | ||||||
|  |     for(int b=0;b<Nblock;b++){ | ||||||
|  |       //      std::cout << " "<< v_pAp[b]<<" "<< v_pAp_test[b]<<std::endl; | ||||||
|  |       v_alpha[b] = v_rr[b]/real(v_pAp[b]); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Psi, R update | ||||||
|  |     sliceMaddTimer.Start(); | ||||||
|  |     sliceMaddVector(Psi,v_alpha, P,Psi,Orthog);     // add alpha *  P to psi | ||||||
|  |     sliceMaddVector(R  ,v_alpha,AP,  R,Orthog,-1.0);// sub alpha * AP to resid | ||||||
|  |     sliceMaddTimer.Stop(); | ||||||
|  |  | ||||||
|  |     // Beta | ||||||
|  |     for(int b=0;b<Nblock;b++){ | ||||||
|  |       v_rr_inv[b] = 1.0/v_rr[b]; | ||||||
|  |     } | ||||||
|  |     sliceNormTimer.Start(); | ||||||
|  |     sliceNorm(v_rr,R,Orthog); | ||||||
|  |     sliceNormTimer.Stop(); | ||||||
|  |     for(int b=0;b<Nblock;b++){ | ||||||
|  |       v_beta[b] = v_rr_inv[b] *v_rr[b]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Search update | ||||||
|  |     sliceMaddTimer.Start(); | ||||||
|  |     sliceMaddVector(P,v_beta,P,R,Orthog); | ||||||
|  |     sliceMaddTimer.Stop(); | ||||||
|  |  | ||||||
|  |     /********************* | ||||||
|  |      * convergence monitor | ||||||
|  |      ********************* | ||||||
|  |      */ | ||||||
|  |     RealD max_resid=0; | ||||||
|  |     for(int b=0;b<Nblock;b++){ | ||||||
|  |       RealD rr = v_rr[b]/ssq[b]; | ||||||
|  |       if ( rr > max_resid ) max_resid = rr; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     if ( max_resid < Tolerance*Tolerance ) {  | ||||||
|  |  | ||||||
|  |       SolverTimer.Stop(); | ||||||
|  |  | ||||||
|  |       std::cout << GridLogMessage<<"MultiRHS solver converged in " <<k<<" iterations"<<std::endl; | ||||||
|  |       for(int b=0;b<Nblock;b++){ | ||||||
|  | 	std::cout << GridLogMessage<< "\t\tBlock "<<b<<" resid "<< std::sqrt(v_rr[b]/ssq[b])<<std::endl; | ||||||
|  |       } | ||||||
|  |       std::cout << GridLogMessage<<"\tMax residual is "<<std::sqrt(max_resid)<<std::endl; | ||||||
|  |  | ||||||
|  |       Linop.HermOp(Psi, AP); | ||||||
|  |       AP = AP-Src; | ||||||
|  |       std::cout <<GridLogMessage << "\tTrue residual is " << std::sqrt(norm2(AP)/norm2(Src)) <<std::endl; | ||||||
|  |  | ||||||
|  |       std::cout << GridLogMessage << "Time Breakdown "<<std::endl; | ||||||
|  |       std::cout << GridLogMessage << "\tElapsed    " << SolverTimer.Elapsed()     <<std::endl; | ||||||
|  |       std::cout << GridLogMessage << "\tMatrix     " << MatrixTimer.Elapsed()     <<std::endl; | ||||||
|  |       std::cout << GridLogMessage << "\tInnerProd  " << sliceInnerTimer.Elapsed() <<std::endl; | ||||||
|  |       std::cout << GridLogMessage << "\tNorm       " << sliceNormTimer.Elapsed() <<std::endl; | ||||||
|  |       std::cout << GridLogMessage << "\tMaddMatrix " << sliceMaddTimer.Elapsed()  <<std::endl; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |       IterationsToComplete = k; | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   } | ||||||
|  |   std::cout << GridLogMessage << "MultiRHSConjugateGradient did NOT converge" << std::endl; | ||||||
|  |  | ||||||
|  |   if (ErrorOnNoConverge) assert(0); | ||||||
|  |   IterationsToComplete = k; | ||||||
|  | } | ||||||
|  | }; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | } | ||||||
|  | #endif | ||||||
| @@ -45,6 +45,8 @@ class ConjugateGradient : public OperatorFunction<Field> { | |||||||
|                            // Defaults true. |                            // Defaults true. | ||||||
|   RealD Tolerance; |   RealD Tolerance; | ||||||
|   Integer MaxIterations; |   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) |   ConjugateGradient(RealD tol, Integer maxit, bool err_on_no_conv = true) | ||||||
|       : Tolerance(tol), |       : Tolerance(tol), | ||||||
|         MaxIterations(maxit), |         MaxIterations(maxit), | ||||||
| @@ -76,18 +78,12 @@ class ConjugateGradient : public OperatorFunction<Field> { | |||||||
|     cp = a; |     cp = a; | ||||||
|     ssq = norm2(src); |     ssq = norm2(src); | ||||||
|  |  | ||||||
|     std::cout << GridLogIterative << std::setprecision(4) |     std::cout << GridLogIterative << std::setprecision(4) << "ConjugateGradient: guess " << guess << std::endl; | ||||||
|               << "ConjugateGradient: guess " << guess << std::endl; |     std::cout << GridLogIterative << std::setprecision(4) << "ConjugateGradient:   src " << ssq << std::endl; | ||||||
|     std::cout << GridLogIterative << std::setprecision(4) |     std::cout << GridLogIterative << std::setprecision(4) << "ConjugateGradient:    mp " << d << std::endl; | ||||||
|               << "ConjugateGradient:   src " << ssq << std::endl; |     std::cout << GridLogIterative << std::setprecision(4) << "ConjugateGradient:   mmp " << b << std::endl; | ||||||
|     std::cout << GridLogIterative << std::setprecision(4) |     std::cout << GridLogIterative << std::setprecision(4) << "ConjugateGradient:  cp,r " << cp << std::endl; | ||||||
|               << "ConjugateGradient:    mp " << d << std::endl; |     std::cout << GridLogIterative << std::setprecision(4) << "ConjugateGradient:     p " << a << 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; |     RealD rsq = Tolerance * Tolerance * ssq; | ||||||
|  |  | ||||||
| @@ -97,8 +93,7 @@ class ConjugateGradient : public OperatorFunction<Field> { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     std::cout << GridLogIterative << std::setprecision(4) |     std::cout << GridLogIterative << std::setprecision(4) | ||||||
|               << "ConjugateGradient: k=0 residual " << cp << " target " << rsq |               << "ConjugateGradient: k=0 residual " << cp << " target " << rsq << std::endl; | ||||||
|               << std::endl; |  | ||||||
|  |  | ||||||
|     GridStopWatch LinalgTimer; |     GridStopWatch LinalgTimer; | ||||||
|     GridStopWatch MatrixTimer; |     GridStopWatch MatrixTimer; | ||||||
| @@ -143,18 +138,19 @@ class ConjugateGradient : public OperatorFunction<Field> { | |||||||
|         RealD resnorm = sqrt(norm2(p)); |         RealD resnorm = sqrt(norm2(p)); | ||||||
|         RealD true_residual = resnorm / srcnorm; |         RealD true_residual = resnorm / srcnorm; | ||||||
|  |  | ||||||
|         std::cout << GridLogMessage |         std::cout << GridLogMessage << "ConjugateGradient Converged on iteration " << k << std::endl; | ||||||
|                   << "ConjugateGradient: Converged on iteration " << k << std::endl; |         std::cout << GridLogMessage << "\tComputed residual " << sqrt(cp / ssq)<<std::endl; | ||||||
|         std::cout << GridLogMessage << "Computed residual " << sqrt(cp / ssq) | 	std::cout << GridLogMessage << "\tTrue residual " << true_residual<<std::endl; | ||||||
|                   << " true residual " << true_residual << " target " | 	std::cout << GridLogMessage << "\tTarget " << Tolerance << std::endl; | ||||||
|                   << 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 < 1000.0); |         std::cout << GridLogMessage << "Time breakdown "<<std::endl; | ||||||
|  | 	std::cout << GridLogMessage << "\tElapsed    " << SolverTimer.Elapsed() <<std::endl; | ||||||
|  | 	std::cout << GridLogMessage << "\tMatrix     " << MatrixTimer.Elapsed() <<std::endl; | ||||||
|  | 	std::cout << GridLogMessage << "\tLinalg     " << LinalgTimer.Elapsed() <<std::endl; | ||||||
|  |  | ||||||
|  |         if (ErrorOnNoConverge) assert(true_residual / Tolerance < 10000.0); | ||||||
|  |  | ||||||
|  | 	IterationsToComplete = k;	 | ||||||
|  |  | ||||||
|         return; |         return; | ||||||
|       } |       } | ||||||
| @@ -162,6 +158,7 @@ class ConjugateGradient : public OperatorFunction<Field> { | |||||||
|     std::cout << GridLogMessage << "ConjugateGradient did NOT converge" |     std::cout << GridLogMessage << "ConjugateGradient did NOT converge" | ||||||
|               << std::endl; |               << std::endl; | ||||||
|     if (ErrorOnNoConverge) assert(0); |     if (ErrorOnNoConverge) assert(0); | ||||||
|  |     IterationsToComplete = k; | ||||||
|   } |   } | ||||||
| }; | }; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -35,6 +35,7 @@ namespace Grid { | |||||||
|   class MixedPrecisionConjugateGradient : public LinearFunction<FieldD> { |   class MixedPrecisionConjugateGradient : public LinearFunction<FieldD> { | ||||||
|   public:                                                 |   public:                                                 | ||||||
|     RealD   Tolerance; |     RealD   Tolerance; | ||||||
|  |     RealD   InnerTolerance; //Initial tolerance for inner CG. Defaults to Tolerance but can be changed | ||||||
|     Integer MaxInnerIterations; |     Integer MaxInnerIterations; | ||||||
|     Integer MaxOuterIterations; |     Integer MaxOuterIterations; | ||||||
|     GridBase* SinglePrecGrid; //Grid for single-precision fields |     GridBase* SinglePrecGrid; //Grid for single-precision fields | ||||||
| @@ -42,12 +43,16 @@ namespace Grid { | |||||||
|     LinearOperatorBase<FieldF> &Linop_f; |     LinearOperatorBase<FieldF> &Linop_f; | ||||||
|     LinearOperatorBase<FieldD> &Linop_d; |     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 |     //Option to speed up *inner single precision* solves using a LinearFunction that produces a guess | ||||||
|     LinearFunction<FieldF> *guesser; |     LinearFunction<FieldF> *guesser; | ||||||
|      |      | ||||||
|     MixedPrecisionConjugateGradient(RealD tol, Integer maxinnerit, Integer maxouterit, GridBase* _sp_grid, LinearOperatorBase<FieldF> &_Linop_f, LinearOperatorBase<FieldD> &_Linop_d) : |     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), |       Linop_f(_Linop_f), Linop_d(_Linop_d), | ||||||
|       Tolerance(tol), MaxInnerIterations(maxinnerit), MaxOuterIterations(maxouterit), SinglePrecGrid(_sp_grid), |       Tolerance(tol), InnerTolerance(tol), MaxInnerIterations(maxinnerit), MaxOuterIterations(maxouterit), SinglePrecGrid(_sp_grid), | ||||||
|       OuterLoopNormMult(100.), guesser(NULL){ }; |       OuterLoopNormMult(100.), guesser(NULL){ }; | ||||||
|  |  | ||||||
|     void useGuesser(LinearFunction<FieldF> &g){ |     void useGuesser(LinearFunction<FieldF> &g){ | ||||||
| @@ -55,6 +60,8 @@ namespace Grid { | |||||||
|     } |     } | ||||||
|    |    | ||||||
|     void operator() (const FieldD &src_d_in, FieldD &sol_d){ |     void operator() (const FieldD &src_d_in, FieldD &sol_d){ | ||||||
|  |       TotalInnerIterations = 0; | ||||||
|  | 	 | ||||||
|       GridStopWatch TotalTimer; |       GridStopWatch TotalTimer; | ||||||
|       TotalTimer.Start(); |       TotalTimer.Start(); | ||||||
|      |      | ||||||
| @@ -74,7 +81,7 @@ namespace Grid { | |||||||
|       FieldD src_d(DoublePrecGrid); |       FieldD src_d(DoublePrecGrid); | ||||||
|       src_d = src_d_in; //source for next inner iteration, computed from residual during operation |       src_d = src_d_in; //source for next inner iteration, computed from residual during operation | ||||||
|      |      | ||||||
|       RealD inner_tol = Tolerance; |       RealD inner_tol = InnerTolerance; | ||||||
|      |      | ||||||
|       FieldF src_f(SinglePrecGrid); |       FieldF src_f(SinglePrecGrid); | ||||||
|       src_f.checkerboard = cb; |       src_f.checkerboard = cb; | ||||||
| @@ -89,7 +96,9 @@ namespace Grid { | |||||||
|  |  | ||||||
|       GridStopWatch PrecChangeTimer; |       GridStopWatch PrecChangeTimer; | ||||||
|      |      | ||||||
|       for(Integer outer_iter = 0; outer_iter < MaxOuterIterations; outer_iter++){ |       Integer &outer_iter = TotalOuterIterations; //so it will be equal to the final iteration count | ||||||
|  |        | ||||||
|  |       for(outer_iter = 0; outer_iter < MaxOuterIterations; outer_iter++){ | ||||||
| 	//Compute double precision rsd and also new RHS vector. | 	//Compute double precision rsd and also new RHS vector. | ||||||
| 	Linop_d.HermOp(sol_d, tmp_d); | 	Linop_d.HermOp(sol_d, tmp_d); | ||||||
| 	RealD norm = axpy_norm(src_d, -1., tmp_d, src_d_in); //src_d is residual vector | 	RealD norm = axpy_norm(src_d, -1., tmp_d, src_d_in); //src_d is residual vector | ||||||
| @@ -117,6 +126,7 @@ namespace Grid { | |||||||
| 	InnerCGtimer.Start(); | 	InnerCGtimer.Start(); | ||||||
| 	CG_f(Linop_f, src_f, sol_f); | 	CG_f(Linop_f, src_f, sol_f); | ||||||
| 	InnerCGtimer.Stop(); | 	InnerCGtimer.Stop(); | ||||||
|  | 	TotalInnerIterations += CG_f.IterationsToComplete; | ||||||
|        |        | ||||||
| 	//Convert sol back to double and add to double prec solution | 	//Convert sol back to double and add to double prec solution | ||||||
| 	PrecChangeTimer.Start(); | 	PrecChangeTimer.Start(); | ||||||
| @@ -131,9 +141,11 @@ namespace Grid { | |||||||
|      |      | ||||||
|       ConjugateGradient<FieldD> CG_d(Tolerance, MaxInnerIterations); |       ConjugateGradient<FieldD> CG_d(Tolerance, MaxInnerIterations); | ||||||
|       CG_d(Linop_d, src_d_in, sol_d); |       CG_d(Linop_d, src_d_in, sol_d); | ||||||
|  |       TotalFinalStepIterations = CG_d.IterationsToComplete; | ||||||
|  |  | ||||||
|       TotalTimer.Stop(); |       TotalTimer.Stop(); | ||||||
|       std::cout<<GridLogMessage<<"MixedPrecisionConjugateGradient: Total " << TotalTimer.Elapsed() << " Precision change " << PrecChangeTimer.Elapsed() << " Inner CG total " << InnerCGtimer.Elapsed() << std::endl; |       std::cout<<GridLogMessage<<"MixedPrecisionConjugateGradient: Inner CG iterations " << TotalInnerIterations << " Restarts " << TotalOuterIterations << " Final CG iterations " << TotalFinalStepIterations << std::endl; | ||||||
|  |       std::cout<<GridLogMessage<<"MixedPrecisionConjugateGradient: Total time " << TotalTimer.Elapsed() << " Precision change " << PrecChangeTimer.Elapsed() << " Inner CG total " << InnerCGtimer.Elapsed() << std::endl; | ||||||
|     } |     } | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -30,11 +30,17 @@ Author: paboyle <paboyle@ph.ed.ac.uk> | |||||||
| #define GRID_IRL_H | #define GRID_IRL_H | ||||||
|  |  | ||||||
| #include <string.h> //memset | #include <string.h> //memset | ||||||
|  |  | ||||||
| #ifdef USE_LAPACK | #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 | #endif | ||||||
| #include "DenseMatrix.h" |  | ||||||
| #include "EigenSort.h" | #include <Grid/algorithms/densematrix/DenseMatrix.h> | ||||||
|  | #include <Grid/algorithms/iterative/EigenSort.h> | ||||||
|  |  | ||||||
| namespace Grid { | namespace Grid { | ||||||
|  |  | ||||||
| @@ -1076,16 +1082,14 @@ say con = 2 | |||||||
| **/ | **/ | ||||||
|  |  | ||||||
| template<class T> | template<class T> | ||||||
| static void Lock(DenseMatrix<T> &H, 	///Hess mtx	 | static void Lock(DenseMatrix<T> &H, 	// Hess mtx	 | ||||||
| 		 DenseMatrix<T> &Q, 	///Lock Transform | 		 DenseMatrix<T> &Q, 	// Lock Transform | ||||||
| 		 T val, 		///value to be locked | 		 T val, 		// value to be locked | ||||||
| 		 int con, 	///number already locked | 		 int con, 	// number already locked | ||||||
| 		 RealD small, | 		 RealD small, | ||||||
| 		 int dfg, | 		 int dfg, | ||||||
| 		 bool herm) | 		 bool herm) | ||||||
| {	 | {	 | ||||||
|  |  | ||||||
|  |  | ||||||
|   //ForceTridiagonal(H); |   //ForceTridiagonal(H); | ||||||
|  |  | ||||||
|   int M = H.dim; |   int M = H.dim; | ||||||
| @@ -1118,7 +1122,6 @@ static void Lock(DenseMatrix<T> &H, 	///Hess mtx | |||||||
|   AH = Hermitian(QQ)*AH; |   AH = Hermitian(QQ)*AH; | ||||||
|   AH = AH*QQ; |   AH = AH*QQ; | ||||||
|  |  | ||||||
|  |  | ||||||
|   for(int i=con;i<M;i++){ |   for(int i=con;i<M;i++){ | ||||||
|     for(int j=con;j<M;j++){ |     for(int j=con;j<M;j++){ | ||||||
|       Q[i][j]=QQ[i-con][j-con]; |       Q[i][j]=QQ[i-con][j-con]; | ||||||
|   | |||||||
| @@ -1,453 +0,0 @@ | |||||||
|     /************************************************************************************* |  | ||||||
|  |  | ||||||
|     Grid physics library, www.github.com/paboyle/Grid  |  | ||||||
|  |  | ||||||
|     Source file: ./lib/algorithms/iterative/Matrix.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 MATRIX_H |  | ||||||
| #define MATRIX_H |  | ||||||
|  |  | ||||||
| #include <cstdlib> |  | ||||||
| #include <string> |  | ||||||
| #include <cmath> |  | ||||||
| #include <vector> |  | ||||||
| #include <iostream> |  | ||||||
| #include <iomanip> |  | ||||||
| #include <complex> |  | ||||||
| #include <typeinfo> |  | ||||||
| #include <Grid.h> |  | ||||||
|  |  | ||||||
|  |  | ||||||
| /** Sign function **/ |  | ||||||
| template <class T> T sign(T p){return ( p/abs(p) );} |  | ||||||
|  |  | ||||||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////// |  | ||||||
| ///////////////////// Hijack STL containers for our wicked means ///////////////////////////////////////// |  | ||||||
| ///////////////////////////////////////////////////////////////////////////////////////////////////////// |  | ||||||
| template<class T> using Vector = Vector<T>; |  | ||||||
| template<class T> using Matrix = Vector<Vector<T> >; |  | ||||||
|  |  | ||||||
| template<class T> void Resize(Vector<T > & vec, int N) { vec.resize(N); } |  | ||||||
|  |  | ||||||
| template<class T> void Resize(Matrix<T > & mat, int N, int M) {  |  | ||||||
|   mat.resize(N); |  | ||||||
|   for(int i=0;i<N;i++){ |  | ||||||
|     mat[i].resize(M); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| template<class T> void Size(Vector<T> & vec, int &N)  |  | ||||||
| {  |  | ||||||
|   N= vec.size(); |  | ||||||
| } |  | ||||||
| template<class T> void Size(Matrix<T> & mat, int &N,int &M)  |  | ||||||
| {  |  | ||||||
|   N= mat.size(); |  | ||||||
|   M= mat[0].size(); |  | ||||||
| } |  | ||||||
| template<class T> void SizeSquare(Matrix<T> & mat, int &N)  |  | ||||||
| {  |  | ||||||
|   int M; Size(mat,N,M); |  | ||||||
|   assert(N==M); |  | ||||||
| } |  | ||||||
| template<class T> void SizeSame(Matrix<T> & mat1,Matrix<T> &mat2, int &N1,int &M1)  |  | ||||||
| {  |  | ||||||
|   int N2,M2; |  | ||||||
|   Size(mat1,N1,M1); |  | ||||||
|   Size(mat2,N2,M2); |  | ||||||
|   assert(N1==N2); |  | ||||||
|   assert(M1==M2); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| //***************************************** |  | ||||||
| //*	(Complex) Vector operations	* |  | ||||||
| //***************************************** |  | ||||||
|  |  | ||||||
| /**Conj of a Vector **/ |  | ||||||
| template <class T> Vector<T> conj(Vector<T> p){ |  | ||||||
| 	Vector<T> q(p.size()); |  | ||||||
| 	for(int i=0;i<p.size();i++){q[i] = conj(p[i]);} |  | ||||||
| 	return q; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /** Norm of a Vector**/ |  | ||||||
| template <class T> T norm(Vector<T> p){ |  | ||||||
| 	T sum = 0; |  | ||||||
| 	for(int i=0;i<p.size();i++){sum = sum + p[i]*conj(p[i]);} |  | ||||||
| 	return abs(sqrt(sum)); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /** Norm squared of a Vector **/ |  | ||||||
| template <class T> T norm2(Vector<T> p){ |  | ||||||
| 	T sum = 0; |  | ||||||
| 	for(int i=0;i<p.size();i++){sum = sum + p[i]*conj(p[i]);} |  | ||||||
| 	return abs((sum)); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /** Sum elements of a Vector **/ |  | ||||||
| template <class T> T trace(Vector<T> p){ |  | ||||||
| 	T sum = 0; |  | ||||||
| 	for(int i=0;i<p.size();i++){sum = sum + p[i];} |  | ||||||
| 	return sum; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /** Fill a Vector with constant c **/ |  | ||||||
| template <class T> void Fill(Vector<T> &p, T c){ |  | ||||||
| 	for(int i=0;i<p.size();i++){p[i] = c;} |  | ||||||
| } |  | ||||||
| /** Normalize a Vector **/ |  | ||||||
| template <class T> void normalize(Vector<T> &p){ |  | ||||||
| 	T m = norm(p); |  | ||||||
| 	if( abs(m) > 0.0) for(int i=0;i<p.size();i++){p[i] /= m;} |  | ||||||
| } |  | ||||||
| /** Vector by scalar **/ |  | ||||||
| template <class T, class U> Vector<T> times(Vector<T> p, U s){ |  | ||||||
| 	for(int i=0;i<p.size();i++){p[i] *= s;} |  | ||||||
| 	return p; |  | ||||||
| } |  | ||||||
| template <class T, class U> Vector<T> times(U s, Vector<T> p){ |  | ||||||
| 	for(int i=0;i<p.size();i++){p[i] *= s;} |  | ||||||
| 	return p; |  | ||||||
| } |  | ||||||
| /** inner product of a and b = conj(a) . b **/ |  | ||||||
| template <class T> T inner(Vector<T> a, Vector<T> b){ |  | ||||||
| 	T m = 0.; |  | ||||||
| 	for(int i=0;i<a.size();i++){m = m + conj(a[i])*b[i];} |  | ||||||
| 	return m; |  | ||||||
| } |  | ||||||
| /** sum of a and b = a + b **/ |  | ||||||
| template <class T> Vector<T> add(Vector<T> a, Vector<T> b){ |  | ||||||
| 	Vector<T> m(a.size()); |  | ||||||
| 	for(int i=0;i<a.size();i++){m[i] = a[i] + b[i];} |  | ||||||
| 	return m; |  | ||||||
| } |  | ||||||
| /** sum of a and b = a - b **/ |  | ||||||
| template <class T> Vector<T> sub(Vector<T> a, Vector<T> b){ |  | ||||||
| 	Vector<T> m(a.size()); |  | ||||||
| 	for(int i=0;i<a.size();i++){m[i] = a[i] - b[i];} |  | ||||||
| 	return m; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /**  |  | ||||||
|  ********************************* |  | ||||||
|  *	Matrices	         * |  | ||||||
|  ********************************* |  | ||||||
|  **/ |  | ||||||
|  |  | ||||||
| template<class T> void Fill(Matrix<T> & mat, T&val) {  |  | ||||||
|   int N,M; |  | ||||||
|   Size(mat,N,M); |  | ||||||
|   for(int i=0;i<N;i++){ |  | ||||||
|   for(int j=0;j<M;j++){ |  | ||||||
|     mat[i][j] = val; |  | ||||||
|   }} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /** Transpose of a matrix **/ |  | ||||||
| Matrix<T> Transpose(Matrix<T> & mat){ |  | ||||||
|   int N,M; |  | ||||||
|   Size(mat,N,M); |  | ||||||
|   Matrix C; Resize(C,M,N); |  | ||||||
|   for(int i=0;i<M;i++){ |  | ||||||
|   for(int j=0;j<N;j++){ |  | ||||||
|     C[i][j] = mat[j][i]; |  | ||||||
|   }}  |  | ||||||
|   return C; |  | ||||||
| } |  | ||||||
| /** Set Matrix to unit matrix **/ |  | ||||||
| template<class T> void Unity(Matrix<T> &mat){ |  | ||||||
|   int N;  SizeSquare(mat,N); |  | ||||||
|   for(int i=0;i<N;i++){ |  | ||||||
|     for(int j=0;j<N;j++){ |  | ||||||
|       if ( i==j ) A[i][j] = 1; |  | ||||||
|       else        A[i][j] = 0; |  | ||||||
|     }  |  | ||||||
|   }  |  | ||||||
| } |  | ||||||
| /** Add C * I to matrix **/ |  | ||||||
| template<class T> |  | ||||||
| void PlusUnit(Matrix<T> & A,T c){ |  | ||||||
|   int dim;  SizeSquare(A,dim); |  | ||||||
|   for(int i=0;i<dim;i++){A[i][i] = A[i][i] + c;}  |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /** return the Hermitian conjugate of matrix **/ |  | ||||||
| Matrix<T> HermitianConj(Matrix<T> &mat){ |  | ||||||
|  |  | ||||||
|   int dim; SizeSquare(mat,dim); |  | ||||||
|  |  | ||||||
|   Matrix<T> C; Resize(C,dim,dim); |  | ||||||
|  |  | ||||||
|   for(int i=0;i<dim;i++){ |  | ||||||
|     for(int j=0;j<dim;j++){ |  | ||||||
|       C[i][j] = conj(mat[j][i]); |  | ||||||
|     }  |  | ||||||
|   }  |  | ||||||
|   return C; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /** return diagonal entries as a Vector **/ |  | ||||||
| Vector<T> diag(Matrix<T> &A) |  | ||||||
| { |  | ||||||
|   int dim; SizeSquare(A,dim); |  | ||||||
|   Vector<T> d; Resize(d,dim); |  | ||||||
|  |  | ||||||
|   for(int i=0;i<dim;i++){ |  | ||||||
|     d[i] = A[i][i]; |  | ||||||
|   } |  | ||||||
|   return d; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /** Left multiply by a Vector **/ |  | ||||||
| Vector<T> operator *(Vector<T> &B,Matrix<T> &A) |  | ||||||
| { |  | ||||||
|   int K,M,N;  |  | ||||||
|   Size(B,K); |  | ||||||
|   Size(A,M,N); |  | ||||||
|   assert(K==M); |  | ||||||
|    |  | ||||||
|   Vector<T> C; Resize(C,N); |  | ||||||
|  |  | ||||||
|   for(int j=0;j<N;j++){ |  | ||||||
|     T sum = 0.0; |  | ||||||
|     for(int i=0;i<M;i++){ |  | ||||||
|       sum += B[i] * A[i][j]; |  | ||||||
|     } |  | ||||||
|     C[j] =  sum; |  | ||||||
|   } |  | ||||||
|   return C;  |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /** return 1/diagonal entries as a Vector **/ |  | ||||||
| Vector<T> inv_diag(Matrix<T> & A){ |  | ||||||
|   int dim; SizeSquare(A,dim); |  | ||||||
|   Vector<T> d; Resize(d,dim); |  | ||||||
|   for(int i=0;i<dim;i++){ |  | ||||||
|     d[i] = 1.0/A[i][i]; |  | ||||||
|   } |  | ||||||
|   return d; |  | ||||||
| } |  | ||||||
| /** Matrix Addition **/ |  | ||||||
| inline Matrix<T> operator + (Matrix<T> &A,Matrix<T> &B) |  | ||||||
| { |  | ||||||
|   int N,M  ; SizeSame(A,B,N,M); |  | ||||||
|   Matrix C; Resize(C,N,M); |  | ||||||
|   for(int i=0;i<N;i++){ |  | ||||||
|     for(int j=0;j<M;j++){ |  | ||||||
|       C[i][j] = A[i][j] +  B[i][j]; |  | ||||||
|     }  |  | ||||||
|   }  |  | ||||||
|   return C; |  | ||||||
| }  |  | ||||||
| /** Matrix Subtraction **/ |  | ||||||
| inline Matrix<T> operator- (Matrix<T> & A,Matrix<T> &B){ |  | ||||||
|   int N,M  ; SizeSame(A,B,N,M); |  | ||||||
|   Matrix C; Resize(C,N,M); |  | ||||||
|   for(int i=0;i<N;i++){ |  | ||||||
|   for(int j=0;j<M;j++){ |  | ||||||
|     C[i][j] = A[i][j] -  B[i][j]; |  | ||||||
|   }} |  | ||||||
|   return C; |  | ||||||
| }  |  | ||||||
|  |  | ||||||
| /** Matrix scalar multiplication **/ |  | ||||||
| inline Matrix<T> operator* (Matrix<T> & A,T c){ |  | ||||||
|   int N,M; Size(A,N,M); |  | ||||||
|   Matrix C; Resize(C,N,M); |  | ||||||
|   for(int i=0;i<N;i++){ |  | ||||||
|   for(int j=0;j<M;j++){ |  | ||||||
|     C[i][j] = A[i][j]*c; |  | ||||||
|   }}  |  | ||||||
|   return C; |  | ||||||
| }  |  | ||||||
| /** Matrix Matrix multiplication **/ |  | ||||||
| inline Matrix<T> operator* (Matrix<T> &A,Matrix<T> &B){ |  | ||||||
|   int K,L,N,M; |  | ||||||
|   Size(A,K,L); |  | ||||||
|   Size(B,N,M); assert(L==N); |  | ||||||
|   Matrix C; Resize(C,K,M); |  | ||||||
|  |  | ||||||
|   for(int i=0;i<K;i++){ |  | ||||||
|     for(int j=0;j<M;j++){ |  | ||||||
|       T sum = 0.0; |  | ||||||
|       for(int k=0;k<N;k++) sum += A[i][k]*B[k][j]; |  | ||||||
|       C[i][j] =sum; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|   return C;  |  | ||||||
| }  |  | ||||||
| /** Matrix Vector multiplication **/ |  | ||||||
| inline Vector<T> operator* (Matrix<T> &A,Vector<T> &B){ |  | ||||||
|   int M,N,K; |  | ||||||
|   Size(A,N,M); |  | ||||||
|   Size(B,K); assert(K==M); |  | ||||||
|   Vector<T> C; Resize(C,N); |  | ||||||
|   for(int i=0;i<N;i++){ |  | ||||||
|     T sum = 0.0; |  | ||||||
|     for(int j=0;j<M;j++) sum += A[i][j]*B[j]; |  | ||||||
|     C[i] =  sum; |  | ||||||
|   } |  | ||||||
|   return C;  |  | ||||||
| }  |  | ||||||
|  |  | ||||||
| /** Some version of Matrix norm **/ |  | ||||||
| /* |  | ||||||
| inline T Norm(){ // this is not a usual L2 norm |  | ||||||
|     T norm = 0; |  | ||||||
|     for(int i=0;i<dim;i++){ |  | ||||||
|       for(int j=0;j<dim;j++){ |  | ||||||
| 	norm += abs(A[i][j]); |  | ||||||
|     }} |  | ||||||
|     return norm; |  | ||||||
|   } |  | ||||||
| */ |  | ||||||
|  |  | ||||||
| /** Some version of Matrix norm **/ |  | ||||||
| template<class T> T LargestDiag(Matrix<T> &A) |  | ||||||
| { |  | ||||||
|   int dim ; SizeSquare(A,dim);  |  | ||||||
|  |  | ||||||
|   T ld = abs(A[0][0]); |  | ||||||
|   for(int i=1;i<dim;i++){ |  | ||||||
|     T cf = abs(A[i][i]); |  | ||||||
|     if(abs(cf) > abs(ld) ){ld = cf;} |  | ||||||
|   } |  | ||||||
|   return ld; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /** Look for entries on the leading subdiagonal that are smaller than 'small' **/ |  | ||||||
| template <class T,class U> int Chop_subdiag(Matrix<T> &A,T norm, int offset, U small) |  | ||||||
| { |  | ||||||
|   int dim; SizeSquare(A,dim); |  | ||||||
|   for(int l = dim - 1 - offset; l >= 1; l--) {             		 |  | ||||||
|     if((U)abs(A[l][l - 1]) < (U)small) { |  | ||||||
|       A[l][l-1]=(U)0.0; |  | ||||||
|       return l; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|   return 0; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /** Look for entries on the leading subdiagonal that are smaller than 'small' **/ |  | ||||||
| template <class T,class U> int Chop_symm_subdiag(Matrix<T> & A,T norm, int offset, U small)  |  | ||||||
| { |  | ||||||
|   int dim; SizeSquare(A,dim); |  | ||||||
|   for(int l = dim - 1 - offset; l >= 1; l--) { |  | ||||||
|     if((U)abs(A[l][l - 1]) < (U)small) { |  | ||||||
|       A[l][l - 1] = (U)0.0; |  | ||||||
|       A[l - 1][l] = (U)0.0; |  | ||||||
|       return l; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|   return 0; |  | ||||||
| } |  | ||||||
| /**Assign a submatrix to a larger one**/ |  | ||||||
| template<class T> |  | ||||||
| void AssignSubMtx(Matrix<T> & A,int row_st, int row_end, int col_st, int col_end, Matrix<T> &S) |  | ||||||
| { |  | ||||||
|   for(int i = row_st; i<row_end; i++){ |  | ||||||
|     for(int j = col_st; j<col_end; j++){ |  | ||||||
|       A[i][j] = S[i - row_st][j - col_st]; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /**Get a square submatrix**/ |  | ||||||
| template <class T> |  | ||||||
| Matrix<T> GetSubMtx(Matrix<T> &A,int row_st, int row_end, int col_st, int col_end) |  | ||||||
| { |  | ||||||
|   Matrix<T> H; Resize(row_end - row_st,col_end-col_st); |  | ||||||
|  |  | ||||||
|   for(int i = row_st; i<row_end; i++){ |  | ||||||
|   for(int j = col_st; j<col_end; j++){ |  | ||||||
|     H[i-row_st][j-col_st]=A[i][j]; |  | ||||||
|   }} |  | ||||||
|   return H; |  | ||||||
| } |  | ||||||
|    |  | ||||||
|  /**Assign a submatrix to a larger one NB remember Vector Vectors are transposes of the matricies they represent**/ |  | ||||||
| template<class T> |  | ||||||
| void AssignSubMtx(Matrix<T> & A,int row_st, int row_end, int col_st, int col_end, Matrix<T> &S) |  | ||||||
| { |  | ||||||
|   for(int i = row_st; i<row_end; i++){ |  | ||||||
|   for(int j = col_st; j<col_end; j++){ |  | ||||||
|     A[i][j] = S[i - row_st][j - col_st]; |  | ||||||
|   }} |  | ||||||
| } |  | ||||||
|    |  | ||||||
| /** compute b_i A_ij b_j **/ // surprised no Conj |  | ||||||
| template<class T> T proj(Matrix<T> A, Vector<T> B){ |  | ||||||
|   int dim; SizeSquare(A,dim); |  | ||||||
|   int dimB; Size(B,dimB); |  | ||||||
|   assert(dimB==dim); |  | ||||||
|   T C = 0; |  | ||||||
|   for(int i=0;i<dim;i++){ |  | ||||||
|     T sum = 0.0; |  | ||||||
|     for(int j=0;j<dim;j++){ |  | ||||||
|       sum += A[i][j]*B[j]; |  | ||||||
|     } |  | ||||||
|     C +=  B[i]*sum; // No conj? |  | ||||||
|   } |  | ||||||
|   return C;  |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| /* |  | ||||||
|  ************************************************************* |  | ||||||
|  * |  | ||||||
|  * Matrix Vector products |  | ||||||
|  * |  | ||||||
|  ************************************************************* |  | ||||||
|  */ |  | ||||||
| // Instead make a linop and call my CG; |  | ||||||
|  |  | ||||||
| /// q -> q Q |  | ||||||
| template <class T,class Fermion> void times(Vector<Fermion> &q, Matrix<T> &Q) |  | ||||||
| { |  | ||||||
|   int M; SizeSquare(Q,M); |  | ||||||
|   int N; Size(q,N);  |  | ||||||
|   assert(M==N); |  | ||||||
|  |  | ||||||
|   times(q,Q,N); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /// q -> q Q |  | ||||||
| template <class T> void times(multi1d<LatticeFermion> &q, Matrix<T> &Q, int N) |  | ||||||
| { |  | ||||||
|   GridBase *grid = q[0]._grid; |  | ||||||
|   int M; SizeSquare(Q,M); |  | ||||||
|   int K; Size(q,K);  |  | ||||||
|   assert(N<M); |  | ||||||
|   assert(N<K); |  | ||||||
|   Vector<Fermion> S(N,grid ); |  | ||||||
|   for(int j=0;j<N;j++){ |  | ||||||
|     S[j] = zero; |  | ||||||
|     for(int k=0;k<N;k++){ |  | ||||||
|       S[j] = S[j] +  q[k]* Q[k][j];  |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|   for(int j=0;j<q.size();j++){ |  | ||||||
|     q[j] = S[j]; |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| #endif |  | ||||||
| @@ -1,15 +0,0 @@ | |||||||
| - ConjugateGradientMultiShift |  | ||||||
| - MCR |  | ||||||
|  |  | ||||||
| - Potentially Useful Boost libraries |  | ||||||
|  |  | ||||||
| - MultiArray |  | ||||||
| - Aligned allocator; memory pool |  | ||||||
| - Remez -- Mike or Boost? |  | ||||||
| - Multiprecision |  | ||||||
| - quaternians |  | ||||||
| - Tokenize |  | ||||||
| - Serialization |  | ||||||
| - Regex |  | ||||||
| - Proto (ET) |  | ||||||
| - uBlas |  | ||||||
| @@ -1,122 +0,0 @@ | |||||||
| #include <math.h> |  | ||||||
| #include <stdlib.h> |  | ||||||
| #include <vector> |  | ||||||
|  |  | ||||||
| struct Bisection { |  | ||||||
|  |  | ||||||
| static void get_eig2(int row_num,std::vector<RealD> &ALPHA,std::vector<RealD> &BETA, std::vector<RealD> & eig) |  | ||||||
| { |  | ||||||
|   int i,j; |  | ||||||
|   std::vector<RealD> evec1(row_num+3); |  | ||||||
|   std::vector<RealD> evec2(row_num+3); |  | ||||||
|   RealD eps2; |  | ||||||
|   ALPHA[1]=0.; |  | ||||||
|   BETHA[1]=0.; |  | ||||||
|   for(i=0;i<row_num-1;i++) { |  | ||||||
|     ALPHA[i+1] = A[i*(row_num+1)].real(); |  | ||||||
|     BETHA[i+2] = A[i*(row_num+1)+1].real(); |  | ||||||
|   } |  | ||||||
|   ALPHA[row_num] = A[(row_num-1)*(row_num+1)].real(); |  | ||||||
|   bisec(ALPHA,BETHA,row_num,1,row_num,1e-10,1e-10,evec1,eps2); |  | ||||||
|   bisec(ALPHA,BETHA,row_num,1,row_num,1e-16,1e-16,evec2,eps2); |  | ||||||
|  |  | ||||||
|   // Do we really need to sort here? |  | ||||||
|   int begin=1; |  | ||||||
|   int end = row_num; |  | ||||||
|   int swapped=1; |  | ||||||
|   while(swapped) { |  | ||||||
|     swapped=0; |  | ||||||
|     for(i=begin;i<end;i++){ |  | ||||||
|       if(mag(evec2[i])>mag(evec2[i+1]))	{ |  | ||||||
| 	swap(evec2+i,evec2+i+1); |  | ||||||
| 	swapped=1; |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|     end--; |  | ||||||
|     for(i=end-1;i>=begin;i--){ |  | ||||||
|       if(mag(evec2[i])>mag(evec2[i+1]))	{ |  | ||||||
| 	swap(evec2+i,evec2+i+1); |  | ||||||
| 	swapped=1; |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|     begin++; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   for(i=0;i<row_num;i++){ |  | ||||||
|     for(j=0;j<row_num;j++) { |  | ||||||
|       if(i==j) H[i*row_num+j]=evec2[i+1]; |  | ||||||
|       else H[i*row_num+j]=0.; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| static void bisec(std::vector<RealD> &c,    |  | ||||||
| 		  std::vector<RealD> &b, |  | ||||||
| 		  int n, |  | ||||||
| 		  int m1, |  | ||||||
| 		  int m2, |  | ||||||
| 		  RealD eps1, |  | ||||||
| 		  RealD relfeh, |  | ||||||
| 		  std::vector<RealD> &x, |  | ||||||
| 		  RealD &eps2) |  | ||||||
| { |  | ||||||
|   std::vector<RealD> wu(n+2); |  | ||||||
|  |  | ||||||
|   RealD h,q,x1,xu,x0,xmin,xmax;  |  | ||||||
|   int i,a,k; |  | ||||||
|  |  | ||||||
|   b[1]=0.0; |  | ||||||
|   xmin=c[n]-fabs(b[n]); |  | ||||||
|   xmax=c[n]+fabs(b[n]); |  | ||||||
|   for(i=1;i<n;i++){ |  | ||||||
|     h=fabs(b[i])+fabs(b[i+1]); |  | ||||||
|     if(c[i]+h>xmax) xmax= c[i]+h; |  | ||||||
|     if(c[i]-h<xmin) xmin= c[i]-h; |  | ||||||
|   } |  | ||||||
|   xmax *=2.; |  | ||||||
|  |  | ||||||
|   eps2=relfeh*((xmin+xmax)>0.0 ? xmax : -xmin); |  | ||||||
|   if(eps1<=0.0) eps1=eps2; |  | ||||||
|   eps2=0.5*eps1+7.0*(eps2); |  | ||||||
|   x0=xmax; |  | ||||||
|   for(i=m1;i<=m2;i++){ |  | ||||||
|     x[i]=xmax; |  | ||||||
|     wu[i]=xmin; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   for(k=m2;k>=m1;k--){ |  | ||||||
|     xu=xmin; |  | ||||||
|     i=k; |  | ||||||
|     do{ |  | ||||||
|       if(xu<wu[i]){ |  | ||||||
| 	xu=wu[i]; |  | ||||||
| 	i=m1-1; |  | ||||||
|       } |  | ||||||
|       i--; |  | ||||||
|     }while(i>=m1); |  | ||||||
|     if(x0>x[k]) x0=x[k]; |  | ||||||
|     while((x0-xu)>2*relfeh*(fabs(xu)+fabs(x0))+eps1){ |  | ||||||
|       x1=(xu+x0)/2; |  | ||||||
|  |  | ||||||
|       a=0; |  | ||||||
|       q=1.0; |  | ||||||
|       for(i=1;i<=n;i++){ |  | ||||||
| 	q=c[i]-x1-((q!=0.0)? b[i]*b[i]/q:fabs(b[i])/relfeh); |  | ||||||
| 	if(q<0) a++; |  | ||||||
|       } |  | ||||||
|       //			printf("x1=%e a=%d\n",x1,a); |  | ||||||
|       if(a<k){ |  | ||||||
| 	if(a<m1){ |  | ||||||
| 	  xu=x1; |  | ||||||
| 	  wu[m1]=x1; |  | ||||||
| 	}else { |  | ||||||
| 	  xu=x1; |  | ||||||
| 	  wu[a+1]=x1; |  | ||||||
| 	  if(x[a]>x1) x[a]=x1; |  | ||||||
| 	} |  | ||||||
|       }else x0=x1; |  | ||||||
|     } |  | ||||||
|     x[k]=(x0+xu)/2; |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| } |  | ||||||
| @@ -1 +0,0 @@ | |||||||
|  |  | ||||||
							
								
								
									
										66
									
								
								lib/allocator/AlignedAllocator.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								lib/allocator/AlignedAllocator.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | |||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #include <Grid/GridCore.h> | ||||||
|  |  | ||||||
|  | namespace Grid { | ||||||
|  |  | ||||||
|  | int PointerCache::victim; | ||||||
|  |  | ||||||
|  |   PointerCache::PointerCacheEntry PointerCache::Entries[PointerCache::Ncache]; | ||||||
|  |  | ||||||
|  | void *PointerCache::Insert(void *ptr,size_t bytes) { | ||||||
|  |  | ||||||
|  |   if (bytes < 4096 ) return NULL; | ||||||
|  |  | ||||||
|  | #ifdef GRID_OMP | ||||||
|  |   assert(omp_in_parallel()==0); | ||||||
|  | #endif  | ||||||
|  |  | ||||||
|  |   void * ret = NULL; | ||||||
|  |   int v = -1; | ||||||
|  |  | ||||||
|  |   for(int e=0;e<Ncache;e++) { | ||||||
|  |     if ( Entries[e].valid==0 ) { | ||||||
|  |       v=e;  | ||||||
|  |       break; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if ( v==-1 ) { | ||||||
|  |     v=victim; | ||||||
|  |     victim = (victim+1)%Ncache; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if ( Entries[v].valid ) { | ||||||
|  |     ret = Entries[v].address; | ||||||
|  |     Entries[v].valid = 0; | ||||||
|  |     Entries[v].address = NULL; | ||||||
|  |     Entries[v].bytes = 0; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   Entries[v].address=ptr; | ||||||
|  |   Entries[v].bytes  =bytes; | ||||||
|  |   Entries[v].valid  =1; | ||||||
|  |  | ||||||
|  |   return ret; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void *PointerCache::Lookup(size_t bytes) { | ||||||
|  |  | ||||||
|  |  if (bytes < 4096 ) return NULL; | ||||||
|  |  | ||||||
|  | #ifdef _OPENMP | ||||||
|  |   assert(omp_in_parallel()==0); | ||||||
|  | #endif  | ||||||
|  |  | ||||||
|  |   for(int e=0;e<Ncache;e++){ | ||||||
|  |     if ( Entries[e].valid && ( Entries[e].bytes == bytes ) ) { | ||||||
|  |       Entries[e].valid = 0; | ||||||
|  |       return Entries[e].address; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   return NULL; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -1,4 +1,4 @@ | |||||||
|     /*************************************************************************************
 | /*************************************************************************************
 | ||||||
| 
 | 
 | ||||||
|     Grid physics library, www.github.com/paboyle/Grid  |     Grid physics library, www.github.com/paboyle/Grid  | ||||||
| 
 | 
 | ||||||
| @@ -42,9 +42,32 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk> | |||||||
| 
 | 
 | ||||||
| namespace Grid { | namespace Grid { | ||||||
| 
 | 
 | ||||||
|  |   class PointerCache { | ||||||
|  |   private: | ||||||
|  | 
 | ||||||
|  |     static const int Ncache=8; | ||||||
|  |     static int victim; | ||||||
|  | 
 | ||||||
|  |     typedef struct {  | ||||||
|  |       void *address; | ||||||
|  |       size_t bytes; | ||||||
|  |       int valid; | ||||||
|  |     } PointerCacheEntry; | ||||||
|  |      | ||||||
|  |     static PointerCacheEntry Entries[Ncache]; | ||||||
|  | 
 | ||||||
|  |   public: | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     static void *Insert(void *ptr,size_t bytes) ; | ||||||
|  |     static void *Lookup(size_t bytes) ; | ||||||
|  | 
 | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
| ////////////////////////////////////////////////////////////////////
 | ////////////////////////////////////////////////////////////////////
 | ||||||
| // A lattice of something, but assume the something is SIMDized.
 | // A lattice of something, but assume the something is SIMDized.
 | ||||||
| ////////////////////////////////////////////////////////////////////
 | ////////////////////////////////////////////////////////////////////
 | ||||||
|  | 
 | ||||||
| template<typename _Tp> | template<typename _Tp> | ||||||
| class alignedAllocator { | class alignedAllocator { | ||||||
| public:  | public:  | ||||||
| @@ -66,27 +89,27 @@ public: | |||||||
| 
 | 
 | ||||||
|   pointer allocate(size_type __n, const void* _p= 0) |   pointer allocate(size_type __n, const void* _p= 0) | ||||||
|   {  |   {  | ||||||
|  |     size_type bytes = __n*sizeof(_Tp); | ||||||
|  | 
 | ||||||
|  |     _Tp *ptr = (_Tp *) PointerCache::Lookup(bytes); | ||||||
|  |      | ||||||
| #ifdef HAVE_MM_MALLOC_H | #ifdef HAVE_MM_MALLOC_H | ||||||
|     _Tp * ptr = (_Tp *) _mm_malloc(__n*sizeof(_Tp),128); |     if ( ptr == (_Tp *) NULL ) ptr = (_Tp *) _mm_malloc(bytes,128); | ||||||
| #else | #else | ||||||
|     _Tp * ptr = (_Tp *) memalign(128,__n*sizeof(_Tp)); |     if ( ptr == (_Tp *) NULL ) ptr = (_Tp *) memalign(128,bytes); | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|     _Tp tmp; |  | ||||||
| #ifdef GRID_NUMA |  | ||||||
| #pragma omp parallel for schedule(static) |  | ||||||
|   for(int i=0;i<__n;i++){ |  | ||||||
|     ptr[i]=tmp; |  | ||||||
|   } |  | ||||||
| #endif  |  | ||||||
|     return ptr; |     return ptr; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   void deallocate(pointer __p, size_type) {  |   void deallocate(pointer __p, size_type __n) {  | ||||||
|  |     size_type bytes = __n * sizeof(_Tp); | ||||||
|  |     pointer __freeme = (pointer)PointerCache::Insert((void *)__p,bytes); | ||||||
|  | 
 | ||||||
| #ifdef HAVE_MM_MALLOC_H | #ifdef HAVE_MM_MALLOC_H | ||||||
|     _mm_free((void *)__p);  |     if ( __freeme ) _mm_free((void *)__freeme);  | ||||||
| #else | #else | ||||||
|     free((void *)__p); |     if ( __freeme ) free((void *)__freeme); | ||||||
| #endif | #endif | ||||||
|   } |   } | ||||||
|   void construct(pointer __p, const _Tp& __val) { }; |   void construct(pointer __p, const _Tp& __val) { }; | ||||||
| @@ -52,7 +52,7 @@ public: | |||||||
|  |  | ||||||
|     // Physics Grid information. |     // Physics Grid information. | ||||||
|     std::vector<int> _simd_layout;// Which dimensions get relayed out over simd lanes. |     std::vector<int> _simd_layout;// Which dimensions get relayed out over simd lanes. | ||||||
|     std::vector<int> _fdimensions;// Global dimensions of array prior to cb removal |     std::vector<int> _fdimensions;// (full) Global dimensions of array prior to cb removal | ||||||
|     std::vector<int> _gdimensions;// Global dimensions of array after cb removal |     std::vector<int> _gdimensions;// Global dimensions of array after cb removal | ||||||
|     std::vector<int> _ldimensions;// local dimensions of array with processor images removed |     std::vector<int> _ldimensions;// local dimensions of array with processor images removed | ||||||
|     std::vector<int> _rdimensions;// Reduced local dimensions with simd lane images and processor images removed  |     std::vector<int> _rdimensions;// Reduced local dimensions with simd lane images and processor images removed  | ||||||
| @@ -77,7 +77,7 @@ public: | |||||||
|     // GridCartesian / GridRedBlackCartesian |     // GridCartesian / GridRedBlackCartesian | ||||||
|     //////////////////////////////////////////////////////////////// |     //////////////////////////////////////////////////////////////// | ||||||
|     virtual int CheckerBoarded(int dim)=0; |     virtual int CheckerBoarded(int dim)=0; | ||||||
|     virtual int CheckerBoard(std::vector<int> &site)=0; |     virtual int CheckerBoard(const std::vector<int> &site)=0; | ||||||
|     virtual int CheckerBoardDestination(int source_cb,int shift,int dim)=0; |     virtual int CheckerBoardDestination(int source_cb,int shift,int dim)=0; | ||||||
|     virtual int CheckerBoardShift(int source_cb,int dim,int shift,int osite)=0; |     virtual int CheckerBoardShift(int source_cb,int dim,int shift,int osite)=0; | ||||||
|     virtual int CheckerBoardShiftForCB(int source_cb,int dim,int shift,int cb)=0; |     virtual int CheckerBoardShiftForCB(int source_cb,int dim,int shift,int cb)=0; | ||||||
| @@ -121,7 +121,6 @@ public: | |||||||
|       Lexicographic::CoorFromIndex(coor,Oindex,_rdimensions); |       Lexicographic::CoorFromIndex(coor,Oindex,_rdimensions); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|     ////////////////////////////////////////////////////////// |     ////////////////////////////////////////////////////////// | ||||||
|     // SIMD lane addressing |     // SIMD lane addressing | ||||||
|     ////////////////////////////////////////////////////////// |     ////////////////////////////////////////////////////////// | ||||||
| @@ -178,9 +177,11 @@ public: | |||||||
|     // Global addressing |     // Global addressing | ||||||
|     //////////////////////////////////////////////////////////////// |     //////////////////////////////////////////////////////////////// | ||||||
|     void GlobalIndexToGlobalCoor(int gidx,std::vector<int> &gcoor){ |     void GlobalIndexToGlobalCoor(int gidx,std::vector<int> &gcoor){ | ||||||
|  |       assert(gidx< gSites()); | ||||||
|       Lexicographic::CoorFromIndex(gcoor,gidx,_gdimensions); |       Lexicographic::CoorFromIndex(gcoor,gidx,_gdimensions); | ||||||
|     } |     } | ||||||
|     void LocalIndexToLocalCoor(int lidx,std::vector<int> &lcoor){ |     void LocalIndexToLocalCoor(int lidx,std::vector<int> &lcoor){ | ||||||
|  |       assert(lidx<lSites()); | ||||||
|       Lexicographic::CoorFromIndex(lcoor,lidx,_ldimensions); |       Lexicographic::CoorFromIndex(lcoor,lidx,_ldimensions); | ||||||
|     } |     } | ||||||
|     void GlobalCoorToGlobalIndex(const std::vector<int> & gcoor,int & gidx){ |     void GlobalCoorToGlobalIndex(const std::vector<int> & gcoor,int & gidx){ | ||||||
| @@ -207,16 +208,16 @@ public: | |||||||
|       std::vector<int> lcoor; |       std::vector<int> lcoor; | ||||||
|       GlobalCoorToProcessorCoorLocalCoor(pcoor,lcoor,gcoor); |       GlobalCoorToProcessorCoorLocalCoor(pcoor,lcoor,gcoor); | ||||||
|       rank = RankFromProcessorCoor(pcoor); |       rank = RankFromProcessorCoor(pcoor); | ||||||
|  |       /* | ||||||
|       std::vector<int> cblcoor(lcoor); |       std::vector<int> cblcoor(lcoor); | ||||||
|       for(int d=0;d<cblcoor.size();d++){ |       for(int d=0;d<cblcoor.size();d++){ | ||||||
| 	if( this->CheckerBoarded(d) ) { | 	if( this->CheckerBoarded(d) ) { | ||||||
| 	  cblcoor[d] = lcoor[d]/2; | 	  cblcoor[d] = lcoor[d]/2; | ||||||
| 	} | 	} | ||||||
|       } |       } | ||||||
|  |       */ | ||||||
|       i_idx= iIndex(cblcoor);// this does not imply divide by 2 on checker dim |       i_idx= iIndex(lcoor); | ||||||
|       o_idx= oIndex(lcoor);  // this implies divide by 2 on checkerdim |       o_idx= oIndex(lcoor); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     void RankIndexToGlobalCoor(int rank, int o_idx, int i_idx , std::vector<int> &gcoor) |     void RankIndexToGlobalCoor(int rank, int o_idx, int i_idx , std::vector<int> &gcoor) | ||||||
|   | |||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user