mirror of
				https://github.com/paboyle/Grid.git
				synced 2025-10-25 02:04:48 +01:00 
			
		
		
		
	Compare commits
	
		
			500 Commits
		
	
	
		
			sycl-linki
			...
			feature/dd
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | c04de86d07 | ||
|  | 53e1b00cde | ||
|  | 1257c9f2f0 | ||
|  | 44b0988f9b | ||
|  | 98766851c3 | ||
|  | f36e984278 | ||
|  | c234a7f913 | ||
|  | 0bf0c65b7d | ||
|  | 3355ceea9f | ||
|  | e4cbfe3d4b | ||
|  | 4867e02dfb | ||
|  | ed68cf6268 | ||
|  | 4016e705fc | ||
|  | 2f4e85e5d6 | ||
|  | 8ed0b57b09 | ||
| 6c66b8d997 | |||
| 9523ad3d73 | |||
| 73a95fa96f | |||
|  | 67e08aa952 | ||
|  | ed1f20f3a1 | ||
|  | cffc736bb3 | ||
|  | c0d56a1c04 | ||
|  | 3206f69478 | ||
|  | b2ccaad761 | ||
|  | 8eb1232683 | ||
|  | c6ce3ad03b | ||
|  | b3b033d343 | ||
|  | ca9816bfbb | ||
|  | 814d5abc7e | ||
|  | a29122e2bf | ||
|  | e188c0512e | ||
|  | 1fb6aaf150 | ||
|  | 894654f7ef | ||
|  | 109507888b | ||
|  | 68650b61fe | ||
|  | 7ee66bf453 | ||
|  | 8bd70ad8b5 | ||
|  | af98525766 | ||
|  | 1c2f218519 | ||
|  | c9aa1f507c | ||
|  | ea7126496d | ||
|  | f660dc67e4 | ||
|  | ede8faea74 | ||
|  | 1b750761c2 | ||
|  | 145acf2919 | ||
|  | cc4a27b9e6 | ||
|  | b4690e6091 | ||
|  | 4b24800132 | ||
|  | 9d2238148c | ||
|  | c15493218d | ||
|  | 001a556a34 | ||
|  | 3d0f88e702 | ||
|  | dd091d0960 | ||
|  | e2abbf9520 | ||
|  | c7baeb5bae | ||
|  | 402d80e197 | ||
|  | 86e33c8ab2 | ||
|  | 5dae6a6dac | ||
|  | 361bb8a101 | ||
|  | 7efdb3cd2b | ||
|  | 65ef4ec29f | ||
|  | d5835c0222 | ||
|  | a7b943b33e | ||
|  | 7440cde92f | ||
|  | 0fc662bb24 | ||
|  | 8195890640 | ||
|  | 4c88104a73 | ||
|  | 73b944c152 | ||
|  | d1b0b7f5c6 | ||
|  | 381d8797d0 | ||
|  | b06526bc1e | ||
|  | 3044419111 | ||
|  | bcfa9cf068 | ||
|  | 114920b8de | ||
|  | 0d588b95f4 | ||
|  | 5b3c530aa7 | ||
|  | c6a5499c8b | ||
|  | ec9c3fe77a | ||
|  | 6135ad530e | ||
|  | 40098424c7 | ||
|  | 7163b31a26 | ||
|  | ffbdd91e0e | ||
|  | 7760417312 | ||
|  | 5d29e175d8 | ||
|  | 417dbfa257 | ||
|  | 1eda4d8e0b | ||
|  | 50181f16e5 | ||
|  | 75030637cc | ||
|  | fe5aaf7677 | ||
|  | 80ac2a73ca | ||
| d75a66a3e6 | |||
| fcc4374d7b | |||
| 67c3c16fe5 | |||
| 25e9be50b5 | |||
| 323cf6c038 | |||
|  | 29a22ae603 | ||
|  | 403bff1a47 | ||
|  | c50f27e68b | ||
|  | 80afacec5b | ||
|  | 6cd9224dd7 | ||
|  | 4bf8196ff1 | ||
|  | 4c5440fb06 | ||
|  | 8cc0defb69 | ||
|  | e0c9d01123 | ||
|  | 91bf1df018 | ||
|  | 386a89c668 | ||
|  | 670f4985fd | ||
|  | dcd48a0435 | ||
|  | 87ec14c353 | ||
|  | 4f5ad73501 | ||
|  | 096bb98f78 | ||
|  | 76837ffc65 | ||
|  | 81bd0d7906 | ||
|  | 7d8d250389 | ||
|  | ad406b2c3e | ||
|  | e6366b98a5 | ||
|  | 302356189c | ||
|  | 9394450c1a | ||
|  | 6cf3edef00 | ||
|  | 31cc227dd2 | ||
|  | c690e66325 | ||
|  | 5fdbb924f0 | ||
|  | 6dcaed621c | ||
| a269a3d919 | |||
|  | f9cda24781 | ||
|  | cd5e3fbd82 | ||
|  | f68036c79f | ||
|  | 216c178c16 | ||
|  | 990d976241 | ||
|  | f2fe2573a7 | ||
|  | 11c55a0476 | ||
|  | 0c4f585496 | ||
|  | 33d2df46a0 | ||
|  | 2df308f649 | ||
|  | 92def28bd3 | ||
| ca10bfa1c7 | |||
| 298a6ec51e | |||
|  | 1cc706b2f4 | ||
|  | e5dbe488a6 | ||
|  | 0e27e3847d | ||
|  | 9e51fa5681 | ||
|  | 9164cfbfc6 | ||
|  | 2f3a96e5de | ||
|  | 26aa89cb0c | ||
|  | 426d2365d1 | ||
|  | 81bbd4e4ce | ||
|  | b83bbe2dd1 | ||
|  | 3f2d8eb727 | ||
|  | 60f9bf69cd | ||
|  | 38d8cd228e | ||
|  | 4e1e242025 | ||
|  | 20c6f19bb2 | ||
|  | 036270a0c5 | ||
|  | 6c506601c5 | ||
|  | 393727b93b | ||
|  | 2b1fcd78c3 | ||
|  | 0a4e0b49a0 | ||
|  | 76af169f05 | ||
|  | 7b89232251 | ||
|  | b5aeae526f | ||
|  | e4ff4c902a | ||
|  | 2e4d4625b6 | ||
|  | 10f2c2530b | ||
|  | 375e0698dc | ||
|  | 64b3b37476 | ||
|  | 59e1a9be4e | ||
|  | aac1736617 | ||
|  | 60f814733d | ||
|  | 612e9a178a | ||
|  | 21af9cf83c | ||
|  | 3b8cb929d6 | ||
|  | 5d3046eae8 | ||
|  | d73063682e | ||
|  | 59584b6605 | ||
|  | f6d7188615 | ||
|  | b810b6f6bd | ||
|  | e0a92dff32 | ||
|  | ef0ddd5d04 | ||
|  | 9b73dacf50 | ||
|  | 244b4aa07f | ||
|  | e125f0f738 | ||
|  | 5f081d87b0 | ||
|  | 84e246a963 | ||
|  | c18025c0b8 | ||
|  | a918955020 | ||
|  | e3c18ce872 | ||
|  | 07a61e8826 | ||
|  | 58cb7c0732 | ||
|  | 10339fd775 | ||
|  | 9400c207f7 | ||
|  | 1fa89a2e7d | ||
|  | 09b233b82e | ||
|  | 34ca4dd53a | ||
|  | c19cf46169 | ||
|  | c8db9ddb33 | ||
|  | 104986b53d | ||
|  | 91fd44419b | ||
|  | d1daa0e3f7 | ||
|  | 05e1aed326 | ||
|  | d3fd23117a | ||
|  | def51267e9 | ||
|  | 5b52f29b2f | ||
|  | 25bd03f201 | ||
|  | d5edd100a5 | ||
|  | e39e326b79 | ||
|  | 8458e13a23 | ||
|  | 3575278b57 | ||
|  | 69a2c8769a | ||
|  | d4eaea00cf | ||
|  | 347ccdc468 | ||
|  | bf034ce239 | ||
|  | 791d0ab0b5 | ||
|  | 94a2a645bd | ||
|  | 281b55df04 | ||
|  | a36e797bfc | ||
|  | 0bade717bf | ||
|  | 84fe791519 | ||
|  | e009a37f6e | ||
|  | d7a887baf1 | ||
|  | 060bb59535 | ||
|  | bac36399c1 | ||
|  | b5b930d5bb | ||
|  | 4fca66a7c6 | ||
|  | bd181b9481 | ||
|  | 919ced1c31 | ||
|  | b32fd473f8 | ||
|  | ffcab64890 | ||
|  | 374fb325f3 | ||
|  | bab88bc4f7 | ||
|  | 7533f66b54 | ||
|  | 805cde5899 | ||
|  | a0534e03f9 | ||
|  | ebba195e0d | ||
|  | 3b433fe6fb | ||
|  | 07d1030660 | ||
|  | f8d7d23893 | ||
|  | cdeb718229 | ||
|  | cb28568198 | ||
|  | 45440da79d | ||
|  | 6fe8533414 | ||
|  | f776a7fe4a | ||
|  | cff884929c | ||
|  | 9c991c7e29 | ||
|  | 1c70d8c4d9 | ||
|  | f0e9a5299f | ||
|  | f1b8ba45e7 | ||
|  | fe998ab578 | ||
|  | c2ee2b5fd1 | ||
|  | 3b734ee397 | ||
|  | 8637a9512a | ||
|  | 7f6e2ee03e | ||
|  | 8cfc7342cd | ||
|  | 7b02acb2bd | ||
|  | 86948c6ea0 | ||
|  | 53d226924a | ||
|  | 80176b1b39 | ||
|  | 15ae317858 | ||
|  | 834f536b5f | ||
|  | 29ddafd0fc | ||
|  | c332d9f08b | ||
| cf2923d5dd | |||
|  | 0e4413ddde | ||
|  | 0f08364e4f | ||
|  | a198d59381 | ||
| 009ccd581e | |||
|  | 8cd4263974 | ||
|  | d45c868656 | ||
|  | 955a8113de | ||
|  | dbe210dd53 | ||
|  | 3a4f5f2324 | ||
|  | 824d84473f | ||
|  | 38964a4076 | ||
|  | 0d9aa87228 | ||
|  | 0e959d9b94 | ||
|  | 752f70cd48 | ||
|  | 86e11743ca | ||
|  | e0e42873c1 | ||
|  | 980e721f6e | ||
|  | 21165ed489 | ||
|  | 09288d633c | ||
|  | fe00c96435 | ||
|  | 0765f30308 | ||
|  | a6326b664e | ||
|  | ccd30e1485 | ||
|  | e2a0142d87 | ||
| 895244ecc3 | |||
| addeb621a7 | |||
|  | 3060887a37 | ||
|  | b53059344e | ||
|  | aaf5ebf345 | ||
|  | 48edb8f72e | ||
|  | a7fb25adf6 | ||
|  | e947992957 | ||
|  | bb89a82a07 | ||
|  | 0ff3bf6dc5 | ||
|  | 351eab02ae | ||
|  | 2bb374daea | ||
|  | 8bdadbadac | ||
|  | 15c50a7442 | ||
|  | 49b0af2c95 | ||
|  | 9c2b37218a | ||
|  | 3c67d626ba | ||
|  | 51f506553c | ||
|  | 226be84937 | ||
|  | 001814b442 | ||
|  | db3ac67506 | ||
|  | da91a884ef | ||
|  | a71e6755e3 | ||
|  | cd5891eecd | ||
|  | 5bb7336f27 | ||
|  | ce1fc1f48a | ||
|  | 82402c6a7c | ||
|  | d9c4afe5b7 | ||
|  | f786ff8d69 | ||
|  | a651caed5f | ||
|  | 0e21adb3f6 | ||
|  | 58bf9b9e6d | ||
|  | 2146eebb65 | ||
|  | 6a429ee6d3 | ||
|  | 4d1ea15c79 | ||
|  | a76cb005e0 | ||
|  | 49ecbc81d4 | ||
|  | 9e5fb52eb9 | ||
|  | a9604367c1 | ||
|  | d7065023cc | ||
|  | 89d299ceec | ||
|  | e34eda66df | ||
|  | b24181aa4f | ||
|  | aa173e2998 | ||
| 7a19432e0b | |||
| 9b15704290 | |||
|  | 017f955b2d | ||
|  | f252d69eef | ||
| 3b06e4655e | |||
| d4b4de8f42 | |||
|  | c90beee774 | ||
|  | 1eea9d73b9 | ||
|  | feee5ccde2 | ||
|  | 679d1d22f7 | ||
|  | b2b5e0b98c | ||
|  | 03e54722c1 | ||
|  | 442336bd96 | ||
|  | 9c9566b9c9 | ||
|  | 1059a81a3c | ||
|  | 2e61556389 | ||
|  | f9b1f240f6 | ||
|  | 69f41469dd | ||
|  | d620b303ff | ||
|  | 157fd1428d | ||
|  | c791cb2214 | ||
|  | d5ab571a89 | ||
| 0ed800f6e4 | |||
|  | 0a32183825 | ||
|  | 2cacfbde2a | ||
|  | c073e62e0b | ||
|  | e3d019bc2f | ||
| 7ae030f585 | |||
| 86b58d5aff | |||
|  | 26e8b9f4a5 | ||
|  | 35114c9e62 | ||
|  | e0f6a146d8 | ||
|  | dfd28a85c9 | ||
|  | a503332924 | ||
|  | daa095c519 | ||
|  | c2676853ca | ||
|  | 1ac13ec3a7 | ||
|  | 55de69a569 | ||
|  | eda9ab487b | ||
|  | 6a824033f8 | ||
|  | cee6a37639 | ||
|  | cd99edcc5f | ||
|  | 4705aa541d | ||
|  | 3215d88a91 | ||
| 9b9a53f870 | |||
|  | 019ffe17d4 | ||
|  | 6cc3ad110c | ||
| bc496dd844 | |||
| a673b6a54d | |||
| 1bf2e4d187 | |||
|  | 96dd7a8fbd | ||
| 7905afa9f5 | |||
| 712bb40650 | |||
| 81d88d9f4d | |||
|  | e6c6f82c52 | ||
|  | d10d0c4e7f | ||
|  | 9c106d625a | ||
|  | 6795bbca31 | ||
|  | 77063418da | ||
|  | 2983b6fdf6 | ||
|  | 69f1f04f74 | ||
|  | 11a5fd09d6 | ||
|  | ff1fa98808 | ||
|  | d161c2dc35 | ||
|  | 7a06826cf1 | ||
|  | c3712b8e06 | ||
|  | 901ee77b84 | ||
| df16202865 | |||
| 3ff7c2c02a | |||
| fc6d07897f | |||
| f9c8e5c8ef | |||
| 8bfa0e74f8 | |||
| 9b73a937e7 | |||
|  | b0339bc5a4 | ||
|  | 3c23a947cc | ||
|  | 56111bb823 | ||
|  | 99445673f6 | ||
|  | 97a59643f7 | ||
|  | 579595f547 | ||
|  | 281ac5fc12 | ||
|  | d8fa903b02 | ||
|  | eaff0f3aeb | ||
|  | e8e20c01b2 | ||
|  | a4afc3ea2a | ||
| fa12b9a329 | |||
| 45fc7ded3a | |||
| 74de2d9742 | |||
| e759367d42 | |||
|  | 1b84f59273 | ||
|  | 1fb41a4300 | ||
|  | 287bac946f | ||
|  | 80c14be65e | ||
|  | d7a2a4852d | ||
|  | d185f2eaa7 | ||
|  | 813d4cd900 | ||
|  | 75c6c6b173 | ||
|  | 299d0de066 | ||
|  | 220ad5e3ee | ||
|  | ba5dc670a5 | ||
|  | 3fe75bc7cb | ||
|  | 45d49d8648 | ||
|  | 6013183361 | ||
|  | 4b882e8056 | ||
|  | 3f9ae6e7e7 | ||
|  | 909acd55cd | ||
|  | 4dd9e39e0d | ||
|  | b4c1317ab4 | ||
|  | a0ca362690 | ||
|  | 249b6e61ec | ||
| f36d6f3923 | |||
|  | 7adb253e25 | ||
| 808f1e0e8c | |||
|  | 873519e960 | ||
|  | 9aec4a3c26 | ||
|  | c438118fd7 | ||
|  | 70510d151b | ||
|  | 9e7bacb5a4 | ||
|  | 2ef1fa66a8 | ||
|  | cf76741ec6 | ||
|  | 497e7c1c40 | ||
|  | 888eacd3b8 | ||
|  | 321f0f51b5 | ||
|  | 17ec9c5545 | ||
|  | 30ad9578a2 | ||
|  | 9dce101586 | ||
|  | 97e264d0ff | ||
|  | 683a5e5bf5 | ||
|  | d4861a362c | ||
|  | 5ff3eae027 | ||
|  | 147dc15d26 | ||
|  | c61ea72949 | ||
|  | 86e8b9fe38 | ||
|  | 612e468889 | ||
|  | 4ea8d128c2 | ||
|  | e49b7f2f88 | ||
|  | aace3d47b9 | ||
|  | d5049949a4 | ||
|  | f1c7480e3c | ||
|  | 5adae5d6ff | ||
|  | a8412ace05 | ||
|  | 9fd1c2ad4b | ||
|  | 4cf3575353 | ||
|  | 804a810d68 | ||
| 3594ce877b | |||
| 9bae6b889a | |||
| 4014dfd5b9 | |||
| 67023c334b | |||
| a3de7026c8 | |||
| ee11678b1f | |||
|  | b3881d2636 | ||
| d060341168 | |||
| c772bcd514 | |||
| 467deee46f | |||
|  | 80fd6ab407 | ||
|  | 5534921bee | ||
|  | 5cffa05c7e | ||
|  | d50a2164d7 | ||
|  | 32ff766dbd | ||
|  | 01652d8cfe | ||
|  | 4d2dc7ba03 | ||
|  | 51d1beb1f3 | ||
|  | 249e2db87d | ||
|  | cf3535d16e | ||
|  | d61ee817f4 | ||
|  | 2a75516330 | ||
|  | b2087f14c4 | ||
|  | dd1ba266b2 | ||
|  | 1292d59563 | ||
|  | 9877ed9bf8 | ||
|  | f0dc0f3621 | ||
|  | 63b0a19f37 | 
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -88,6 +88,7 @@ Thumbs.db | |||||||
| # build directory # | # build directory # | ||||||
| ################### | ################### | ||||||
| build*/* | build*/* | ||||||
|  | Documentation/_build | ||||||
|  |  | ||||||
| # IDE related files # | # IDE related files # | ||||||
| ##################### | ##################### | ||||||
|   | |||||||
							
								
								
									
										56
									
								
								.travis.yml
									
									
									
									
									
								
							
							
						
						
									
										56
									
								
								.travis.yml
									
									
									
									
									
								
							| @@ -1,56 +0,0 @@ | |||||||
| language: cpp |  | ||||||
|  |  | ||||||
| cache: |  | ||||||
|   directories: |  | ||||||
|     - clang |  | ||||||
|  |  | ||||||
| matrix: |  | ||||||
|   include: |  | ||||||
|     - os:        osx |  | ||||||
|       osx_image: xcode8.3 |  | ||||||
|       compiler: clang |  | ||||||
|        |  | ||||||
| before_install: |  | ||||||
|     - export GRIDDIR=`pwd` |  | ||||||
|     - if [[ "$TRAVIS_OS_NAME" == "linux" ]] && [[ "$CC" == "clang" ]] && [ ! -e clang/bin ]; then wget $CLANG_LINK; tar -xf `basename $CLANG_LINK`; mkdir clang; mv clang+*/* clang/; fi |  | ||||||
|     - if [[ "$TRAVIS_OS_NAME" == "linux" ]] && [[ "$CC" == "clang" ]]; then export PATH="${GRIDDIR}/clang/bin:${PATH}"; fi |  | ||||||
|     - if [[ "$TRAVIS_OS_NAME" == "linux" ]] && [[ "$CC" == "clang" ]]; then export LD_LIBRARY_PATH="${GRIDDIR}/clang/lib:${LD_LIBRARY_PATH}"; fi |  | ||||||
|     - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; fi |  | ||||||
|     - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install libmpc openssl; fi |  | ||||||
|      |  | ||||||
| install: |  | ||||||
|     - export CWD=`pwd` |  | ||||||
|     - echo $CWD |  | ||||||
|     - export CC=$CC$VERSION |  | ||||||
|     - export CXX=$CXX$VERSION |  | ||||||
|     - echo $PATH |  | ||||||
|     - which autoconf |  | ||||||
|     - autoconf  --version |  | ||||||
|     - which automake |  | ||||||
|     - automake  --version |  | ||||||
|     - which $CC |  | ||||||
|     - $CC  --version |  | ||||||
|     - which $CXX |  | ||||||
|     - $CXX --version |  | ||||||
|     - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then export LDFLAGS='-L/usr/local/lib'; fi |  | ||||||
|     - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then export EXTRACONF='--with-openssl=/usr/local/opt/openssl'; fi |  | ||||||
|      |  | ||||||
| script: |  | ||||||
|     - ./bootstrap.sh |  | ||||||
|     - mkdir build |  | ||||||
|     - cd build |  | ||||||
|     - mkdir lime |  | ||||||
|     - cd lime |  | ||||||
|     - mkdir build |  | ||||||
|     - cd build |  | ||||||
|     - wget http://usqcd-software.github.io/downloads/c-lime/lime-1.3.2.tar.gz |  | ||||||
|     - tar xf lime-1.3.2.tar.gz |  | ||||||
|     - cd lime-1.3.2 |  | ||||||
|     - ./configure --prefix=$CWD/build/lime/install |  | ||||||
|     - make -j4 |  | ||||||
|     - make install |  | ||||||
|     - cd $CWD/build |  | ||||||
|     - ../configure --enable-simd=SSE4 --enable-comms=none --with-lime=$CWD/build/lime/install ${EXTRACONF} |  | ||||||
|     - make -j4  |  | ||||||
|     - ./benchmarks/Benchmark_dwf --threads 1 --debug-signals |  | ||||||
|     - make check |  | ||||||
| @@ -34,10 +34,15 @@ directory | |||||||
|  |  | ||||||
| #if defined __GNUC__ && __GNUC__>=6 | #if defined __GNUC__ && __GNUC__>=6 | ||||||
| #pragma GCC diagnostic ignored "-Wignored-attributes" | #pragma GCC diagnostic ignored "-Wignored-attributes" | ||||||
|  | #endif | ||||||
|  | #if defined __GNUC__ && __GNUC__>=6 | ||||||
|  | #pragma GCC diagnostic ignored "-Wpsabi" | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  //disables and intel compiler specific warning (in json.hpp) |  //disables and intel compiler specific warning (in json.hpp) | ||||||
|  | #ifdef __ICC | ||||||
| #pragma warning disable 488   | #pragma warning disable 488   | ||||||
|  | #endif | ||||||
|  |  | ||||||
| #ifdef __NVCC__ | #ifdef __NVCC__ | ||||||
|  //disables nvcc specific warning in json.hpp |  //disables nvcc specific warning in json.hpp | ||||||
|   | |||||||
| @@ -36,6 +36,7 @@ Author: paboyle <paboyle@ph.ed.ac.uk> | |||||||
| #include <Grid/GridCore.h> | #include <Grid/GridCore.h> | ||||||
| #include <Grid/qcd/QCD.h> | #include <Grid/qcd/QCD.h> | ||||||
| #include <Grid/qcd/spin/Spin.h> | #include <Grid/qcd/spin/Spin.h> | ||||||
|  | #include <Grid/qcd/gparity/Gparity.h> | ||||||
| #include <Grid/qcd/utils/Utils.h> | #include <Grid/qcd/utils/Utils.h> | ||||||
| #include <Grid/qcd/representations/Representations.h> | #include <Grid/qcd/representations/Representations.h> | ||||||
| NAMESPACE_CHECK(GridQCDCore); | NAMESPACE_CHECK(GridQCDCore); | ||||||
|   | |||||||
| @@ -54,9 +54,11 @@ Version.h: version-cache | |||||||
| include Make.inc | include Make.inc | ||||||
| include Eigen.inc | include Eigen.inc | ||||||
|  |  | ||||||
| extra_sources+=$(ZWILS_FERMION_FILES) |  | ||||||
| extra_sources+=$(WILS_FERMION_FILES) | extra_sources+=$(WILS_FERMION_FILES) | ||||||
| extra_sources+=$(STAG_FERMION_FILES) | extra_sources+=$(STAG_FERMION_FILES) | ||||||
|  | if BUILD_ZMOBIUS | ||||||
|  |   extra_sources+=$(ZWILS_FERMION_FILES) | ||||||
|  | endif | ||||||
| if BUILD_GPARITY | if BUILD_GPARITY | ||||||
|   extra_sources+=$(GP_FERMION_FILES) |   extra_sources+=$(GP_FERMION_FILES) | ||||||
| endif | endif | ||||||
|   | |||||||
| @@ -54,6 +54,7 @@ NAMESPACE_CHECK(BiCGSTAB); | |||||||
| #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> | ||||||
|  | #include <Grid/algorithms/iterative/ConjugateGradientMultiShiftMixedPrec.h> | ||||||
| #include <Grid/algorithms/iterative/BiCGSTABMixedPrec.h> | #include <Grid/algorithms/iterative/BiCGSTABMixedPrec.h> | ||||||
| #include <Grid/algorithms/iterative/BlockConjugateGradient.h> | #include <Grid/algorithms/iterative/BlockConjugateGradient.h> | ||||||
| #include <Grid/algorithms/iterative/ConjugateGradientReliableUpdate.h> | #include <Grid/algorithms/iterative/ConjugateGradientReliableUpdate.h> | ||||||
|   | |||||||
| @@ -31,6 +31,7 @@ Author: paboyle <paboyle@ph.ed.ac.uk> | |||||||
| #ifndef  GRID_ALGORITHM_COARSENED_MATRIX_H | #ifndef  GRID_ALGORITHM_COARSENED_MATRIX_H | ||||||
| #define  GRID_ALGORITHM_COARSENED_MATRIX_H | #define  GRID_ALGORITHM_COARSENED_MATRIX_H | ||||||
|  |  | ||||||
|  | #include <Grid/qcd/QCD.h> // needed for Dagger(Yes|No), Inverse(Yes|No) | ||||||
|  |  | ||||||
| NAMESPACE_BEGIN(Grid); | NAMESPACE_BEGIN(Grid); | ||||||
|  |  | ||||||
| @@ -59,12 +60,14 @@ inline void blockMaskedInnerProduct(Lattice<CComplex> &CoarseInner, | |||||||
| class Geometry { | class Geometry { | ||||||
| public: | public: | ||||||
|   int npoint; |   int npoint; | ||||||
|  |   int base; | ||||||
|   std::vector<int> directions   ; |   std::vector<int> directions   ; | ||||||
|   std::vector<int> displacements; |   std::vector<int> displacements; | ||||||
|  |   std::vector<int> points_dagger; | ||||||
|  |  | ||||||
|   Geometry(int _d)  { |   Geometry(int _d)  { | ||||||
|      |      | ||||||
|     int base = (_d==5) ? 1:0; |     base = (_d==5) ? 1:0; | ||||||
|  |  | ||||||
|     // make coarse grid stencil for 4d , not 5d |     // make coarse grid stencil for 4d , not 5d | ||||||
|     if ( _d==5 ) _d=4; |     if ( _d==5 ) _d=4; | ||||||
| @@ -72,16 +75,51 @@ public: | |||||||
|     npoint = 2*_d+1; |     npoint = 2*_d+1; | ||||||
|     directions.resize(npoint); |     directions.resize(npoint); | ||||||
|     displacements.resize(npoint); |     displacements.resize(npoint); | ||||||
|  |     points_dagger.resize(npoint); | ||||||
|     for(int d=0;d<_d;d++){ |     for(int d=0;d<_d;d++){ | ||||||
|       directions[d   ] = d+base; |       directions[d   ] = d+base; | ||||||
|       directions[d+_d] = d+base; |       directions[d+_d] = d+base; | ||||||
|       displacements[d  ] = +1; |       displacements[d  ] = +1; | ||||||
|       displacements[d+_d]= -1; |       displacements[d+_d]= -1; | ||||||
|  |       points_dagger[d   ] = d+_d; | ||||||
|  |       points_dagger[d+_d] = d; | ||||||
|     } |     } | ||||||
|     directions   [2*_d]=0; |     directions   [2*_d]=0; | ||||||
|     displacements[2*_d]=0; |     displacements[2*_d]=0; | ||||||
|  |     points_dagger[2*_d]=2*_d; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   int point(int dir, int disp) { | ||||||
|  |     assert(disp == -1 || disp == 0 || disp == 1); | ||||||
|  |     assert(base+0 <= dir && dir < base+4); | ||||||
|  |  | ||||||
|  |     // directions faster index = new indexing | ||||||
|  |     // 4d (base = 0): | ||||||
|  |     // point 0  1  2  3  4  5  6  7  8 | ||||||
|  |     // dir   0  1  2  3  0  1  2  3  0 | ||||||
|  |     // disp +1 +1 +1 +1 -1 -1 -1 -1  0 | ||||||
|  |     // 5d (base = 1): | ||||||
|  |     // point 0  1  2  3  4  5  6  7  8 | ||||||
|  |     // dir   1  2  3  4  1  2  3  4  0 | ||||||
|  |     // disp +1 +1 +1 +1 -1 -1 -1 -1  0 | ||||||
|  |  | ||||||
|  |     // displacements faster index = old indexing | ||||||
|  |     // 4d (base = 0): | ||||||
|  |     // point 0  1  2  3  4  5  6  7  8 | ||||||
|  |     // dir   0  0  1  1  2  2  3  3  0 | ||||||
|  |     // disp +1 -1 +1 -1 +1 -1 +1 -1  0 | ||||||
|  |     // 5d (base = 1): | ||||||
|  |     // point 0  1  2  3  4  5  6  7  8 | ||||||
|  |     // dir   1  1  2  2  3  3  4  4  0 | ||||||
|  |     // disp +1 -1 +1 -1 +1 -1 +1 -1  0 | ||||||
|  |  | ||||||
|  |     if(dir == 0 and disp == 0) | ||||||
|  |       return 8; | ||||||
|  |     else // New indexing | ||||||
|  |       return (1 - disp) / 2 * 4 + dir - base; | ||||||
|  |     // else // Old indexing | ||||||
|  |     //   return (4 * (dir - base) + 1 - disp) / 2; | ||||||
|  |   } | ||||||
| }; | }; | ||||||
|    |    | ||||||
| template<class Fobj,class CComplex,int nbasis> | template<class Fobj,class CComplex,int nbasis> | ||||||
| @@ -258,7 +296,7 @@ public: | |||||||
| // Fine Object == (per site) type of fine field | // Fine Object == (per site) type of fine field | ||||||
| // nbasis      == number of deflation vectors | // nbasis      == number of deflation vectors | ||||||
| template<class Fobj,class CComplex,int nbasis> | template<class Fobj,class CComplex,int nbasis> | ||||||
| class CoarsenedMatrix : public SparseMatrixBase<Lattice<iVector<CComplex,nbasis > > >  { | class CoarsenedMatrix : public CheckerBoardedSparseMatrixBase<Lattice<iVector<CComplex,nbasis > > >  { | ||||||
| public: | public: | ||||||
|      |      | ||||||
|   typedef iVector<CComplex,nbasis >           siteVector; |   typedef iVector<CComplex,nbasis >           siteVector; | ||||||
| @@ -268,33 +306,59 @@ public: | |||||||
|   typedef iMatrix<CComplex,nbasis >  Cobj; |   typedef iMatrix<CComplex,nbasis >  Cobj; | ||||||
|   typedef Lattice< CComplex >   CoarseScalar; // used for inner products on fine field |   typedef Lattice< CComplex >   CoarseScalar; // used for inner products on fine field | ||||||
|   typedef Lattice<Fobj >        FineField; |   typedef Lattice<Fobj >        FineField; | ||||||
|  |   typedef CoarseVector FermionField; | ||||||
|  |  | ||||||
|  |   // enrich interface, use default implementation as in FermionOperator /////// | ||||||
|  |   void Dminus(CoarseVector const& in, CoarseVector& out) { out = in; } | ||||||
|  |   void DminusDag(CoarseVector const& in, CoarseVector& out) { out = in; } | ||||||
|  |   void ImportPhysicalFermionSource(CoarseVector const& input, CoarseVector& imported) { imported = input; } | ||||||
|  |   void ImportUnphysicalFermion(CoarseVector const& input, CoarseVector& imported) { imported = input; } | ||||||
|  |   void ExportPhysicalFermionSolution(CoarseVector const& solution, CoarseVector& exported) { exported = solution; }; | ||||||
|  |   void ExportPhysicalFermionSource(CoarseVector const& solution, CoarseVector& exported) { exported = solution; }; | ||||||
|  |  | ||||||
|   //////////////////// |   //////////////////// | ||||||
|   // Data members |   // Data members | ||||||
|   //////////////////// |   //////////////////// | ||||||
|   Geometry         geom; |   Geometry         geom; | ||||||
|   GridBase *       _grid;  |   GridBase *       _grid;  | ||||||
|  |   GridBase*        _cbgrid; | ||||||
|   int hermitian; |   int hermitian; | ||||||
|  |  | ||||||
|   CartesianStencil<siteVector,siteVector,int> Stencil;  |   CartesianStencil<siteVector,siteVector,int> Stencil;  | ||||||
|  |   CartesianStencil<siteVector,siteVector,int> StencilEven; | ||||||
|  |   CartesianStencil<siteVector,siteVector,int> StencilOdd; | ||||||
|  |  | ||||||
|   std::vector<CoarseMatrix> A; |   std::vector<CoarseMatrix> A; | ||||||
|      |   std::vector<CoarseMatrix> Aeven; | ||||||
|  |   std::vector<CoarseMatrix> Aodd; | ||||||
|  |  | ||||||
|  |   CoarseMatrix AselfInv; | ||||||
|  |   CoarseMatrix AselfInvEven; | ||||||
|  |   CoarseMatrix AselfInvOdd; | ||||||
|  |  | ||||||
|  |   Vector<RealD> dag_factor; | ||||||
|  |  | ||||||
|   /////////////////////// |   /////////////////////// | ||||||
|   // Interface |   // Interface | ||||||
|   /////////////////////// |   /////////////////////// | ||||||
|   GridBase * Grid(void)         { return _grid; };   // this is all the linalg routines need to know |   GridBase * Grid(void)         { return _grid; };   // this is all the linalg routines need to know | ||||||
|  |   GridBase * RedBlackGrid()     { return _cbgrid; }; | ||||||
|  |  | ||||||
|  |   int ConstEE() { return 0; } | ||||||
|  |  | ||||||
|   void M (const CoarseVector &in, CoarseVector &out) |   void M (const CoarseVector &in, CoarseVector &out) | ||||||
|   { |   { | ||||||
|     conformable(_grid,in.Grid()); |     conformable(_grid,in.Grid()); | ||||||
|     conformable(in.Grid(),out.Grid()); |     conformable(in.Grid(),out.Grid()); | ||||||
|  |     out.Checkerboard() = in.Checkerboard(); | ||||||
|  |  | ||||||
|     SimpleCompressor<siteVector> compressor; |     SimpleCompressor<siteVector> compressor; | ||||||
|  |  | ||||||
|     Stencil.HaloExchange(in,compressor); |     Stencil.HaloExchange(in,compressor); | ||||||
|     autoView( in_v , in, AcceleratorRead); |     autoView( in_v , in, AcceleratorRead); | ||||||
|     autoView( out_v , out, AcceleratorWrite); |     autoView( out_v , out, AcceleratorWrite); | ||||||
|  |     autoView( Stencil_v  , Stencil, AcceleratorRead); | ||||||
|  |     auto& geom_v = geom; | ||||||
|     typedef LatticeView<Cobj> Aview; |     typedef LatticeView<Cobj> Aview; | ||||||
|        |        | ||||||
|     Vector<Aview> AcceleratorViewContainer; |     Vector<Aview> AcceleratorViewContainer; | ||||||
| @@ -316,14 +380,14 @@ public: | |||||||
|       int ptype; |       int ptype; | ||||||
|       StencilEntry *SE; |       StencilEntry *SE; | ||||||
|  |  | ||||||
|       for(int point=0;point<geom.npoint;point++){ |       for(int point=0;point<geom_v.npoint;point++){ | ||||||
|  |  | ||||||
| 	SE=Stencil.GetEntry(ptype,point,ss); | 	SE=Stencil_v.GetEntry(ptype,point,ss); | ||||||
| 	   | 	   | ||||||
| 	if(SE->_is_local) {  | 	if(SE->_is_local) {  | ||||||
| 	  nbr = coalescedReadPermute(in_v[SE->_offset],ptype,SE->_permute); | 	  nbr = coalescedReadPermute(in_v[SE->_offset],ptype,SE->_permute); | ||||||
| 	} else { | 	} else { | ||||||
| 	  nbr = coalescedRead(Stencil.CommBuf()[SE->_offset]); | 	  nbr = coalescedRead(Stencil_v.CommBuf()[SE->_offset]); | ||||||
| 	} | 	} | ||||||
| 	acceleratorSynchronise(); | 	acceleratorSynchronise(); | ||||||
|  |  | ||||||
| @@ -344,12 +408,74 @@ public: | |||||||
|       return M(in,out); |       return M(in,out); | ||||||
|     } else { |     } else { | ||||||
|       // corresponds to Galerkin coarsening |       // corresponds to Galerkin coarsening | ||||||
|       CoarseVector tmp(Grid()); |       return MdagNonHermitian(in, out); | ||||||
|       G5C(tmp, in);  |  | ||||||
|       M(tmp, out); |  | ||||||
|       G5C(out, out); |  | ||||||
|     } |     } | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
|  |   void MdagNonHermitian(const CoarseVector &in, CoarseVector &out) | ||||||
|  |   { | ||||||
|  |     conformable(_grid,in.Grid()); | ||||||
|  |     conformable(in.Grid(),out.Grid()); | ||||||
|  |     out.Checkerboard() = in.Checkerboard(); | ||||||
|  |  | ||||||
|  |     SimpleCompressor<siteVector> compressor; | ||||||
|  |  | ||||||
|  |     Stencil.HaloExchange(in,compressor); | ||||||
|  |     autoView( in_v , in, AcceleratorRead); | ||||||
|  |     autoView( out_v , out, AcceleratorWrite); | ||||||
|  |     autoView( Stencil_v  , Stencil, AcceleratorRead); | ||||||
|  |     auto& geom_v = geom; | ||||||
|  |     typedef LatticeView<Cobj> Aview; | ||||||
|  |  | ||||||
|  |     Vector<Aview> AcceleratorViewContainer; | ||||||
|  |  | ||||||
|  |     for(int p=0;p<geom.npoint;p++) AcceleratorViewContainer.push_back(A[p].View(AcceleratorRead)); | ||||||
|  |     Aview *Aview_p = & AcceleratorViewContainer[0]; | ||||||
|  |  | ||||||
|  |     const int Nsimd = CComplex::Nsimd(); | ||||||
|  |     typedef decltype(coalescedRead(in_v[0])) calcVector; | ||||||
|  |     typedef decltype(coalescedRead(in_v[0](0))) calcComplex; | ||||||
|  |  | ||||||
|  |     int osites=Grid()->oSites(); | ||||||
|  |  | ||||||
|  |     Vector<int> points(geom.npoint, 0); | ||||||
|  |     for(int p=0; p<geom.npoint; p++) | ||||||
|  |       points[p] = geom.points_dagger[p]; | ||||||
|  |  | ||||||
|  |     auto points_p = &points[0]; | ||||||
|  |  | ||||||
|  |     RealD* dag_factor_p = &dag_factor[0]; | ||||||
|  |  | ||||||
|  |     accelerator_for(sss, Grid()->oSites()*nbasis, Nsimd, { | ||||||
|  |       int ss = sss/nbasis; | ||||||
|  |       int b  = sss%nbasis; | ||||||
|  |       calcComplex res = Zero(); | ||||||
|  |       calcVector nbr; | ||||||
|  |       int ptype; | ||||||
|  |       StencilEntry *SE; | ||||||
|  |  | ||||||
|  |       for(int p=0;p<geom_v.npoint;p++){ | ||||||
|  |         int point = points_p[p]; | ||||||
|  |  | ||||||
|  | 	SE=Stencil_v.GetEntry(ptype,point,ss); | ||||||
|  |  | ||||||
|  | 	if(SE->_is_local) { | ||||||
|  | 	  nbr = coalescedReadPermute(in_v[SE->_offset],ptype,SE->_permute); | ||||||
|  | 	} else { | ||||||
|  | 	  nbr = coalescedRead(Stencil_v.CommBuf()[SE->_offset]); | ||||||
|  | 	} | ||||||
|  | 	acceleratorSynchronise(); | ||||||
|  |  | ||||||
|  | 	for(int bb=0;bb<nbasis;bb++) { | ||||||
|  | 	  res = res + dag_factor_p[b*nbasis+bb]*coalescedRead(Aview_p[point][ss](b,bb))*nbr(bb); | ||||||
|  | 	} | ||||||
|  |       } | ||||||
|  |       coalescedWrite(out_v[ss](b),res); | ||||||
|  |       }); | ||||||
|  |  | ||||||
|  |     for(int p=0;p<geom.npoint;p++) AcceleratorViewContainer[p].ViewClose(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   void MdirComms(const CoarseVector &in) |   void MdirComms(const CoarseVector &in) | ||||||
|   { |   { | ||||||
|     SimpleCompressor<siteVector> compressor; |     SimpleCompressor<siteVector> compressor; | ||||||
| @@ -359,6 +485,7 @@ public: | |||||||
|   { |   { | ||||||
|     conformable(_grid,in.Grid()); |     conformable(_grid,in.Grid()); | ||||||
|     conformable(_grid,out.Grid()); |     conformable(_grid,out.Grid()); | ||||||
|  |     out.Checkerboard() = in.Checkerboard(); | ||||||
|  |  | ||||||
|     typedef LatticeView<Cobj> Aview; |     typedef LatticeView<Cobj> Aview; | ||||||
|     Vector<Aview> AcceleratorViewContainer; |     Vector<Aview> AcceleratorViewContainer; | ||||||
| @@ -367,6 +494,7 @@ public: | |||||||
|  |  | ||||||
|     autoView( out_v , out, AcceleratorWrite); |     autoView( out_v , out, AcceleratorWrite); | ||||||
|     autoView( in_v  , in, AcceleratorRead); |     autoView( in_v  , in, AcceleratorRead); | ||||||
|  |     autoView( Stencil_v  , Stencil, AcceleratorRead); | ||||||
|  |  | ||||||
|     const int Nsimd = CComplex::Nsimd(); |     const int Nsimd = CComplex::Nsimd(); | ||||||
|     typedef decltype(coalescedRead(in_v[0])) calcVector; |     typedef decltype(coalescedRead(in_v[0])) calcVector; | ||||||
| @@ -380,12 +508,12 @@ public: | |||||||
|       int ptype; |       int ptype; | ||||||
|       StencilEntry *SE; |       StencilEntry *SE; | ||||||
|  |  | ||||||
|       SE=Stencil.GetEntry(ptype,point,ss); |       SE=Stencil_v.GetEntry(ptype,point,ss); | ||||||
| 	   | 	   | ||||||
|       if(SE->_is_local) {  |       if(SE->_is_local) {  | ||||||
| 	nbr = coalescedReadPermute(in_v[SE->_offset],ptype,SE->_permute); | 	nbr = coalescedReadPermute(in_v[SE->_offset],ptype,SE->_permute); | ||||||
|       } else { |       } else { | ||||||
| 	nbr = coalescedRead(Stencil.CommBuf()[SE->_offset]); | 	nbr = coalescedRead(Stencil_v.CommBuf()[SE->_offset]); | ||||||
|       } |       } | ||||||
|       acceleratorSynchronise(); |       acceleratorSynchronise(); | ||||||
|  |  | ||||||
| @@ -413,34 +541,7 @@ public: | |||||||
|  |  | ||||||
|     this->MdirComms(in); |     this->MdirComms(in); | ||||||
|  |  | ||||||
|     int ndim = in.Grid()->Nd(); |     MdirCalc(in,out,geom.point(dir,disp)); | ||||||
|  |  | ||||||
|     ////////////// |  | ||||||
|     // 4D action like wilson |  | ||||||
|     // 0+ => 0  |  | ||||||
|     // 0- => 1 |  | ||||||
|     // 1+ => 2  |  | ||||||
|     // 1- => 3 |  | ||||||
|     // etc.. |  | ||||||
|     ////////////// |  | ||||||
|     // 5D action like DWF |  | ||||||
|     // 1+ => 0  |  | ||||||
|     // 1- => 1 |  | ||||||
|     // 2+ => 2  |  | ||||||
|     // 2- => 3 |  | ||||||
|     // etc.. |  | ||||||
|     auto point = [dir, disp, ndim](){ |  | ||||||
|       if(dir == 0 and disp == 0) |  | ||||||
| 	return 8; |  | ||||||
|       else if ( ndim==4 ) {  |  | ||||||
| 	return (4 * dir + 1 - disp) / 2; |  | ||||||
|       } else {  |  | ||||||
| 	return (4 * (dir-1) + 1 - disp) / 2; |  | ||||||
|       } |  | ||||||
|     }(); |  | ||||||
|  |  | ||||||
|     MdirCalc(in,out,point); |  | ||||||
|  |  | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
|   void Mdiag(const CoarseVector &in, CoarseVector &out) |   void Mdiag(const CoarseVector &in, CoarseVector &out) | ||||||
| @@ -449,23 +550,298 @@ public: | |||||||
|     MdirCalc(in, out, point); // No comms |     MdirCalc(in, out, point); // No comms | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
|    |   void Mooee(const CoarseVector &in, CoarseVector &out) { | ||||||
|  CoarsenedMatrix(GridCartesian &CoarseGrid, int hermitian_=0) 	:  |     MooeeInternal(in, out, DaggerNo, InverseNo); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void MooeeInv(const CoarseVector &in, CoarseVector &out) { | ||||||
|  |     MooeeInternal(in, out, DaggerNo, InverseYes); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void MooeeDag(const CoarseVector &in, CoarseVector &out) { | ||||||
|  |     MooeeInternal(in, out, DaggerYes, InverseNo); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void MooeeInvDag(const CoarseVector &in, CoarseVector &out) { | ||||||
|  |     MooeeInternal(in, out, DaggerYes, InverseYes); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void Meooe(const CoarseVector &in, CoarseVector &out) { | ||||||
|  |     if(in.Checkerboard() == Odd) { | ||||||
|  |       DhopEO(in, out, DaggerNo); | ||||||
|  |     } else { | ||||||
|  |       DhopOE(in, out, DaggerNo); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void MeooeDag(const CoarseVector &in, CoarseVector &out) { | ||||||
|  |     if(in.Checkerboard() == Odd) { | ||||||
|  |       DhopEO(in, out, DaggerYes); | ||||||
|  |     } else { | ||||||
|  |       DhopOE(in, out, DaggerYes); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void Dhop(const CoarseVector &in, CoarseVector &out, int dag) { | ||||||
|  |     conformable(in.Grid(), _grid); // verifies full grid | ||||||
|  |     conformable(in.Grid(), out.Grid()); | ||||||
|  |  | ||||||
|  |     out.Checkerboard() = in.Checkerboard(); | ||||||
|  |  | ||||||
|  |     DhopInternal(Stencil, A, in, out, dag); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void DhopOE(const CoarseVector &in, CoarseVector &out, int dag) { | ||||||
|  |     conformable(in.Grid(), _cbgrid);    // verifies half grid | ||||||
|  |     conformable(in.Grid(), out.Grid()); // drops the cb check | ||||||
|  |  | ||||||
|  |     assert(in.Checkerboard() == Even); | ||||||
|  |     out.Checkerboard() = Odd; | ||||||
|  |  | ||||||
|  |     DhopInternal(StencilEven, Aodd, in, out, dag); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void DhopEO(const CoarseVector &in, CoarseVector &out, int dag) { | ||||||
|  |     conformable(in.Grid(), _cbgrid);    // verifies half grid | ||||||
|  |     conformable(in.Grid(), out.Grid()); // drops the cb check | ||||||
|  |  | ||||||
|  |     assert(in.Checkerboard() == Odd); | ||||||
|  |     out.Checkerboard() = Even; | ||||||
|  |  | ||||||
|  |     DhopInternal(StencilOdd, Aeven, in, out, dag); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void MooeeInternal(const CoarseVector &in, CoarseVector &out, int dag, int inv) { | ||||||
|  |     out.Checkerboard() = in.Checkerboard(); | ||||||
|  |     assert(in.Checkerboard() == Odd || in.Checkerboard() == Even); | ||||||
|  |  | ||||||
|  |     CoarseMatrix *Aself = nullptr; | ||||||
|  |     if(in.Grid()->_isCheckerBoarded) { | ||||||
|  |       if(in.Checkerboard() == Odd) { | ||||||
|  |         Aself = (inv) ? &AselfInvOdd : &Aodd[geom.npoint-1]; | ||||||
|  |         DselfInternal(StencilOdd, *Aself, in, out, dag); | ||||||
|  |       } else { | ||||||
|  |         Aself = (inv) ? &AselfInvEven : &Aeven[geom.npoint-1]; | ||||||
|  |         DselfInternal(StencilEven, *Aself, in, out, dag); | ||||||
|  |       } | ||||||
|  |     } else { | ||||||
|  |       Aself = (inv) ? &AselfInv : &A[geom.npoint-1]; | ||||||
|  |       DselfInternal(Stencil, *Aself, in, out, dag); | ||||||
|  |     } | ||||||
|  |     assert(Aself != nullptr); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void DselfInternal(CartesianStencil<siteVector,siteVector,int> &st, CoarseMatrix &a, | ||||||
|  |                        const CoarseVector &in, CoarseVector &out, int dag) { | ||||||
|  |     int point = geom.npoint-1; | ||||||
|  |     autoView( out_v, out, AcceleratorWrite); | ||||||
|  |     autoView( in_v,  in,  AcceleratorRead); | ||||||
|  |     autoView( st_v,  st,  AcceleratorRead); | ||||||
|  |     autoView( a_v,   a,   AcceleratorRead); | ||||||
|  |  | ||||||
|  |     const int Nsimd = CComplex::Nsimd(); | ||||||
|  |     typedef decltype(coalescedRead(in_v[0])) calcVector; | ||||||
|  |     typedef decltype(coalescedRead(in_v[0](0))) calcComplex; | ||||||
|  |  | ||||||
|  |     RealD* dag_factor_p = &dag_factor[0]; | ||||||
|  |  | ||||||
|  |     if(dag) { | ||||||
|  |       accelerator_for(sss, in.Grid()->oSites()*nbasis, Nsimd, { | ||||||
|  |         int ss = sss/nbasis; | ||||||
|  |         int b  = sss%nbasis; | ||||||
|  |         calcComplex res = Zero(); | ||||||
|  |         calcVector nbr; | ||||||
|  |         int ptype; | ||||||
|  |         StencilEntry *SE; | ||||||
|  |  | ||||||
|  |         SE=st_v.GetEntry(ptype,point,ss); | ||||||
|  |  | ||||||
|  |         if(SE->_is_local) { | ||||||
|  |           nbr = coalescedReadPermute(in_v[SE->_offset],ptype,SE->_permute); | ||||||
|  |         } else { | ||||||
|  |           nbr = coalescedRead(st_v.CommBuf()[SE->_offset]); | ||||||
|  |         } | ||||||
|  |         acceleratorSynchronise(); | ||||||
|  |  | ||||||
|  |         for(int bb=0;bb<nbasis;bb++) { | ||||||
|  |           res = res + dag_factor_p[b*nbasis+bb]*coalescedRead(a_v[ss](b,bb))*nbr(bb); | ||||||
|  |         } | ||||||
|  |         coalescedWrite(out_v[ss](b),res); | ||||||
|  |       }); | ||||||
|  |     } else { | ||||||
|  |       accelerator_for(sss, in.Grid()->oSites()*nbasis, Nsimd, { | ||||||
|  |         int ss = sss/nbasis; | ||||||
|  |         int b  = sss%nbasis; | ||||||
|  |         calcComplex res = Zero(); | ||||||
|  |         calcVector nbr; | ||||||
|  |         int ptype; | ||||||
|  |         StencilEntry *SE; | ||||||
|  |  | ||||||
|  |         SE=st_v.GetEntry(ptype,point,ss); | ||||||
|  |  | ||||||
|  |         if(SE->_is_local) { | ||||||
|  |           nbr = coalescedReadPermute(in_v[SE->_offset],ptype,SE->_permute); | ||||||
|  |         } else { | ||||||
|  |           nbr = coalescedRead(st_v.CommBuf()[SE->_offset]); | ||||||
|  |         } | ||||||
|  |         acceleratorSynchronise(); | ||||||
|  |  | ||||||
|  |         for(int bb=0;bb<nbasis;bb++) { | ||||||
|  |           res = res + coalescedRead(a_v[ss](b,bb))*nbr(bb); | ||||||
|  |         } | ||||||
|  |         coalescedWrite(out_v[ss](b),res); | ||||||
|  |       }); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void DhopInternal(CartesianStencil<siteVector,siteVector,int> &st, std::vector<CoarseMatrix> &a, | ||||||
|  |                     const CoarseVector &in, CoarseVector &out, int dag) { | ||||||
|  |     SimpleCompressor<siteVector> compressor; | ||||||
|  |  | ||||||
|  |     st.HaloExchange(in,compressor); | ||||||
|  |     autoView( in_v,  in,  AcceleratorRead); | ||||||
|  |     autoView( out_v, out, AcceleratorWrite); | ||||||
|  |     autoView( st_v , st,  AcceleratorRead); | ||||||
|  |     typedef LatticeView<Cobj> Aview; | ||||||
|  |  | ||||||
|  |     // determine in what order we need the points | ||||||
|  |     int npoint = geom.npoint-1; | ||||||
|  |     Vector<int> points(npoint, 0); | ||||||
|  |     for(int p=0; p<npoint; p++) | ||||||
|  |       points[p] = (dag && !hermitian) ? geom.points_dagger[p] : p; | ||||||
|  |  | ||||||
|  |     auto points_p = &points[0]; | ||||||
|  |  | ||||||
|  |     Vector<Aview> AcceleratorViewContainer; | ||||||
|  |     for(int p=0;p<npoint;p++) AcceleratorViewContainer.push_back(a[p].View(AcceleratorRead)); | ||||||
|  |     Aview *Aview_p = & AcceleratorViewContainer[0]; | ||||||
|  |  | ||||||
|  |     const int Nsimd = CComplex::Nsimd(); | ||||||
|  |     typedef decltype(coalescedRead(in_v[0])) calcVector; | ||||||
|  |     typedef decltype(coalescedRead(in_v[0](0))) calcComplex; | ||||||
|  |  | ||||||
|  |     RealD* dag_factor_p = &dag_factor[0]; | ||||||
|  |  | ||||||
|  |     if(dag) { | ||||||
|  |       accelerator_for(sss, in.Grid()->oSites()*nbasis, Nsimd, { | ||||||
|  |         int ss = sss/nbasis; | ||||||
|  |         int b  = sss%nbasis; | ||||||
|  |         calcComplex res = Zero(); | ||||||
|  |         calcVector nbr; | ||||||
|  |         int ptype; | ||||||
|  |         StencilEntry *SE; | ||||||
|  |  | ||||||
|  |         for(int p=0;p<npoint;p++){ | ||||||
|  |           int point = points_p[p]; | ||||||
|  |           SE=st_v.GetEntry(ptype,point,ss); | ||||||
|  |  | ||||||
|  |           if(SE->_is_local) { | ||||||
|  |             nbr = coalescedReadPermute(in_v[SE->_offset],ptype,SE->_permute); | ||||||
|  |           } else { | ||||||
|  |             nbr = coalescedRead(st_v.CommBuf()[SE->_offset]); | ||||||
|  |           } | ||||||
|  |           acceleratorSynchronise(); | ||||||
|  |  | ||||||
|  |           for(int bb=0;bb<nbasis;bb++) { | ||||||
|  |             res = res + dag_factor_p[b*nbasis+bb]*coalescedRead(Aview_p[point][ss](b,bb))*nbr(bb); | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |         coalescedWrite(out_v[ss](b),res); | ||||||
|  |       }); | ||||||
|  |     } else { | ||||||
|  |       accelerator_for(sss, in.Grid()->oSites()*nbasis, Nsimd, { | ||||||
|  |         int ss = sss/nbasis; | ||||||
|  |         int b  = sss%nbasis; | ||||||
|  |         calcComplex res = Zero(); | ||||||
|  |         calcVector nbr; | ||||||
|  |         int ptype; | ||||||
|  |         StencilEntry *SE; | ||||||
|  |  | ||||||
|  |         for(int p=0;p<npoint;p++){ | ||||||
|  |           int point = points_p[p]; | ||||||
|  |           SE=st_v.GetEntry(ptype,point,ss); | ||||||
|  |  | ||||||
|  |           if(SE->_is_local) { | ||||||
|  |             nbr = coalescedReadPermute(in_v[SE->_offset],ptype,SE->_permute); | ||||||
|  |           } else { | ||||||
|  |             nbr = coalescedRead(st_v.CommBuf()[SE->_offset]); | ||||||
|  |           } | ||||||
|  |           acceleratorSynchronise(); | ||||||
|  |  | ||||||
|  |           for(int bb=0;bb<nbasis;bb++) { | ||||||
|  |             res = res + coalescedRead(Aview_p[point][ss](b,bb))*nbr(bb); | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |         coalescedWrite(out_v[ss](b),res); | ||||||
|  |       }); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     for(int p=0;p<npoint;p++) AcceleratorViewContainer[p].ViewClose(); | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   CoarsenedMatrix(GridCartesian &CoarseGrid, int hermitian_=0) 	: | ||||||
|     _grid(&CoarseGrid), |     _grid(&CoarseGrid), | ||||||
|  |     _cbgrid(new GridRedBlackCartesian(&CoarseGrid)), | ||||||
|     geom(CoarseGrid._ndimension), |     geom(CoarseGrid._ndimension), | ||||||
|     hermitian(hermitian_), |     hermitian(hermitian_), | ||||||
|     Stencil(&CoarseGrid,geom.npoint,Even,geom.directions,geom.displacements,0), |     Stencil(&CoarseGrid,geom.npoint,Even,geom.directions,geom.displacements,0), | ||||||
|       A(geom.npoint,&CoarseGrid) |     StencilEven(_cbgrid,geom.npoint,Even,geom.directions,geom.displacements,0), | ||||||
|  |     StencilOdd(_cbgrid,geom.npoint,Odd,geom.directions,geom.displacements,0), | ||||||
|  |     A(geom.npoint,&CoarseGrid), | ||||||
|  |     Aeven(geom.npoint,_cbgrid), | ||||||
|  |     Aodd(geom.npoint,_cbgrid), | ||||||
|  |     AselfInv(&CoarseGrid), | ||||||
|  |     AselfInvEven(_cbgrid), | ||||||
|  |     AselfInvOdd(_cbgrid), | ||||||
|  |     dag_factor(nbasis*nbasis) | ||||||
|   { |   { | ||||||
|  |     fillFactor(); | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
|  |   CoarsenedMatrix(GridCartesian &CoarseGrid, GridRedBlackCartesian &CoarseRBGrid, int hermitian_=0) 	: | ||||||
|  |  | ||||||
|  |     _grid(&CoarseGrid), | ||||||
|  |     _cbgrid(&CoarseRBGrid), | ||||||
|  |     geom(CoarseGrid._ndimension), | ||||||
|  |     hermitian(hermitian_), | ||||||
|  |     Stencil(&CoarseGrid,geom.npoint,Even,geom.directions,geom.displacements,0), | ||||||
|  |     StencilEven(&CoarseRBGrid,geom.npoint,Even,geom.directions,geom.displacements,0), | ||||||
|  |     StencilOdd(&CoarseRBGrid,geom.npoint,Odd,geom.directions,geom.displacements,0), | ||||||
|  |     A(geom.npoint,&CoarseGrid), | ||||||
|  |     Aeven(geom.npoint,&CoarseRBGrid), | ||||||
|  |     Aodd(geom.npoint,&CoarseRBGrid), | ||||||
|  |     AselfInv(&CoarseGrid), | ||||||
|  |     AselfInvEven(&CoarseRBGrid), | ||||||
|  |     AselfInvOdd(&CoarseRBGrid), | ||||||
|  |     dag_factor(nbasis*nbasis) | ||||||
|  |   { | ||||||
|  |     fillFactor(); | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   void fillFactor() { | ||||||
|  |     Eigen::MatrixXd dag_factor_eigen = Eigen::MatrixXd::Ones(nbasis, nbasis); | ||||||
|  |     if(!hermitian) { | ||||||
|  |       const int nb = nbasis/2; | ||||||
|  |       dag_factor_eigen.block(0,nb,nb,nb) *= -1.0; | ||||||
|  |       dag_factor_eigen.block(nb,0,nb,nb) *= -1.0; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // GPU readable prefactor | ||||||
|  |     thread_for(i, nbasis*nbasis, { | ||||||
|  |       int j = i/nbasis; | ||||||
|  |       int k = i%nbasis; | ||||||
|  |       dag_factor[i] = dag_factor_eigen(j, k); | ||||||
|  |     }); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   void CoarsenOperator(GridBase *FineGrid,LinearOperatorBase<Lattice<Fobj> > &linop, |   void CoarsenOperator(GridBase *FineGrid,LinearOperatorBase<Lattice<Fobj> > &linop, | ||||||
| 		       Aggregation<Fobj,CComplex,nbasis> & Subspace) | 		       Aggregation<Fobj,CComplex,nbasis> & Subspace) | ||||||
|   { |   { | ||||||
|     typedef Lattice<typename Fobj::tensor_reduced> FineComplexField; |     typedef Lattice<typename Fobj::tensor_reduced> FineComplexField; | ||||||
|     typedef typename Fobj::scalar_type scalar_type; |     typedef typename Fobj::scalar_type scalar_type; | ||||||
|  |  | ||||||
|  |     std::cout << GridLogMessage<< "CoarsenMatrix "<< std::endl; | ||||||
|  |  | ||||||
|     FineComplexField one(FineGrid); one=scalar_type(1.0,0.0); |     FineComplexField one(FineGrid); one=scalar_type(1.0,0.0); | ||||||
|     FineComplexField zero(FineGrid); zero=scalar_type(0.0,0.0); |     FineComplexField zero(FineGrid); zero=scalar_type(0.0,0.0); | ||||||
|  |  | ||||||
| @@ -496,11 +872,13 @@ public: | |||||||
|  |  | ||||||
|     CoarseScalar InnerProd(Grid());  |     CoarseScalar InnerProd(Grid());  | ||||||
|  |  | ||||||
|  |     std::cout << GridLogMessage<< "CoarsenMatrix Orthog "<< std::endl; | ||||||
|     // Orthogonalise the subblocks over the basis |     // Orthogonalise the subblocks over the basis | ||||||
|     blockOrthogonalise(InnerProd,Subspace.subspace); |     blockOrthogonalise(InnerProd,Subspace.subspace); | ||||||
|  |  | ||||||
|     // Compute the matrix elements of linop between this orthonormal |     // Compute the matrix elements of linop between this orthonormal | ||||||
|     // set of vectors. |     // set of vectors. | ||||||
|  |     std::cout << GridLogMessage<< "CoarsenMatrix masks "<< std::endl; | ||||||
|     int self_stencil=-1; |     int self_stencil=-1; | ||||||
|     for(int p=0;p<geom.npoint;p++) |     for(int p=0;p<geom.npoint;p++) | ||||||
|     {  |     {  | ||||||
| @@ -539,7 +917,7 @@ public: | |||||||
|  |  | ||||||
|       phi=Subspace.subspace[i]; |       phi=Subspace.subspace[i]; | ||||||
|  |  | ||||||
|       //      std::cout << GridLogMessage<< "CoarsenMatrix vector "<<i << std::endl; |       std::cout << GridLogMessage<< "CoarsenMatrix vector "<<i << std::endl; | ||||||
|       linop.OpDirAll(phi,Mphi_p); |       linop.OpDirAll(phi,Mphi_p); | ||||||
|       linop.OpDiag  (phi,Mphi_p[geom.npoint-1]); |       linop.OpDiag  (phi,Mphi_p[geom.npoint-1]); | ||||||
|  |  | ||||||
| @@ -568,6 +946,18 @@ public: | |||||||
| 	    autoView( A_self  , A[self_stencil], AcceleratorWrite); | 	    autoView( A_self  , A[self_stencil], AcceleratorWrite); | ||||||
|  |  | ||||||
| 	    accelerator_for(ss, Grid()->oSites(), Fobj::Nsimd(),{ coalescedWrite(A_p[ss](j,i),oZProj_v(ss)); }); | 	    accelerator_for(ss, Grid()->oSites(), Fobj::Nsimd(),{ coalescedWrite(A_p[ss](j,i),oZProj_v(ss)); }); | ||||||
|  | 	    if ( hermitian && (disp==-1) ) { | ||||||
|  | 	      for(int pp=0;pp<geom.npoint;pp++){// Find the opposite link and set <j|A|i> = <i|A|j>* | ||||||
|  | 		int dirp   = geom.directions[pp]; | ||||||
|  | 		int dispp  = geom.displacements[pp]; | ||||||
|  | 		if ( (dirp==dir) && (dispp==1) ){ | ||||||
|  | 		  auto sft = conjugate(Cshift(oZProj,dir,1)); | ||||||
|  | 		  autoView( sft_v    ,  sft  , AcceleratorWrite); | ||||||
|  | 		  autoView( A_pp     ,  A[pp], AcceleratorWrite); | ||||||
|  | 		  accelerator_for(ss, Grid()->oSites(), Fobj::Nsimd(),{ coalescedWrite(A_pp[ss](i,j),sft_v(ss)); }); | ||||||
|  | 		} | ||||||
|  | 	      } | ||||||
|  | 	    } | ||||||
|  |  | ||||||
| 	  } | 	  } | ||||||
| 	} | 	} | ||||||
| @@ -606,28 +996,54 @@ public: | |||||||
|     } |     } | ||||||
|     if(hermitian) { |     if(hermitian) { | ||||||
|       std::cout << GridLogMessage << " ForceHermitian, new code "<<std::endl; |       std::cout << GridLogMessage << " ForceHermitian, new code "<<std::endl; | ||||||
|       ForceHermitian(); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     InvertSelfStencilLink(); std::cout << GridLogMessage << "Coarse self link inverted" << std::endl; | ||||||
|  |     FillHalfCbs(); std::cout << GridLogMessage << "Coarse half checkerboards filled" << std::endl; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void ForceHermitian(void) { |   void InvertSelfStencilLink() { | ||||||
|     CoarseMatrix Diff  (Grid()); |     std::cout << GridLogDebug << "CoarsenedMatrix::InvertSelfStencilLink" << std::endl; | ||||||
|     for(int p=0;p<geom.npoint;p++){ |     int localVolume = Grid()->lSites(); | ||||||
|       int dir   = geom.directions[p]; |  | ||||||
|       int disp  = geom.displacements[p]; |     typedef typename Cobj::scalar_object scalar_object; | ||||||
|       if(disp==-1) { |  | ||||||
| 	// Find the opposite link |     autoView(Aself_v,    A[geom.npoint-1], CpuRead); | ||||||
| 	for(int pp=0;pp<geom.npoint;pp++){ |     autoView(AselfInv_v, AselfInv,         CpuWrite); | ||||||
| 	  int dirp   = geom.directions[pp]; |     thread_for(site, localVolume, { // NOTE: Not able to bring this to GPU because of Eigen + peek/poke | ||||||
| 	  int dispp  = geom.displacements[pp]; |       Eigen::MatrixXcd selfLinkEigen    = Eigen::MatrixXcd::Zero(nbasis, nbasis); | ||||||
| 	  if ( (dirp==dir) && (dispp==1) ){ |       Eigen::MatrixXcd selfLinkInvEigen = Eigen::MatrixXcd::Zero(nbasis, nbasis); | ||||||
| 	    //	    Diff = adj(Cshift(A[p],dir,1)) - A[pp];  |  | ||||||
| 	    //	    std::cout << GridLogMessage<<" Replacing stencil leg "<<pp<<" with leg "<<p<< " diff "<<norm2(Diff) <<std::endl; |       scalar_object selfLink    = Zero(); | ||||||
| 	    A[pp] = adj(Cshift(A[p],dir,1)); |       scalar_object selfLinkInv = Zero(); | ||||||
| 	  } |  | ||||||
| 	} |       Coordinate lcoor; | ||||||
|       } |  | ||||||
|  |       Grid()->LocalIndexToLocalCoor(site, lcoor); | ||||||
|  |       peekLocalSite(selfLink, Aself_v, lcoor); | ||||||
|  |  | ||||||
|  |       for (int i = 0; i < nbasis; ++i) | ||||||
|  |         for (int j = 0; j < nbasis; ++j) | ||||||
|  |           selfLinkEigen(i, j) = static_cast<ComplexD>(TensorRemove(selfLink(i, j))); | ||||||
|  |  | ||||||
|  |       selfLinkInvEigen = selfLinkEigen.inverse(); | ||||||
|  |  | ||||||
|  |       for(int i = 0; i < nbasis; ++i) | ||||||
|  |         for(int j = 0; j < nbasis; ++j) | ||||||
|  |           selfLinkInv(i, j) = selfLinkInvEigen(i, j); | ||||||
|  |  | ||||||
|  |       pokeLocalSite(selfLinkInv, AselfInv_v, lcoor); | ||||||
|  |     }); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void FillHalfCbs() { | ||||||
|  |     std::cout << GridLogDebug << "CoarsenedMatrix::FillHalfCbs" << std::endl; | ||||||
|  |     for(int p = 0; p < geom.npoint; ++p) { | ||||||
|  |       pickCheckerboard(Even, Aeven[p], A[p]); | ||||||
|  |       pickCheckerboard(Odd, Aodd[p], A[p]); | ||||||
|     } |     } | ||||||
|  |     pickCheckerboard(Even, AselfInvEven, AselfInv); | ||||||
|  |     pickCheckerboard(Odd, AselfInvOdd, AselfInv); | ||||||
|   } |   } | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -136,7 +136,7 @@ public: | |||||||
|     flops=0; |     flops=0; | ||||||
|     usec =0; |     usec =0; | ||||||
|     Coordinate layout(Nd,1); |     Coordinate layout(Nd,1); | ||||||
|     sgrid = new GridCartesian(dimensions,layout,processors); |     sgrid = new GridCartesian(dimensions,layout,processors,*grid); | ||||||
|   }; |   }; | ||||||
|      |      | ||||||
|   ~FFT ( void)  { |   ~FFT ( void)  { | ||||||
| @@ -182,7 +182,7 @@ public: | |||||||
|     pencil_gd[dim] = G*processors[dim]; |     pencil_gd[dim] = G*processors[dim]; | ||||||
|        |        | ||||||
|     // Pencil global vol LxLxGxLxL per node |     // Pencil global vol LxLxGxLxL per node | ||||||
|     GridCartesian pencil_g(pencil_gd,layout,processors); |     GridCartesian pencil_g(pencil_gd,layout,processors,*vgrid); | ||||||
|        |        | ||||||
|     // Construct pencils |     // Construct pencils | ||||||
|     typedef typename vobj::scalar_object sobj; |     typedef typename vobj::scalar_object sobj; | ||||||
|   | |||||||
| @@ -223,9 +223,14 @@ class SchurOperatorBase :  public LinearOperatorBase<Field> { | |||||||
|     Mpc(in,tmp); |     Mpc(in,tmp); | ||||||
|     MpcDag(tmp,out); |     MpcDag(tmp,out); | ||||||
|   } |   } | ||||||
|  |   virtual  void MpcMpcDag(const Field &in, Field &out) { | ||||||
|  |     Field tmp(in.Grid()); | ||||||
|  |     tmp.Checkerboard() = in.Checkerboard(); | ||||||
|  |     MpcDag(in,tmp); | ||||||
|  |     Mpc(tmp,out); | ||||||
|  |   } | ||||||
|   virtual void HermOpAndNorm(const Field &in, Field &out,RealD &n1,RealD &n2){ |   virtual void HermOpAndNorm(const Field &in, Field &out,RealD &n1,RealD &n2){ | ||||||
|     out.Checkerboard() = in.Checkerboard(); |     HermOp(in,out); | ||||||
|     MpcDagMpc(in,out); |  | ||||||
|     ComplexD dot= innerProduct(in,out);  |     ComplexD dot= innerProduct(in,out);  | ||||||
|     n1=real(dot); |     n1=real(dot); | ||||||
|     n2=norm2(out); |     n2=norm2(out); | ||||||
| @@ -276,6 +281,16 @@ template<class Matrix,class Field> | |||||||
|       axpy(out,-1.0,tmp,out); |       axpy(out,-1.0,tmp,out); | ||||||
|     } |     } | ||||||
| }; | }; | ||||||
|  | // Mpc MpcDag system presented as the HermOp | ||||||
|  | template<class Matrix,class Field> | ||||||
|  | class SchurDiagMooeeDagOperator :  public SchurDiagMooeeOperator<Matrix,Field> { | ||||||
|  |  public: | ||||||
|  |   virtual void HermOp(const Field &in, Field &out){ | ||||||
|  |     out.Checkerboard() = in.Checkerboard(); | ||||||
|  |     this->MpcMpcDag(in,out); | ||||||
|  |   } | ||||||
|  |   SchurDiagMooeeDagOperator (Matrix &Mat): SchurDiagMooeeOperator<Matrix,Field>(Mat){}; | ||||||
|  | }; | ||||||
| template<class Matrix,class Field> | template<class Matrix,class Field> | ||||||
|   class SchurDiagOneOperator :  public SchurOperatorBase<Field> { |   class SchurDiagOneOperator :  public SchurOperatorBase<Field> { | ||||||
|  protected: |  protected: | ||||||
| @@ -530,6 +545,16 @@ public: | |||||||
| template<class Field> class LinearFunction { | template<class Field> class LinearFunction { | ||||||
| public: | public: | ||||||
|   virtual void operator() (const Field &in, Field &out) = 0; |   virtual void operator() (const Field &in, Field &out) = 0; | ||||||
|  |  | ||||||
|  |   virtual void operator() (const std::vector<Field> &in, std::vector<Field> &out) | ||||||
|  |   { | ||||||
|  |     assert(in.size() == out.size()); | ||||||
|  |  | ||||||
|  |     for (unsigned int i = 0; i < in.size(); ++i) | ||||||
|  |     { | ||||||
|  |       (*this)(in[i], out[i]); | ||||||
|  |     } | ||||||
|  |   } | ||||||
| }; | }; | ||||||
|  |  | ||||||
| template<class Field> class IdentityLinearFunction : public LinearFunction<Field> { | template<class Field> class IdentityLinearFunction : public LinearFunction<Field> { | ||||||
|   | |||||||
| @@ -292,6 +292,7 @@ public: | |||||||
| template<class Field> | template<class Field> | ||||||
| class ChebyshevLanczos : public Chebyshev<Field> { | class ChebyshevLanczos : public Chebyshev<Field> { | ||||||
| private: | private: | ||||||
|  |  | ||||||
|   std::vector<RealD> Coeffs; |   std::vector<RealD> Coeffs; | ||||||
|   int order; |   int order; | ||||||
|   RealD alpha; |   RealD alpha; | ||||||
|   | |||||||
| @@ -102,7 +102,7 @@ public: | |||||||
|     // Check if guess is really REALLY good :) |     // Check if guess is really REALLY good :) | ||||||
|     if (cp <= rsq) { |     if (cp <= rsq) { | ||||||
|       TrueResidual = std::sqrt(a/ssq); |       TrueResidual = std::sqrt(a/ssq); | ||||||
|       std::cout << GridLogMessage << "ConjugateGradient guess is converged already " << std::endl; |       std::cout << GridLogMessage << "ConjugateGradient guess is converged already "<<TrueResidual<< " tol "<< Tolerance<< std::endl; | ||||||
|       IterationsToComplete = 0;	 |       IterationsToComplete = 0;	 | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -48,19 +48,29 @@ NAMESPACE_BEGIN(Grid); | |||||||
|     Integer TotalInnerIterations; //Number of inner CG iterations |     Integer TotalInnerIterations; //Number of inner CG iterations | ||||||
|     Integer TotalOuterIterations; //Number of restarts |     Integer TotalOuterIterations; //Number of restarts | ||||||
|     Integer TotalFinalStepIterations; //Number of CG iterations in final patch-up step |     Integer TotalFinalStepIterations; //Number of CG iterations in final patch-up step | ||||||
|  |     RealD TrueResidual; | ||||||
|  |  | ||||||
|     //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,  |     MixedPrecisionConjugateGradient(RealD Tol, | ||||||
|  | 				    Integer maxinnerit,  | ||||||
|  | 				    Integer maxouterit,  | ||||||
|  | 				    GridBase* _sp_grid,  | ||||||
|  | 				    LinearOperatorBase<FieldF> &_Linop_f,  | ||||||
|  | 				    LinearOperatorBase<FieldD> &_Linop_d) : | ||||||
|  |       MixedPrecisionConjugateGradient(Tol, Tol, maxinnerit, maxouterit, _sp_grid, _Linop_f, _Linop_d) {}; | ||||||
|  |  | ||||||
|  |     MixedPrecisionConjugateGradient(RealD Tol, | ||||||
|  | 				    RealD InnerTol, | ||||||
| 				    Integer maxinnerit,  | 				    Integer maxinnerit,  | ||||||
| 				    Integer maxouterit,  | 				    Integer maxouterit,  | ||||||
| 				    GridBase* _sp_grid,  | 				    GridBase* _sp_grid,  | ||||||
| 				    LinearOperatorBase<FieldF> &_Linop_f,  | 				    LinearOperatorBase<FieldF> &_Linop_f,  | ||||||
| 				    LinearOperatorBase<FieldD> &_Linop_d) : | 				    LinearOperatorBase<FieldD> &_Linop_d) : | ||||||
|       Linop_f(_Linop_f), Linop_d(_Linop_d), |       Linop_f(_Linop_f), Linop_d(_Linop_d), | ||||||
|       Tolerance(tol), InnerTolerance(tol), MaxInnerIterations(maxinnerit), MaxOuterIterations(maxouterit), SinglePrecGrid(_sp_grid), |       Tolerance(Tol), InnerTolerance(InnerTol), MaxInnerIterations(maxinnerit), MaxOuterIterations(maxouterit), SinglePrecGrid(_sp_grid), | ||||||
|       OuterLoopNormMult(100.), guesser(NULL){ }; |       OuterLoopNormMult(100.), guesser(NULL){ assert(InnerTol < 1.0e-1);}; | ||||||
|  |  | ||||||
|     void useGuesser(LinearFunction<FieldF> &g){ |     void useGuesser(LinearFunction<FieldF> &g){ | ||||||
|       guesser = &g; |       guesser = &g; | ||||||
| @@ -79,6 +89,11 @@ NAMESPACE_BEGIN(Grid); | |||||||
|     RealD stop = src_norm * Tolerance*Tolerance; |     RealD stop = src_norm * Tolerance*Tolerance; | ||||||
|  |  | ||||||
|     GridBase* DoublePrecGrid = src_d_in.Grid(); |     GridBase* DoublePrecGrid = src_d_in.Grid(); | ||||||
|  |  | ||||||
|  |     //Generate precision change workspaces | ||||||
|  |     precisionChangeWorkspace wk_dp_from_sp(DoublePrecGrid, SinglePrecGrid); | ||||||
|  |     precisionChangeWorkspace wk_sp_from_dp(SinglePrecGrid, DoublePrecGrid); | ||||||
|  |  | ||||||
|     FieldD tmp_d(DoublePrecGrid); |     FieldD tmp_d(DoublePrecGrid); | ||||||
|     tmp_d.Checkerboard() = cb; |     tmp_d.Checkerboard() = cb; | ||||||
|      |      | ||||||
| @@ -119,7 +134,7 @@ NAMESPACE_BEGIN(Grid); | |||||||
|       while(norm * inner_tol * inner_tol < stop) inner_tol *= 2;  // inner_tol = sqrt(stop/norm) ?? |       while(norm * inner_tol * inner_tol < stop) inner_tol *= 2;  // inner_tol = sqrt(stop/norm) ?? | ||||||
|  |  | ||||||
|       PrecChangeTimer.Start(); |       PrecChangeTimer.Start(); | ||||||
|       precisionChange(src_f, src_d); |       precisionChange(src_f, src_d, wk_sp_from_dp); | ||||||
|       PrecChangeTimer.Stop(); |       PrecChangeTimer.Stop(); | ||||||
|        |        | ||||||
|       sol_f = Zero(); |       sol_f = Zero(); | ||||||
| @@ -137,7 +152,7 @@ NAMESPACE_BEGIN(Grid); | |||||||
|        |        | ||||||
|       //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(); | ||||||
|       precisionChange(tmp_d, sol_f); |       precisionChange(tmp_d, sol_f, wk_dp_from_sp); | ||||||
|       PrecChangeTimer.Stop(); |       PrecChangeTimer.Stop(); | ||||||
|        |        | ||||||
|       axpy(sol_d, 1.0, tmp_d, sol_d); |       axpy(sol_d, 1.0, tmp_d, sol_d); | ||||||
| @@ -149,6 +164,7 @@ NAMESPACE_BEGIN(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; |     TotalFinalStepIterations = CG_d.IterationsToComplete; | ||||||
|  |     TrueResidual = CG_d.TrueResidual; | ||||||
|  |  | ||||||
|     TotalTimer.Stop(); |     TotalTimer.Stop(); | ||||||
|     std::cout<<GridLogMessage<<"MixedPrecisionConjugateGradient: Inner CG iterations " << TotalInnerIterations << " Restarts " << TotalOuterIterations << " Final CG iterations " << TotalFinalStepIterations << std::endl; |     std::cout<<GridLogMessage<<"MixedPrecisionConjugateGradient: Inner CG iterations " << TotalInnerIterations << " Restarts " << TotalOuterIterations << " Final CG iterations " << TotalFinalStepIterations << std::endl; | ||||||
|   | |||||||
| @@ -52,7 +52,7 @@ public: | |||||||
|   MultiShiftFunction shifts; |   MultiShiftFunction shifts; | ||||||
|   std::vector<RealD> TrueResidualShift; |   std::vector<RealD> TrueResidualShift; | ||||||
|  |  | ||||||
|   ConjugateGradientMultiShift(Integer maxit,MultiShiftFunction &_shifts) :  |   ConjugateGradientMultiShift(Integer maxit, const MultiShiftFunction &_shifts) :  | ||||||
|     MaxIterations(maxit), |     MaxIterations(maxit), | ||||||
|     shifts(_shifts) |     shifts(_shifts) | ||||||
|   {  |   {  | ||||||
| @@ -182,6 +182,9 @@ public: | |||||||
|     for(int s=0;s<nshift;s++) { |     for(int s=0;s<nshift;s++) { | ||||||
|       axpby(psi[s],0.,-bs[s]*alpha[s],src,src); |       axpby(psi[s],0.,-bs[s]*alpha[s],src,src); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     std::cout << GridLogIterative << "ConjugateGradientMultiShift: initial rn (|src|^2) =" << rn << " qq (|MdagM src|^2) =" << qq << " d ( dot(src, [MdagM + m_0]src) ) =" << d << " c=" << c << std::endl; | ||||||
|  |      | ||||||
|    |    | ||||||
|   /////////////////////////////////////// |   /////////////////////////////////////// | ||||||
|   // Timers |   // Timers | ||||||
|   | |||||||
							
								
								
									
										411
									
								
								Grid/algorithms/iterative/ConjugateGradientMultiShiftMixedPrec.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										411
									
								
								Grid/algorithms/iterative/ConjugateGradientMultiShiftMixedPrec.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,411 @@ | |||||||
|  | /************************************************************************************* | ||||||
|  |  | ||||||
|  |     Grid physics library, www.github.com/paboyle/Grid  | ||||||
|  |  | ||||||
|  |     Source file: ./lib/algorithms/iterative/ConjugateGradientMultiShift.h | ||||||
|  |  | ||||||
|  |     Copyright (C) 2015 | ||||||
|  |  | ||||||
|  | Author: Azusa Yamaguchi <ayamaguc@staffmail.ed.ac.uk> | ||||||
|  | Author: Peter Boyle <paboyle@ph.ed.ac.uk> | ||||||
|  | Author: Christopher Kelly <ckelly@bnl.gov> | ||||||
|  |  | ||||||
|  |     This program is free software; you can redistribute it and/or modify | ||||||
|  |     it under the terms of the GNU General Public License as published by | ||||||
|  |     the Free Software Foundation; either version 2 of the License, or | ||||||
|  |     (at your option) any later version. | ||||||
|  |  | ||||||
|  |     This program is distributed in the hope that it will be useful, | ||||||
|  |     but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |     GNU General Public License for more details. | ||||||
|  |  | ||||||
|  |     You should have received a copy of the GNU General Public License along | ||||||
|  |     with this program; if not, write to the Free Software Foundation, Inc., | ||||||
|  |     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||||||
|  |  | ||||||
|  |     See the full license in the file "LICENSE" in the top level distribution directory | ||||||
|  | *************************************************************************************/ | ||||||
|  | /*  END LEGAL */ | ||||||
|  | #ifndef GRID_CONJUGATE_GRADIENT_MULTI_SHIFT_MIXEDPREC_H | ||||||
|  | #define GRID_CONJUGATE_GRADIENT_MULTI_SHIFT_MIXEDPREC_H | ||||||
|  |  | ||||||
|  | NAMESPACE_BEGIN(Grid); | ||||||
|  |  | ||||||
|  | //CK 2020: A variant of the multi-shift conjugate gradient with the matrix multiplication in single precision.  | ||||||
|  | //The residual is stored in single precision, but the search directions and solution are stored in double precision.  | ||||||
|  | //Every update_freq iterations the residual is corrected in double precision.  | ||||||
|  |      | ||||||
|  | //For safety the a final regular CG is applied to clean up if necessary | ||||||
|  |  | ||||||
|  | //Linop to add shift to input linop, used in cleanup CG | ||||||
|  | namespace ConjugateGradientMultiShiftMixedPrecSupport{ | ||||||
|  | template<typename Field> | ||||||
|  | class ShiftedLinop: public LinearOperatorBase<Field>{ | ||||||
|  | public: | ||||||
|  |   LinearOperatorBase<Field> &linop_base; | ||||||
|  |   RealD shift; | ||||||
|  |  | ||||||
|  |   ShiftedLinop(LinearOperatorBase<Field> &_linop_base, RealD _shift): linop_base(_linop_base), shift(_shift){} | ||||||
|  |  | ||||||
|  |   void OpDiag (const Field &in, Field &out){ assert(0); } | ||||||
|  |   void OpDir  (const Field &in, Field &out,int dir,int disp){ assert(0); } | ||||||
|  |   void OpDirAll  (const Field &in, std::vector<Field> &out){ assert(0); } | ||||||
|  |    | ||||||
|  |   void Op     (const Field &in, Field &out){ assert(0); } | ||||||
|  |   void AdjOp  (const Field &in, Field &out){ assert(0); } | ||||||
|  |  | ||||||
|  |   void HermOp(const Field &in, Field &out){ | ||||||
|  |     linop_base.HermOp(in, out); | ||||||
|  |     axpy(out, shift, in, out); | ||||||
|  |   }     | ||||||
|  |  | ||||||
|  |   void HermOpAndNorm(const Field &in, Field &out,RealD &n1,RealD &n2){ | ||||||
|  |     HermOp(in,out); | ||||||
|  |     ComplexD dot = innerProduct(in,out); | ||||||
|  |     n1=real(dot); | ||||||
|  |     n2=norm2(out); | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | template<class FieldD, class FieldF, | ||||||
|  | 	 typename std::enable_if< getPrecision<FieldD>::value == 2, int>::type = 0, | ||||||
|  | 	 typename std::enable_if< getPrecision<FieldF>::value == 1, int>::type = 0>  | ||||||
|  | class ConjugateGradientMultiShiftMixedPrec : public OperatorMultiFunction<FieldD>, | ||||||
|  | 					     public OperatorFunction<FieldD> | ||||||
|  | { | ||||||
|  | public:                                                 | ||||||
|  |  | ||||||
|  |   using OperatorFunction<FieldD>::operator(); | ||||||
|  |  | ||||||
|  |   RealD   Tolerance; | ||||||
|  |   Integer MaxIterations; | ||||||
|  |   Integer IterationsToComplete; //Number of iterations the CG took to finish. Filled in upon completion | ||||||
|  |   std::vector<int> IterationsToCompleteShift;  // Iterations for this shift | ||||||
|  |   int verbose; | ||||||
|  |   MultiShiftFunction shifts; | ||||||
|  |   std::vector<RealD> TrueResidualShift; | ||||||
|  |  | ||||||
|  |   int ReliableUpdateFreq; //number of iterations between reliable updates | ||||||
|  |  | ||||||
|  |   GridBase* SinglePrecGrid; //Grid for single-precision fields | ||||||
|  |   LinearOperatorBase<FieldF> &Linop_f; //single precision | ||||||
|  |  | ||||||
|  |   ConjugateGradientMultiShiftMixedPrec(Integer maxit, const MultiShiftFunction &_shifts, | ||||||
|  | 				       GridBase* _SinglePrecGrid, LinearOperatorBase<FieldF> &_Linop_f, | ||||||
|  | 				       int _ReliableUpdateFreq | ||||||
|  | 				       ) :  | ||||||
|  |     MaxIterations(maxit),  shifts(_shifts), SinglePrecGrid(_SinglePrecGrid), Linop_f(_Linop_f), ReliableUpdateFreq(_ReliableUpdateFreq) | ||||||
|  |   {  | ||||||
|  |     verbose=1; | ||||||
|  |     IterationsToCompleteShift.resize(_shifts.order); | ||||||
|  |     TrueResidualShift.resize(_shifts.order); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void operator() (LinearOperatorBase<FieldD> &Linop, const FieldD &src, FieldD &psi) | ||||||
|  |   { | ||||||
|  |     GridBase *grid = src.Grid(); | ||||||
|  |     int nshift = shifts.order; | ||||||
|  |     std::vector<FieldD> results(nshift,grid); | ||||||
|  |     (*this)(Linop,src,results,psi); | ||||||
|  |   } | ||||||
|  |   void operator() (LinearOperatorBase<FieldD> &Linop, const FieldD &src, std::vector<FieldD> &results, FieldD &psi) | ||||||
|  |   { | ||||||
|  |     int nshift = shifts.order; | ||||||
|  |  | ||||||
|  |     (*this)(Linop,src,results); | ||||||
|  |    | ||||||
|  |     psi = shifts.norm*src; | ||||||
|  |     for(int i=0;i<nshift;i++){ | ||||||
|  |       psi = psi + shifts.residues[i]*results[i]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void operator() (LinearOperatorBase<FieldD> &Linop_d, const FieldD &src_d, std::vector<FieldD> &psi_d) | ||||||
|  |   {  | ||||||
|  |     GridBase *DoublePrecGrid = src_d.Grid(); | ||||||
|  |     precisionChangeWorkspace wk_f_from_d(SinglePrecGrid, DoublePrecGrid); | ||||||
|  |     precisionChangeWorkspace wk_d_from_f(DoublePrecGrid, SinglePrecGrid); | ||||||
|  |  | ||||||
|  |     //////////////////////////////////////////////////////////////////////// | ||||||
|  |     // Convenience references to the info stored in "MultiShiftFunction" | ||||||
|  |     //////////////////////////////////////////////////////////////////////// | ||||||
|  |     int nshift = shifts.order; | ||||||
|  |  | ||||||
|  |     std::vector<RealD> &mass(shifts.poles); // Make references to array in "shifts" | ||||||
|  |     std::vector<RealD> &mresidual(shifts.tolerances); | ||||||
|  |     std::vector<RealD> alpha(nshift,1.0); | ||||||
|  |  | ||||||
|  |     //Double precision search directions | ||||||
|  |     FieldD p_d(DoublePrecGrid); | ||||||
|  |     std::vector<FieldD> ps_d(nshift, DoublePrecGrid);// Search directions (double precision) | ||||||
|  |  | ||||||
|  |     FieldD tmp_d(DoublePrecGrid); | ||||||
|  |     FieldD r_d(DoublePrecGrid); | ||||||
|  |     FieldD mmp_d(DoublePrecGrid); | ||||||
|  |  | ||||||
|  |     assert(psi_d.size()==nshift); | ||||||
|  |     assert(mass.size()==nshift); | ||||||
|  |     assert(mresidual.size()==nshift); | ||||||
|  |    | ||||||
|  |     // dynamic sized arrays on stack; 2d is a pain with vector | ||||||
|  |     RealD  bs[nshift]; | ||||||
|  |     RealD  rsq[nshift]; | ||||||
|  |     RealD  z[nshift][2]; | ||||||
|  |     int     converged[nshift]; | ||||||
|  |    | ||||||
|  |     const int       primary =0; | ||||||
|  |    | ||||||
|  |     //Primary shift fields CG iteration | ||||||
|  |     RealD a,b,c,d; | ||||||
|  |     RealD cp,bp,qq; //prev | ||||||
|  |    | ||||||
|  |     // Matrix mult fields | ||||||
|  |     FieldF r_f(SinglePrecGrid); | ||||||
|  |     FieldF p_f(SinglePrecGrid); | ||||||
|  |     FieldF tmp_f(SinglePrecGrid); | ||||||
|  |     FieldF mmp_f(SinglePrecGrid); | ||||||
|  |     FieldF src_f(SinglePrecGrid); | ||||||
|  |     precisionChange(src_f, src_d, wk_f_from_d); | ||||||
|  |  | ||||||
|  |     // Check lightest mass | ||||||
|  |     for(int s=0;s<nshift;s++){ | ||||||
|  |       assert( mass[s]>= mass[primary] ); | ||||||
|  |       converged[s]=0; | ||||||
|  |     } | ||||||
|  |    | ||||||
|  |     // Wire guess to zero | ||||||
|  |     // Residuals "r" are src | ||||||
|  |     // First search direction "p" is also src | ||||||
|  |     cp = norm2(src_d); | ||||||
|  |  | ||||||
|  |     // Handle trivial case of zero src. | ||||||
|  |     if( cp == 0. ){ | ||||||
|  |       for(int s=0;s<nshift;s++){ | ||||||
|  | 	psi_d[s] = Zero(); | ||||||
|  | 	IterationsToCompleteShift[s] = 1; | ||||||
|  | 	TrueResidualShift[s] = 0.; | ||||||
|  |       } | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     for(int s=0;s<nshift;s++){ | ||||||
|  |       rsq[s] = cp * mresidual[s] * mresidual[s]; | ||||||
|  |       std::cout<<GridLogMessage<<"ConjugateGradientMultiShiftMixedPrec: shift "<< s <<" target resid "<<rsq[s]<<std::endl; | ||||||
|  |       ps_d[s] = src_d; | ||||||
|  |     } | ||||||
|  |     // r and p for primary | ||||||
|  |     r_f=src_f; //residual maintained in single | ||||||
|  |     p_f=src_f; | ||||||
|  |     p_d = src_d; //primary copy --- make this a reference to ps_d to save axpys | ||||||
|  |    | ||||||
|  |     //MdagM+m[0] | ||||||
|  |     Linop_f.HermOpAndNorm(p_f,mmp_f,d,qq); // mmp = MdagM p        d=real(dot(p, mmp)),  qq=norm2(mmp) | ||||||
|  |     axpy(mmp_f,mass[0],p_f,mmp_f); | ||||||
|  |     RealD rn = norm2(p_f); | ||||||
|  |     d += rn*mass[0]; | ||||||
|  |  | ||||||
|  |     b = -cp /d; | ||||||
|  |    | ||||||
|  |     // Set up the various shift variables | ||||||
|  |     int       iz=0; | ||||||
|  |     z[0][1-iz] = 1.0; | ||||||
|  |     z[0][iz]   = 1.0; | ||||||
|  |     bs[0]      = b; | ||||||
|  |     for(int s=1;s<nshift;s++){ | ||||||
|  |       z[s][1-iz] = 1.0; | ||||||
|  |       z[s][iz]   = 1.0/( 1.0 - b*(mass[s]-mass[0])); | ||||||
|  |       bs[s]      = b*z[s][iz];  | ||||||
|  |     } | ||||||
|  |    | ||||||
|  |     // r += b[0] A.p[0] | ||||||
|  |     // c= norm(r) | ||||||
|  |     c=axpy_norm(r_f,b,mmp_f,r_f); | ||||||
|  |    | ||||||
|  |     for(int s=0;s<nshift;s++) { | ||||||
|  |       axpby(psi_d[s],0.,-bs[s]*alpha[s],src_d,src_d); | ||||||
|  |     } | ||||||
|  |    | ||||||
|  |     /////////////////////////////////////// | ||||||
|  |     // Timers | ||||||
|  |     /////////////////////////////////////// | ||||||
|  |     GridStopWatch AXPYTimer, ShiftTimer, QRTimer, MatrixTimer, SolverTimer, PrecChangeTimer, CleanupTimer; | ||||||
|  |  | ||||||
|  |     SolverTimer.Start(); | ||||||
|  |    | ||||||
|  |     // Iteration loop | ||||||
|  |     int k; | ||||||
|  |    | ||||||
|  |     for (k=1;k<=MaxIterations;k++){     | ||||||
|  |       a = c /cp; | ||||||
|  |  | ||||||
|  |       //Update double precision search direction by residual | ||||||
|  |       PrecChangeTimer.Start(); | ||||||
|  |       precisionChange(r_d, r_f, wk_d_from_f); | ||||||
|  |       PrecChangeTimer.Stop(); | ||||||
|  |  | ||||||
|  |       AXPYTimer.Start(); | ||||||
|  |       axpy(p_d,a,p_d,r_d);  | ||||||
|  |  | ||||||
|  |       for(int s=0;s<nshift;s++){ | ||||||
|  | 	if ( ! converged[s] ) {  | ||||||
|  | 	  if (s==0){ | ||||||
|  | 	    axpy(ps_d[s],a,ps_d[s],r_d); | ||||||
|  | 	  } else{ | ||||||
|  | 	    RealD as =a *z[s][iz]*bs[s] /(z[s][1-iz]*b); | ||||||
|  | 	    axpby(ps_d[s],z[s][iz],as,r_d,ps_d[s]); | ||||||
|  | 	  } | ||||||
|  | 	} | ||||||
|  |       } | ||||||
|  |       AXPYTimer.Stop(); | ||||||
|  |  | ||||||
|  |       PrecChangeTimer.Start(); | ||||||
|  |       precisionChange(p_f, p_d, wk_f_from_d); //get back single prec search direction for linop | ||||||
|  |       PrecChangeTimer.Stop(); | ||||||
|  |  | ||||||
|  |       cp=c; | ||||||
|  |       MatrixTimer.Start();   | ||||||
|  |       Linop_f.HermOp(p_f,mmp_f);  | ||||||
|  |       d=real(innerProduct(p_f,mmp_f));     | ||||||
|  |       MatrixTimer.Stop();   | ||||||
|  |  | ||||||
|  |       AXPYTimer.Start(); | ||||||
|  |       axpy(mmp_f,mass[0],p_f,mmp_f); | ||||||
|  |       AXPYTimer.Stop(); | ||||||
|  |       RealD rn = norm2(p_f); | ||||||
|  |       d += rn*mass[0]; | ||||||
|  |      | ||||||
|  |       bp=b; | ||||||
|  |       b=-cp/d; | ||||||
|  |      | ||||||
|  |       // Toggle the recurrence history | ||||||
|  |       bs[0] = b; | ||||||
|  |       iz = 1-iz; | ||||||
|  |       ShiftTimer.Start(); | ||||||
|  |       for(int s=1;s<nshift;s++){ | ||||||
|  | 	if((!converged[s])){ | ||||||
|  | 	  RealD z0 = z[s][1-iz]; | ||||||
|  | 	  RealD z1 = z[s][iz]; | ||||||
|  | 	  z[s][iz] = z0*z1*bp | ||||||
|  | 	    / (b*a*(z1-z0) + z1*bp*(1- (mass[s]-mass[0])*b));  | ||||||
|  | 	  bs[s] = b*z[s][iz]/z0; // NB sign  rel to Mike | ||||||
|  | 	} | ||||||
|  |       } | ||||||
|  |       ShiftTimer.Stop(); | ||||||
|  |  | ||||||
|  |       //Update double precision solutions | ||||||
|  |       AXPYTimer.Start(); | ||||||
|  |       for(int s=0;s<nshift;s++){ | ||||||
|  | 	int ss = s; | ||||||
|  | 	if( (!converged[s]) ) {  | ||||||
|  | 	  axpy(psi_d[ss],-bs[s]*alpha[s],ps_d[s],psi_d[ss]); | ||||||
|  | 	} | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       //Perform reliable update if necessary; otherwise update residual from single-prec mmp | ||||||
|  |       RealD c_f = axpy_norm(r_f,b,mmp_f,r_f); | ||||||
|  |       AXPYTimer.Stop(); | ||||||
|  |  | ||||||
|  |       c = c_f; | ||||||
|  |  | ||||||
|  |       if(k % ReliableUpdateFreq == 0){ | ||||||
|  | 	//Replace r with true residual | ||||||
|  | 	MatrixTimer.Start();   | ||||||
|  | 	Linop_d.HermOp(psi_d[0],mmp_d);  | ||||||
|  | 	MatrixTimer.Stop();   | ||||||
|  |  | ||||||
|  | 	AXPYTimer.Start(); | ||||||
|  | 	axpy(mmp_d,mass[0],psi_d[0],mmp_d); | ||||||
|  |  | ||||||
|  | 	RealD c_d = axpy_norm(r_d, -1.0, mmp_d, src_d); | ||||||
|  | 	AXPYTimer.Stop(); | ||||||
|  |  | ||||||
|  | 	std::cout<<GridLogMessage<<"ConjugateGradientMultiShiftMixedPrec k="<<k<< ", replaced |r|^2 = "<<c_f <<" with |r|^2 = "<<c_d<<std::endl; | ||||||
|  | 	 | ||||||
|  | 	PrecChangeTimer.Start(); | ||||||
|  | 	precisionChange(r_f, r_d, wk_f_from_d); | ||||||
|  | 	PrecChangeTimer.Stop(); | ||||||
|  | 	c = c_d; | ||||||
|  |       } | ||||||
|  |      | ||||||
|  |       // Convergence checks | ||||||
|  |       int all_converged = 1; | ||||||
|  |       for(int s=0;s<nshift;s++){ | ||||||
|  |        | ||||||
|  | 	if ( (!converged[s]) ){ | ||||||
|  | 	  IterationsToCompleteShift[s] = k; | ||||||
|  | 	 | ||||||
|  | 	  RealD css  = c * z[s][iz]* z[s][iz]; | ||||||
|  | 	 | ||||||
|  | 	  if(css<rsq[s]){ | ||||||
|  | 	    if ( ! converged[s] ) | ||||||
|  | 	      std::cout<<GridLogMessage<<"ConjugateGradientMultiShiftMixedPrec k="<<k<<" Shift "<<s<<" has converged"<<std::endl; | ||||||
|  | 	    converged[s]=1; | ||||||
|  | 	  } else { | ||||||
|  | 	    all_converged=0; | ||||||
|  | 	  } | ||||||
|  |  | ||||||
|  | 	} | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       if ( all_converged ){ | ||||||
|  |  | ||||||
|  | 	SolverTimer.Stop(); | ||||||
|  | 	std::cout<<GridLogMessage<< "ConjugateGradientMultiShiftMixedPrec: All shifts have converged iteration "<<k<<std::endl; | ||||||
|  | 	std::cout<<GridLogMessage<< "ConjugateGradientMultiShiftMixedPrec: Checking solutions"<<std::endl; | ||||||
|  |        | ||||||
|  | 	// Check answers  | ||||||
|  | 	for(int s=0; s < nshift; s++) {  | ||||||
|  | 	  Linop_d.HermOpAndNorm(psi_d[s],mmp_d,d,qq); | ||||||
|  | 	  axpy(tmp_d,mass[s],psi_d[s],mmp_d); | ||||||
|  | 	  axpy(r_d,-alpha[s],src_d,tmp_d); | ||||||
|  | 	  RealD rn = norm2(r_d); | ||||||
|  | 	  RealD cn = norm2(src_d); | ||||||
|  | 	  TrueResidualShift[s] = std::sqrt(rn/cn); | ||||||
|  | 	  std::cout<<GridLogMessage<<"ConjugateGradientMultiShiftMixedPrec: shift["<<s<<"] true residual "<< TrueResidualShift[s] << " target " << mresidual[s] << std::endl; | ||||||
|  |  | ||||||
|  | 	  //If we have not reached the desired tolerance, do a (mixed precision) CG cleanup | ||||||
|  | 	  if(rn >= rsq[s]){ | ||||||
|  | 	    CleanupTimer.Start(); | ||||||
|  | 	    std::cout<<GridLogMessage<<"ConjugateGradientMultiShiftMixedPrec: performing cleanup step for shift " << s << std::endl; | ||||||
|  |  | ||||||
|  | 	    //Setup linear operators for final cleanup | ||||||
|  | 	    ConjugateGradientMultiShiftMixedPrecSupport::ShiftedLinop<FieldD> Linop_shift_d(Linop_d, mass[s]); | ||||||
|  | 	    ConjugateGradientMultiShiftMixedPrecSupport::ShiftedLinop<FieldF> Linop_shift_f(Linop_f, mass[s]); | ||||||
|  | 					        | ||||||
|  | 	    MixedPrecisionConjugateGradient<FieldD,FieldF> cg(mresidual[s], MaxIterations, MaxIterations, SinglePrecGrid, Linop_shift_f, Linop_shift_d);  | ||||||
|  | 	    cg(src_d, psi_d[s]); | ||||||
|  | 	     | ||||||
|  | 	    TrueResidualShift[s] = cg.TrueResidual; | ||||||
|  | 	    CleanupTimer.Stop(); | ||||||
|  | 	  } | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	std::cout << GridLogMessage << "ConjugateGradientMultiShiftMixedPrec: Time Breakdown for body"<<std::endl; | ||||||
|  | 	std::cout << GridLogMessage << "\tSolver    " << SolverTimer.Elapsed()     <<std::endl; | ||||||
|  | 	std::cout << GridLogMessage << "\t\tAXPY    " << AXPYTimer.Elapsed()     <<std::endl; | ||||||
|  | 	std::cout << GridLogMessage << "\t\tMatrix    " << MatrixTimer.Elapsed()     <<std::endl; | ||||||
|  | 	std::cout << GridLogMessage << "\t\tShift    " << ShiftTimer.Elapsed()     <<std::endl; | ||||||
|  | 	std::cout << GridLogMessage << "\t\tPrecision Change " << PrecChangeTimer.Elapsed()     <<std::endl; | ||||||
|  | 	std::cout << GridLogMessage << "\tFinal Cleanup " << CleanupTimer.Elapsed()     <<std::endl; | ||||||
|  | 	std::cout << GridLogMessage << "\tSolver+Cleanup " << SolverTimer.Elapsed() + CleanupTimer.Elapsed() << std::endl; | ||||||
|  |  | ||||||
|  | 	IterationsToComplete = k;	 | ||||||
|  |  | ||||||
|  | 	return; | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |     | ||||||
|  |     } | ||||||
|  |     // ugly hack | ||||||
|  |     std::cout<<GridLogMessage<<"CG multi shift did not converge"<<std::endl; | ||||||
|  |     //  assert(0); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | }; | ||||||
|  | NAMESPACE_END(Grid); | ||||||
|  | #endif | ||||||
| @@ -54,15 +54,23 @@ class DeflatedGuesser: public LinearFunction<Field> { | |||||||
| private: | private: | ||||||
|   const std::vector<Field> &evec; |   const std::vector<Field> &evec; | ||||||
|   const std::vector<RealD> &eval; |   const std::vector<RealD> &eval; | ||||||
|  |   const unsigned int       N; | ||||||
|  |  | ||||||
| public: | public: | ||||||
|  |  | ||||||
|   DeflatedGuesser(const std::vector<Field> & _evec,const std::vector<RealD> & _eval) : evec(_evec), eval(_eval) {}; |   DeflatedGuesser(const std::vector<Field> & _evec,const std::vector<RealD> & _eval) | ||||||
|  |   : DeflatedGuesser(_evec, _eval, _evec.size()) | ||||||
|  |   {} | ||||||
|  |  | ||||||
|  |   DeflatedGuesser(const std::vector<Field> & _evec, const std::vector<RealD> & _eval, const unsigned int _N) | ||||||
|  |   : evec(_evec), eval(_eval), N(_N) | ||||||
|  |   { | ||||||
|  |     assert(evec.size()==eval.size()); | ||||||
|  |     assert(N <= evec.size()); | ||||||
|  |   }  | ||||||
|  |  | ||||||
|   virtual void operator()(const Field &src,Field &guess) { |   virtual void operator()(const Field &src,Field &guess) { | ||||||
|     guess = Zero(); |     guess = Zero(); | ||||||
|     assert(evec.size()==eval.size()); |  | ||||||
|     auto N = evec.size(); |  | ||||||
|     for (int i=0;i<N;i++) { |     for (int i=0;i<N;i++) { | ||||||
|       const Field& tmp = evec[i]; |       const Field& tmp = evec[i]; | ||||||
|       axpy(guess,TensorRemove(innerProduct(tmp,src)) / eval[i],tmp,guess); |       axpy(guess,TensorRemove(innerProduct(tmp,src)) / eval[i],tmp,guess); | ||||||
|   | |||||||
| @@ -40,7 +40,7 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk> | |||||||
|    *        (-MoeMee^{-1}   1 )    |    *        (-MoeMee^{-1}   1 )    | ||||||
|    * L^{dag} = ( 1       Mee^{-dag} Moe^{dag} ) |    * L^{dag} = ( 1       Mee^{-dag} Moe^{dag} ) | ||||||
|    *           ( 0       1                    ) |    *           ( 0       1                    ) | ||||||
|    * L^{-d}  = ( 1      -Mee^{-dag} Moe^{dag} ) |    * L^{-dag}= ( 1      -Mee^{-dag} Moe^{dag} ) | ||||||
|    *           ( 0       1                    ) |    *           ( 0       1                    ) | ||||||
|    * |    * | ||||||
|    * U^-1 = (1   -Mee^{-1} Meo) |    * U^-1 = (1   -Mee^{-1} Meo) | ||||||
| @@ -82,7 +82,8 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk> | |||||||
|    * c) M_oo^-dag Doo^{dag} Doo Moo^-1 phi_0 = M_oo^-dag (D_oo)^dag L^{-1}  eta_o |    * c) M_oo^-dag Doo^{dag} Doo Moo^-1 phi_0 = M_oo^-dag (D_oo)^dag L^{-1}  eta_o | ||||||
|    *                              eta_o'     = M_oo^-dag (D_oo)^dag (eta_o - Moe Mee^{-1} eta_e) |    *                              eta_o'     = M_oo^-dag (D_oo)^dag (eta_o - Moe Mee^{-1} eta_e) | ||||||
|    *                              psi_o = M_oo^-1 phi_o |    *                              psi_o = M_oo^-1 phi_o | ||||||
|    * TODO: Deflation  |    * | ||||||
|  |    * | ||||||
|    */ |    */ | ||||||
| namespace Grid { | namespace Grid { | ||||||
|  |  | ||||||
| @@ -97,6 +98,7 @@ namespace Grid { | |||||||
|   protected: |   protected: | ||||||
|     typedef CheckerBoardedSparseMatrixBase<Field> Matrix; |     typedef CheckerBoardedSparseMatrixBase<Field> Matrix; | ||||||
|     OperatorFunction<Field> & _HermitianRBSolver; |     OperatorFunction<Field> & _HermitianRBSolver; | ||||||
|  |      | ||||||
|     int CBfactorise; |     int CBfactorise; | ||||||
|     bool subGuess; |     bool subGuess; | ||||||
|     bool useSolnAsInitGuess; // if true user-supplied solution vector is used as initial guess for solver |     bool useSolnAsInitGuess; // if true user-supplied solution vector is used as initial guess for solver | ||||||
| @@ -132,6 +134,31 @@ namespace Grid { | |||||||
|       (*this)(_Matrix,in,out,guess); |       (*this)(_Matrix,in,out,guess); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     void RedBlackSource(Matrix &_Matrix, const std::vector<Field> &in, std::vector<Field> &src_o)  | ||||||
|  |     { | ||||||
|  |       GridBase *grid = _Matrix.RedBlackGrid(); | ||||||
|  |       Field tmp(grid); | ||||||
|  |       int nblock = in.size(); | ||||||
|  |       for(int b=0;b<nblock;b++){ | ||||||
|  | 	RedBlackSource(_Matrix,in[b],tmp,src_o[b]); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     // James can write his own deflated guesser | ||||||
|  |     // with optimised code for the inner products | ||||||
|  |     //    RedBlackSolveSplitGrid(); | ||||||
|  |     //    RedBlackSolve(_Matrix,src_o,sol_o);  | ||||||
|  |  | ||||||
|  |     void RedBlackSolution(Matrix &_Matrix, const std::vector<Field> &in, const std::vector<Field> &sol_o, std::vector<Field> &out) | ||||||
|  |     { | ||||||
|  |       GridBase *grid = _Matrix.RedBlackGrid(); | ||||||
|  |       Field tmp(grid); | ||||||
|  |       int nblock = in.size(); | ||||||
|  |       for(int b=0;b<nblock;b++) { | ||||||
|  | 	pickCheckerboard(Even,tmp,in[b]); | ||||||
|  | 	RedBlackSolution(_Matrix,sol_o[b],tmp,out[b]); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     template<class Guesser> |     template<class Guesser> | ||||||
|     void operator()(Matrix &_Matrix, const std::vector<Field> &in, std::vector<Field> &out,Guesser &guess)  |     void operator()(Matrix &_Matrix, const std::vector<Field> &in, std::vector<Field> &out,Guesser &guess)  | ||||||
|     { |     { | ||||||
| @@ -150,24 +177,29 @@ namespace Grid { | |||||||
|       //////////////////////////////////////////////// |       //////////////////////////////////////////////// | ||||||
|       // Prepare RedBlack source |       // Prepare RedBlack source | ||||||
|       //////////////////////////////////////////////// |       //////////////////////////////////////////////// | ||||||
|       for(int b=0;b<nblock;b++){ |       RedBlackSource(_Matrix,in,src_o); | ||||||
| 	RedBlackSource(_Matrix,in[b],tmp,src_o[b]); | 	//      for(int b=0;b<nblock;b++){ | ||||||
|       } | 	//	RedBlackSource(_Matrix,in[b],tmp,src_o[b]); | ||||||
|  | 	//      } | ||||||
|  |        | ||||||
|       //////////////////////////////////////////////// |       //////////////////////////////////////////////// | ||||||
|       // Make the guesses |       // Make the guesses | ||||||
|       //////////////////////////////////////////////// |       //////////////////////////////////////////////// | ||||||
|       if ( subGuess ) guess_save.resize(nblock,grid); |       if ( subGuess ) guess_save.resize(nblock,grid); | ||||||
|  |  | ||||||
|       for(int b=0;b<nblock;b++){ |        | ||||||
|         if(useSolnAsInitGuess) { |       if(useSolnAsInitGuess) { | ||||||
|  |         for(int b=0;b<nblock;b++){ | ||||||
|           pickCheckerboard(Odd, sol_o[b], out[b]); |           pickCheckerboard(Odd, sol_o[b], out[b]); | ||||||
|         } else { |  | ||||||
|           guess(src_o[b],sol_o[b]);  |  | ||||||
|         } |         } | ||||||
|  |       } else { | ||||||
|  |         guess(src_o, sol_o);  | ||||||
|  |       } | ||||||
|  |  | ||||||
| 	if ( subGuess ) {  | 	    if ( subGuess ) {  | ||||||
| 	  guess_save[b] = sol_o[b]; |         for(int b=0;b<nblock;b++){ | ||||||
| 	} |           guess_save[b] = sol_o[b]; | ||||||
|  |         } | ||||||
|       } |       } | ||||||
|       ////////////////////////////////////////////////////////////// |       ////////////////////////////////////////////////////////////// | ||||||
|       // Call the block solver |       // Call the block solver | ||||||
| @@ -189,13 +221,20 @@ namespace Grid { | |||||||
| 	///////////////////////////////////////////////// | 	///////////////////////////////////////////////// | ||||||
| 	// Check unprec residual if possible | 	// Check unprec residual if possible | ||||||
| 	///////////////////////////////////////////////// | 	///////////////////////////////////////////////// | ||||||
| 	if ( ! subGuess ) { | 	if ( ! subGuess ) {	   | ||||||
| 	  _Matrix.M(out[b],resid);  |  | ||||||
|  | 	  if ( this->adjoint() ) _Matrix.Mdag(out[b],resid);  | ||||||
|  | 	  else                   _Matrix.M(out[b],resid);  | ||||||
|  |  | ||||||
| 	  resid = resid-in[b]; | 	  resid = resid-in[b]; | ||||||
| 	  RealD ns = norm2(in[b]); | 	  RealD ns = norm2(in[b]); | ||||||
| 	  RealD nr = norm2(resid); | 	  RealD nr = norm2(resid); | ||||||
| 	 | 	 | ||||||
| 	  std::cout<<GridLogMessage<< "SchurRedBlackBase solver true unprec resid["<<b<<"] "<<std::sqrt(nr/ns) << std::endl; | 	  std::cout<<GridLogMessage<< "SchurRedBlackBase adjoint "<< this->adjoint() << std::endl; | ||||||
|  | 	  if ( this->adjoint() )  | ||||||
|  | 	    std::cout<<GridLogMessage<< "SchurRedBlackBase adjoint solver true unprec resid["<<b<<"] "<<std::sqrt(nr/ns) << std::endl; | ||||||
|  | 	  else                    | ||||||
|  | 	    std::cout<<GridLogMessage<< "SchurRedBlackBase solver true unprec resid["<<b<<"] "<<std::sqrt(nr/ns) << std::endl; | ||||||
| 	} else { | 	} else { | ||||||
| 	  std::cout<<GridLogMessage<< "SchurRedBlackBase Guess subtracted after solve["<<b<<"] " << std::endl; | 	  std::cout<<GridLogMessage<< "SchurRedBlackBase Guess subtracted after solve["<<b<<"] " << std::endl; | ||||||
| 	} | 	} | ||||||
| @@ -249,12 +288,21 @@ namespace Grid { | |||||||
|  |  | ||||||
|       // Verify the unprec residual |       // Verify the unprec residual | ||||||
|       if ( ! subGuess ) { |       if ( ! subGuess ) { | ||||||
|         _Matrix.M(out,resid);  |  | ||||||
|  | 	std::cout<<GridLogMessage<< "SchurRedBlackBase adjoint "<< this->adjoint() << std::endl; | ||||||
|  | 	 | ||||||
|  | 	if ( this->adjoint() ) _Matrix.Mdag(out,resid);  | ||||||
|  | 	else                   _Matrix.M(out,resid);  | ||||||
|  |  | ||||||
|         resid = resid-in; |         resid = resid-in; | ||||||
|         RealD ns = norm2(in); |         RealD ns = norm2(in); | ||||||
|         RealD nr = norm2(resid); |         RealD nr = norm2(resid); | ||||||
|  |  | ||||||
|         std::cout<<GridLogMessage << "SchurRedBlackBase solver true unprec resid "<< std::sqrt(nr/ns) << std::endl; | 	  if ( this->adjoint() )  | ||||||
|  | 	    std::cout<<GridLogMessage<< "SchurRedBlackBase adjoint solver true unprec resid "<<std::sqrt(nr/ns) << std::endl; | ||||||
|  | 	  else                    | ||||||
|  | 	    std::cout<<GridLogMessage<< "SchurRedBlackBase solver true unprec resid "<<std::sqrt(nr/ns) << std::endl; | ||||||
|  |  | ||||||
|       } else { |       } else { | ||||||
|         std::cout << GridLogMessage << "SchurRedBlackBase Guess subtracted after solve." << std::endl; |         std::cout << GridLogMessage << "SchurRedBlackBase Guess subtracted after solve." << std::endl; | ||||||
|       } |       } | ||||||
| @@ -263,6 +311,7 @@ namespace Grid { | |||||||
|     ///////////////////////////////////////////////////////////// |     ///////////////////////////////////////////////////////////// | ||||||
|     // Override in derived.  |     // Override in derived.  | ||||||
|     ///////////////////////////////////////////////////////////// |     ///////////////////////////////////////////////////////////// | ||||||
|  |     virtual bool adjoint(void) { return false; } | ||||||
|     virtual void RedBlackSource  (Matrix & _Matrix,const Field &src, Field &src_e,Field &src_o)                =0; |     virtual void RedBlackSource  (Matrix & _Matrix,const Field &src, Field &src_e,Field &src_o)                =0; | ||||||
|     virtual void RedBlackSolution(Matrix & _Matrix,const Field &sol_o, const Field &src_e,Field &sol)          =0; |     virtual void RedBlackSolution(Matrix & _Matrix,const Field &sol_o, const Field &src_e,Field &sol)          =0; | ||||||
|     virtual void RedBlackSolve   (Matrix & _Matrix,const Field &src_o, Field &sol_o)                           =0; |     virtual void RedBlackSolve   (Matrix & _Matrix,const Field &src_o, Field &sol_o)                           =0; | ||||||
| @@ -616,6 +665,127 @@ namespace Grid { | |||||||
|         this->_HermitianRBSolver(_OpEO, src_o, sol_o);  |         this->_HermitianRBSolver(_OpEO, src_o, sol_o);  | ||||||
|       } |       } | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
|  |   /* | ||||||
|  |    * Red black Schur decomposition | ||||||
|  |    * | ||||||
|  |    *  M = (Mee Meo) =  (1             0 )   (Mee   0               )  (1 Mee^{-1} Meo) | ||||||
|  |    *      (Moe Moo)    (Moe Mee^-1    1 )   (0   Moo-Moe Mee^-1 Meo)  (0   1         ) | ||||||
|  |    *                =         L                     D                     U | ||||||
|  |    * | ||||||
|  |    * L^-1 = (1              0 ) | ||||||
|  |    *        (-MoeMee^{-1}   1 )    | ||||||
|  |    * L^{dag} = ( 1       Mee^{-dag} Moe^{dag} ) | ||||||
|  |    *           ( 0       1                    ) | ||||||
|  |    * | ||||||
|  |    * U^-1 = (1   -Mee^{-1} Meo) | ||||||
|  |    *        (0    1           ) | ||||||
|  |    * U^{dag} = ( 1                 0) | ||||||
|  |    *           (Meo^dag Mee^{-dag} 1) | ||||||
|  |    * U^{-dag} = (  1                 0) | ||||||
|  |    *            (-Meo^dag Mee^{-dag} 1) | ||||||
|  |    * | ||||||
|  |    * | ||||||
|  |    *********************** | ||||||
|  |    *     M^dag psi = eta | ||||||
|  |    *********************** | ||||||
|  |    * | ||||||
|  |    * Really for Mobius: (Wilson - easier to just use gamma 5 hermiticity) | ||||||
|  |    * | ||||||
|  |    *    Mdag psi     =         Udag  Ddag  Ldag psi = eta | ||||||
|  |    * | ||||||
|  |    * U^{-dag} = (  1                 0) | ||||||
|  |    *            (-Meo^dag Mee^{-dag} 1) | ||||||
|  |    * | ||||||
|  |    * | ||||||
|  |    * i)                D^dag phi =  (U^{-dag}  eta) | ||||||
|  |    *                        eta'_e = eta_e | ||||||
|  |    *                        eta'_o = (eta_o - Meo^dag Mee^{-dag} eta_e) | ||||||
|  |    *  | ||||||
|  |    *      phi_o = D_oo^-dag eta'_o = D_oo^-dag (eta_o - Meo^dag Mee^{-dag} eta_e) | ||||||
|  |    * | ||||||
|  |    *      phi_e = D_ee^-dag eta'_e = D_ee^-dag eta_e | ||||||
|  |    *  | ||||||
|  |    * Solve:  | ||||||
|  |    * | ||||||
|  |    *      D_oo D_oo^dag phi_o = D_oo (eta_o - Meo^dag Mee^{-dag} eta_e) | ||||||
|  |    * | ||||||
|  |    * ii)  | ||||||
|  |    *      phi = L^dag psi => psi = L^-dag phi.  | ||||||
|  |    * | ||||||
|  |    * L^{-dag} = ( 1      -Mee^{-dag} Moe^{dag} ) | ||||||
|  |    *            ( 0       1                    ) | ||||||
|  |    * | ||||||
|  |    *   => sol_e = M_ee^-dag * ( src_e - Moe^dag phi_o )... | ||||||
|  |    *   => sol_o = phi_o | ||||||
|  |    */ | ||||||
|  |   /////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||||
|  |   // Site diagonal has Mooee on it, but solve the Adjoint system | ||||||
|  |   /////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||||
|  |   template<class Field> class SchurRedBlackDiagMooeeDagSolve : public SchurRedBlackBase<Field> { | ||||||
|  |   public: | ||||||
|  |     typedef CheckerBoardedSparseMatrixBase<Field> Matrix; | ||||||
|  |  | ||||||
|  |     virtual bool adjoint(void) { return true; } | ||||||
|  |     SchurRedBlackDiagMooeeDagSolve(OperatorFunction<Field> &HermitianRBSolver, | ||||||
|  | 				   const bool initSubGuess = false, | ||||||
|  | 				   const bool _solnAsInitGuess = false)   | ||||||
|  |       : SchurRedBlackBase<Field> (HermitianRBSolver,initSubGuess,_solnAsInitGuess) {}; | ||||||
|  |  | ||||||
|  |     ////////////////////////////////////////////////////// | ||||||
|  |     // Override RedBlack specialisation | ||||||
|  |     ////////////////////////////////////////////////////// | ||||||
|  |     virtual void RedBlackSource(Matrix & _Matrix,const Field &src, Field &src_e,Field &src_o) | ||||||
|  |     { | ||||||
|  |       GridBase *grid = _Matrix.RedBlackGrid(); | ||||||
|  |       GridBase *fgrid= _Matrix.Grid(); | ||||||
|  |  | ||||||
|  |       Field   tmp(grid); | ||||||
|  |       Field  Mtmp(grid); | ||||||
|  |  | ||||||
|  |       pickCheckerboard(Even,src_e,src); | ||||||
|  |       pickCheckerboard(Odd ,src_o,src); | ||||||
|  |       ///////////////////////////////////////////////////// | ||||||
|  |       // src_o = (source_o - Moe^dag MeeInvDag source_e) | ||||||
|  |       ///////////////////////////////////////////////////// | ||||||
|  |       _Matrix.MooeeInvDag(src_e,tmp);  assert(  tmp.Checkerboard() ==Even); | ||||||
|  |       _Matrix.MeooeDag   (tmp,Mtmp);   assert( Mtmp.Checkerboard() ==Odd);      | ||||||
|  |       tmp=src_o-Mtmp;                  assert(  tmp.Checkerboard() ==Odd);      | ||||||
|  |  | ||||||
|  |       // get the right Mpc | ||||||
|  |       SchurDiagMooeeOperator<Matrix,Field> _HermOpEO(_Matrix); | ||||||
|  |       _HermOpEO.Mpc(tmp,src_o);     assert(src_o.Checkerboard() ==Odd); | ||||||
|  |     } | ||||||
|  |     virtual void RedBlackSolve   (Matrix & _Matrix,const Field &src_o, Field &sol_o) | ||||||
|  |     { | ||||||
|  |       SchurDiagMooeeDagOperator<Matrix,Field> _HermOpEO(_Matrix); | ||||||
|  |       this->_HermitianRBSolver(_HermOpEO,src_o,sol_o);  | ||||||
|  |     }; | ||||||
|  |     virtual void RedBlackSolve   (Matrix & _Matrix,const std::vector<Field> &src_o,  std::vector<Field> &sol_o) | ||||||
|  |     { | ||||||
|  |       SchurDiagMooeeDagOperator<Matrix,Field> _HermOpEO(_Matrix); | ||||||
|  |       this->_HermitianRBSolver(_HermOpEO,src_o,sol_o); | ||||||
|  |     } | ||||||
|  |     virtual void RedBlackSolution(Matrix & _Matrix,const Field &sol_o, const Field &src_e,Field &sol) | ||||||
|  |     { | ||||||
|  |       GridBase *grid = _Matrix.RedBlackGrid(); | ||||||
|  |       GridBase *fgrid= _Matrix.Grid(); | ||||||
|  |  | ||||||
|  |       Field  sol_e(grid); | ||||||
|  |       Field  tmp(grid); | ||||||
|  |       /////////////////////////////////////////////////// | ||||||
|  |       // sol_e = M_ee^-dag * ( src_e - Moe^dag phi_o )... | ||||||
|  |       // sol_o = phi_o | ||||||
|  |       /////////////////////////////////////////////////// | ||||||
|  |       _Matrix.MeooeDag(sol_o,tmp);      assert(tmp.Checkerboard()==Even); | ||||||
|  |       tmp = src_e-tmp;                  assert(tmp.Checkerboard()==Even); | ||||||
|  |       _Matrix.MooeeInvDag(tmp,sol_e);   assert(sol_e.Checkerboard()==Even); | ||||||
|  |        | ||||||
|  |       setCheckerboard(sol,sol_e); assert(  sol_e.Checkerboard() ==Even); | ||||||
|  |       setCheckerboard(sol,sol_o); assert(  sol_o.Checkerboard() ==Odd ); | ||||||
|  |     } | ||||||
|  |   }; | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|   | |||||||
| @@ -173,7 +173,8 @@ template<class T> using cshiftAllocator = devAllocator<T>; | |||||||
| template<class T> using cshiftAllocator = std::allocator<T>; | template<class T> using cshiftAllocator = std::allocator<T>; | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| template<class T> using Vector     = std::vector<T,uvmAllocator<T> >;            | template<class T> using Vector        = std::vector<T,uvmAllocator<T> >;            | ||||||
|  | template<class T> using stencilVector = std::vector<T,alignedAllocator<T> >;            | ||||||
| template<class T> using commVector = std::vector<T,devAllocator<T> >; | template<class T> using commVector = std::vector<T,devAllocator<T> >; | ||||||
| template<class T> using cshiftVector = std::vector<T,cshiftAllocator<T> >; | template<class T> using cshiftVector = std::vector<T,cshiftAllocator<T> >; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -9,14 +9,30 @@ NAMESPACE_BEGIN(Grid); | |||||||
| #define AccSmall (3) | #define AccSmall (3) | ||||||
| #define Shared   (4) | #define Shared   (4) | ||||||
| #define SharedSmall (5) | #define SharedSmall (5) | ||||||
|  | #undef GRID_MM_VERBOSE  | ||||||
| uint64_t total_shared; | uint64_t total_shared; | ||||||
| uint64_t total_device; | uint64_t total_device; | ||||||
| uint64_t total_host;; | uint64_t total_host;; | ||||||
| void MemoryManager::PrintBytes(void) | void MemoryManager::PrintBytes(void) | ||||||
| { | { | ||||||
|   std::cout << " MemoryManager : "<<total_shared<<" shared      bytes "<<std::endl; |   std::cout << " MemoryManager : ------------------------------------ "<<std::endl; | ||||||
|   std::cout << " MemoryManager : "<<total_device<<" accelerator bytes "<<std::endl; |   std::cout << " MemoryManager : PrintBytes "<<std::endl; | ||||||
|   std::cout << " MemoryManager : "<<total_host  <<" cpu         bytes "<<std::endl; |   std::cout << " MemoryManager : ------------------------------------ "<<std::endl; | ||||||
|  |   std::cout << " MemoryManager : "<<(total_shared>>20)<<" shared      Mbytes "<<std::endl; | ||||||
|  |   std::cout << " MemoryManager : "<<(total_device>>20)<<" accelerator Mbytes "<<std::endl; | ||||||
|  |   std::cout << " MemoryManager : "<<(total_host>>20)  <<" cpu         Mbytes "<<std::endl; | ||||||
|  |   uint64_t cacheBytes; | ||||||
|  |   cacheBytes = CacheBytes[Cpu]; | ||||||
|  |   std::cout << " MemoryManager : "<<(cacheBytes>>20) <<" cpu cache Mbytes "<<std::endl; | ||||||
|  |   cacheBytes = CacheBytes[Acc]; | ||||||
|  |   std::cout << " MemoryManager : "<<(cacheBytes>>20) <<" acc cache Mbytes "<<std::endl; | ||||||
|  |   cacheBytes = CacheBytes[Shared]; | ||||||
|  |   std::cout << " MemoryManager : "<<(cacheBytes>>20) <<" shared cache Mbytes "<<std::endl; | ||||||
|  |    | ||||||
|  | #ifdef GRID_CUDA | ||||||
|  |   cuda_mem(); | ||||||
|  | #endif | ||||||
|  |    | ||||||
| } | } | ||||||
|  |  | ||||||
| ////////////////////////////////////////////////////////////////////// | ////////////////////////////////////////////////////////////////////// | ||||||
| @@ -24,86 +40,114 @@ void MemoryManager::PrintBytes(void) | |||||||
| ////////////////////////////////////////////////////////////////////// | ////////////////////////////////////////////////////////////////////// | ||||||
| MemoryManager::AllocationCacheEntry MemoryManager::Entries[MemoryManager::NallocType][MemoryManager::NallocCacheMax]; | MemoryManager::AllocationCacheEntry MemoryManager::Entries[MemoryManager::NallocType][MemoryManager::NallocCacheMax]; | ||||||
| int MemoryManager::Victim[MemoryManager::NallocType]; | int MemoryManager::Victim[MemoryManager::NallocType]; | ||||||
| int MemoryManager::Ncache[MemoryManager::NallocType] = { 8, 32, 8, 32, 8, 32 }; | int MemoryManager::Ncache[MemoryManager::NallocType] = { 2, 8, 2, 8, 2, 8 }; | ||||||
|  | uint64_t MemoryManager::CacheBytes[MemoryManager::NallocType]; | ||||||
| ////////////////////////////////////////////////////////////////////// | ////////////////////////////////////////////////////////////////////// | ||||||
| // Actual allocation and deallocation utils | // Actual allocation and deallocation utils | ||||||
| ////////////////////////////////////////////////////////////////////// | ////////////////////////////////////////////////////////////////////// | ||||||
| void *MemoryManager::AcceleratorAllocate(size_t bytes) | void *MemoryManager::AcceleratorAllocate(size_t bytes) | ||||||
| { | { | ||||||
|  |   total_device+=bytes; | ||||||
|   void *ptr = (void *) Lookup(bytes,Acc); |   void *ptr = (void *) Lookup(bytes,Acc); | ||||||
|   if ( ptr == (void *) NULL ) { |   if ( ptr == (void *) NULL ) { | ||||||
|     ptr = (void *) acceleratorAllocDevice(bytes); |     ptr = (void *) acceleratorAllocDevice(bytes); | ||||||
|     total_device+=bytes; |  | ||||||
|   } |   } | ||||||
|  | #ifdef GRID_MM_VERBOSE | ||||||
|  |   std::cout <<"AcceleratorAllocate "<<std::endl; | ||||||
|  |   PrintBytes(); | ||||||
|  | #endif | ||||||
|   return ptr; |   return ptr; | ||||||
| } | } | ||||||
| void  MemoryManager::AcceleratorFree    (void *ptr,size_t bytes) | void  MemoryManager::AcceleratorFree    (void *ptr,size_t bytes) | ||||||
| { | { | ||||||
|  |   total_device-=bytes; | ||||||
|   void *__freeme = Insert(ptr,bytes,Acc); |   void *__freeme = Insert(ptr,bytes,Acc); | ||||||
|   if ( __freeme ) { |   if ( __freeme ) { | ||||||
|     acceleratorFreeDevice(__freeme); |     acceleratorFreeDevice(__freeme); | ||||||
|     total_device-=bytes; |  | ||||||
|     //    PrintBytes(); |  | ||||||
|   } |   } | ||||||
|  | #ifdef GRID_MM_VERBOSE | ||||||
|  |   std::cout <<"AcceleratorFree "<<std::endl; | ||||||
|  |   PrintBytes(); | ||||||
|  | #endif | ||||||
| } | } | ||||||
| void *MemoryManager::SharedAllocate(size_t bytes) | void *MemoryManager::SharedAllocate(size_t bytes) | ||||||
| { | { | ||||||
|  |   total_shared+=bytes; | ||||||
|   void *ptr = (void *) Lookup(bytes,Shared); |   void *ptr = (void *) Lookup(bytes,Shared); | ||||||
|   if ( ptr == (void *) NULL ) { |   if ( ptr == (void *) NULL ) { | ||||||
|     ptr = (void *) acceleratorAllocShared(bytes); |     ptr = (void *) acceleratorAllocShared(bytes); | ||||||
|     total_shared+=bytes; |  | ||||||
|     //    std::cout <<"AcceleratorAllocate: allocated Shared pointer "<<std::hex<<ptr<<std::dec<<std::endl; |  | ||||||
|     //    PrintBytes(); |  | ||||||
|   } |   } | ||||||
|  | #ifdef GRID_MM_VERBOSE | ||||||
|  |   std::cout <<"SharedAllocate "<<std::endl; | ||||||
|  |   PrintBytes(); | ||||||
|  | #endif | ||||||
|   return ptr; |   return ptr; | ||||||
| } | } | ||||||
| void  MemoryManager::SharedFree    (void *ptr,size_t bytes) | void  MemoryManager::SharedFree    (void *ptr,size_t bytes) | ||||||
| { | { | ||||||
|  |   total_shared-=bytes; | ||||||
|   void *__freeme = Insert(ptr,bytes,Shared); |   void *__freeme = Insert(ptr,bytes,Shared); | ||||||
|   if ( __freeme ) { |   if ( __freeme ) { | ||||||
|     acceleratorFreeShared(__freeme); |     acceleratorFreeShared(__freeme); | ||||||
|     total_shared-=bytes; |  | ||||||
|     //    PrintBytes(); |  | ||||||
|   } |   } | ||||||
|  | #ifdef GRID_MM_VERBOSE | ||||||
|  |   std::cout <<"SharedFree "<<std::endl; | ||||||
|  |   PrintBytes(); | ||||||
|  | #endif | ||||||
| } | } | ||||||
| #ifdef GRID_UVM | #ifdef GRID_UVM | ||||||
| void *MemoryManager::CpuAllocate(size_t bytes) | void *MemoryManager::CpuAllocate(size_t bytes) | ||||||
| { | { | ||||||
|  |   total_host+=bytes; | ||||||
|   void *ptr = (void *) Lookup(bytes,Cpu); |   void *ptr = (void *) Lookup(bytes,Cpu); | ||||||
|   if ( ptr == (void *) NULL ) { |   if ( ptr == (void *) NULL ) { | ||||||
|     ptr = (void *) acceleratorAllocShared(bytes); |     ptr = (void *) acceleratorAllocShared(bytes); | ||||||
|     total_host+=bytes; |  | ||||||
|   } |   } | ||||||
|  | #ifdef GRID_MM_VERBOSE | ||||||
|  |   std::cout <<"CpuAllocate "<<std::endl; | ||||||
|  |   PrintBytes(); | ||||||
|  | #endif | ||||||
|   return ptr; |   return ptr; | ||||||
| } | } | ||||||
| void  MemoryManager::CpuFree    (void *_ptr,size_t bytes) | void  MemoryManager::CpuFree    (void *_ptr,size_t bytes) | ||||||
| { | { | ||||||
|  |   total_host-=bytes; | ||||||
|   NotifyDeletion(_ptr); |   NotifyDeletion(_ptr); | ||||||
|   void *__freeme = Insert(_ptr,bytes,Cpu); |   void *__freeme = Insert(_ptr,bytes,Cpu); | ||||||
|   if ( __freeme ) {  |   if ( __freeme ) {  | ||||||
|     acceleratorFreeShared(__freeme); |     acceleratorFreeShared(__freeme); | ||||||
|     total_host-=bytes; |  | ||||||
|   } |   } | ||||||
|  | #ifdef GRID_MM_VERBOSE | ||||||
|  |   std::cout <<"CpuFree "<<std::endl; | ||||||
|  |   PrintBytes(); | ||||||
|  | #endif | ||||||
| } | } | ||||||
| #else | #else | ||||||
| void *MemoryManager::CpuAllocate(size_t bytes) | void *MemoryManager::CpuAllocate(size_t bytes) | ||||||
| { | { | ||||||
|  |   total_host+=bytes; | ||||||
|   void *ptr = (void *) Lookup(bytes,Cpu); |   void *ptr = (void *) Lookup(bytes,Cpu); | ||||||
|   if ( ptr == (void *) NULL ) { |   if ( ptr == (void *) NULL ) { | ||||||
|     ptr = (void *) acceleratorAllocCpu(bytes); |     ptr = (void *) acceleratorAllocCpu(bytes); | ||||||
|     total_host+=bytes; |  | ||||||
|   } |   } | ||||||
|  | #ifdef GRID_MM_VERBOSE | ||||||
|  |   std::cout <<"CpuAllocate "<<std::endl; | ||||||
|  |   PrintBytes(); | ||||||
|  | #endif | ||||||
|   return ptr; |   return ptr; | ||||||
| } | } | ||||||
| void  MemoryManager::CpuFree    (void *_ptr,size_t bytes) | void  MemoryManager::CpuFree    (void *_ptr,size_t bytes) | ||||||
| { | { | ||||||
|  |   total_host-=bytes; | ||||||
|   NotifyDeletion(_ptr); |   NotifyDeletion(_ptr); | ||||||
|   void *__freeme = Insert(_ptr,bytes,Cpu); |   void *__freeme = Insert(_ptr,bytes,Cpu); | ||||||
|   if ( __freeme ) {  |   if ( __freeme ) {  | ||||||
|     acceleratorFreeCpu(__freeme); |     acceleratorFreeCpu(__freeme); | ||||||
|     total_host-=bytes; |  | ||||||
|   } |   } | ||||||
|  | #ifdef GRID_MM_VERBOSE | ||||||
|  |   std::cout <<"CpuFree "<<std::endl; | ||||||
|  |   PrintBytes(); | ||||||
|  | #endif | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| @@ -181,13 +225,13 @@ void *MemoryManager::Insert(void *ptr,size_t bytes,int type) | |||||||
| #ifdef ALLOCATION_CACHE | #ifdef ALLOCATION_CACHE | ||||||
|   bool small = (bytes < GRID_ALLOC_SMALL_LIMIT); |   bool small = (bytes < GRID_ALLOC_SMALL_LIMIT); | ||||||
|   int cache = type + small; |   int cache = type + small; | ||||||
|   return Insert(ptr,bytes,Entries[cache],Ncache[cache],Victim[cache]);   |   return Insert(ptr,bytes,Entries[cache],Ncache[cache],Victim[cache],CacheBytes[cache]);   | ||||||
| #else | #else | ||||||
|   return ptr; |   return ptr; | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
|  |  | ||||||
| void *MemoryManager::Insert(void *ptr,size_t bytes,AllocationCacheEntry *entries,int ncache,int &victim)  | void *MemoryManager::Insert(void *ptr,size_t bytes,AllocationCacheEntry *entries,int ncache,int &victim, uint64_t &cacheBytes)  | ||||||
| { | { | ||||||
|   assert(ncache>0); |   assert(ncache>0); | ||||||
| #ifdef GRID_OMP | #ifdef GRID_OMP | ||||||
| @@ -211,6 +255,7 @@ void *MemoryManager::Insert(void *ptr,size_t bytes,AllocationCacheEntry *entries | |||||||
|  |  | ||||||
|   if ( entries[v].valid ) { |   if ( entries[v].valid ) { | ||||||
|     ret = entries[v].address; |     ret = entries[v].address; | ||||||
|  |     cacheBytes -= entries[v].bytes; | ||||||
|     entries[v].valid = 0; |     entries[v].valid = 0; | ||||||
|     entries[v].address = NULL; |     entries[v].address = NULL; | ||||||
|     entries[v].bytes = 0; |     entries[v].bytes = 0; | ||||||
| @@ -219,6 +264,7 @@ void *MemoryManager::Insert(void *ptr,size_t bytes,AllocationCacheEntry *entries | |||||||
|   entries[v].address=ptr; |   entries[v].address=ptr; | ||||||
|   entries[v].bytes  =bytes; |   entries[v].bytes  =bytes; | ||||||
|   entries[v].valid  =1; |   entries[v].valid  =1; | ||||||
|  |   cacheBytes += bytes; | ||||||
|  |  | ||||||
|   return ret; |   return ret; | ||||||
| } | } | ||||||
| @@ -228,13 +274,13 @@ void *MemoryManager::Lookup(size_t bytes,int type) | |||||||
| #ifdef ALLOCATION_CACHE | #ifdef ALLOCATION_CACHE | ||||||
|   bool small = (bytes < GRID_ALLOC_SMALL_LIMIT); |   bool small = (bytes < GRID_ALLOC_SMALL_LIMIT); | ||||||
|   int cache = type+small; |   int cache = type+small; | ||||||
|   return Lookup(bytes,Entries[cache],Ncache[cache]); |   return Lookup(bytes,Entries[cache],Ncache[cache],CacheBytes[cache]); | ||||||
| #else | #else | ||||||
|   return NULL; |   return NULL; | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
|  |  | ||||||
| void *MemoryManager::Lookup(size_t bytes,AllocationCacheEntry *entries,int ncache)  | void *MemoryManager::Lookup(size_t bytes,AllocationCacheEntry *entries,int ncache,uint64_t & cacheBytes)  | ||||||
| { | { | ||||||
|   assert(ncache>0); |   assert(ncache>0); | ||||||
| #ifdef GRID_OMP | #ifdef GRID_OMP | ||||||
| @@ -243,6 +289,7 @@ void *MemoryManager::Lookup(size_t bytes,AllocationCacheEntry *entries,int ncach | |||||||
|   for(int e=0;e<ncache;e++){ |   for(int e=0;e<ncache;e++){ | ||||||
|     if ( entries[e].valid && ( entries[e].bytes == bytes ) ) { |     if ( entries[e].valid && ( entries[e].bytes == bytes ) ) { | ||||||
|       entries[e].valid = 0; |       entries[e].valid = 0; | ||||||
|  |       cacheBytes -= entries[e].bytes; | ||||||
|       return entries[e].address; |       return entries[e].address; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -34,8 +34,6 @@ NAMESPACE_BEGIN(Grid); | |||||||
|  |  | ||||||
| // Move control to configure.ac and Config.h? | // Move control to configure.ac and Config.h? | ||||||
|  |  | ||||||
| #define ALLOCATION_CACHE |  | ||||||
| #define GRID_ALLOC_ALIGN (2*1024*1024) |  | ||||||
| #define GRID_ALLOC_SMALL_LIMIT (4096) | #define GRID_ALLOC_SMALL_LIMIT (4096) | ||||||
|  |  | ||||||
| /*Pinning pages is costly*/ | /*Pinning pages is costly*/ | ||||||
| @@ -84,14 +82,15 @@ private: | |||||||
|   static AllocationCacheEntry Entries[NallocType][NallocCacheMax]; |   static AllocationCacheEntry Entries[NallocType][NallocCacheMax]; | ||||||
|   static int Victim[NallocType]; |   static int Victim[NallocType]; | ||||||
|   static int Ncache[NallocType]; |   static int Ncache[NallocType]; | ||||||
|  |   static uint64_t CacheBytes[NallocType]; | ||||||
|  |  | ||||||
|   ///////////////////////////////////////////////// |   ///////////////////////////////////////////////// | ||||||
|   // Free pool |   // Free pool | ||||||
|   ///////////////////////////////////////////////// |   ///////////////////////////////////////////////// | ||||||
|   static void *Insert(void *ptr,size_t bytes,int type) ; |   static void *Insert(void *ptr,size_t bytes,int type) ; | ||||||
|   static void *Lookup(size_t bytes,int type) ; |   static void *Lookup(size_t bytes,int type) ; | ||||||
|   static void *Insert(void *ptr,size_t bytes,AllocationCacheEntry *entries,int ncache,int &victim) ; |   static void *Insert(void *ptr,size_t bytes,AllocationCacheEntry *entries,int ncache,int &victim,uint64_t &cbytes) ; | ||||||
|   static void *Lookup(size_t bytes,AllocationCacheEntry *entries,int ncache) ; |   static void *Lookup(size_t bytes,AllocationCacheEntry *entries,int ncache,uint64_t &cbytes) ; | ||||||
|  |  | ||||||
|   static void PrintBytes(void); |   static void PrintBytes(void); | ||||||
|  public: |  public: | ||||||
|   | |||||||
| @@ -1,11 +1,12 @@ | |||||||
| #include <Grid/GridCore.h> | #include <Grid/GridCore.h> | ||||||
|  |  | ||||||
| #ifndef GRID_UVM | #ifndef GRID_UVM | ||||||
|  |  | ||||||
| #warning "Using explicit device memory copies" | #warning "Using explicit device memory copies" | ||||||
| NAMESPACE_BEGIN(Grid); | NAMESPACE_BEGIN(Grid); | ||||||
|  | //#define dprintf(...) printf ( __VA_ARGS__ ); fflush(stdout); | ||||||
| #define dprintf(...) | #define dprintf(...) | ||||||
|  |  | ||||||
|  |  | ||||||
| //////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////// | ||||||
| // For caching copies of data on device | // For caching copies of data on device | ||||||
| //////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////// | ||||||
| @@ -103,7 +104,7 @@ void MemoryManager::AccDiscard(AcceleratorViewEntry &AccCache) | |||||||
|   /////////////////////////////////////////////////////////// |   /////////////////////////////////////////////////////////// | ||||||
|   assert(AccCache.state!=Empty); |   assert(AccCache.state!=Empty); | ||||||
|    |    | ||||||
|   //  dprintf("MemoryManager: Discard(%llx) %llx\n",(uint64_t)AccCache.CpuPtr,(uint64_t)AccCache.AccPtr);  |    dprintf("MemoryManager: Discard(%llx) %llx\n",(uint64_t)AccCache.CpuPtr,(uint64_t)AccCache.AccPtr);  | ||||||
|   assert(AccCache.accLock==0); |   assert(AccCache.accLock==0); | ||||||
|   assert(AccCache.cpuLock==0); |   assert(AccCache.cpuLock==0); | ||||||
|   assert(AccCache.CpuPtr!=(uint64_t)NULL); |   assert(AccCache.CpuPtr!=(uint64_t)NULL); | ||||||
| @@ -111,7 +112,7 @@ void MemoryManager::AccDiscard(AcceleratorViewEntry &AccCache) | |||||||
|     AcceleratorFree((void *)AccCache.AccPtr,AccCache.bytes); |     AcceleratorFree((void *)AccCache.AccPtr,AccCache.bytes); | ||||||
|     DeviceBytes   -=AccCache.bytes; |     DeviceBytes   -=AccCache.bytes; | ||||||
|     LRUremove(AccCache); |     LRUremove(AccCache); | ||||||
|     //    dprintf("MemoryManager: Free(%llx) LRU %lld Total %lld\n",(uint64_t)AccCache.AccPtr,DeviceLRUBytes,DeviceBytes);   |     dprintf("MemoryManager: Free(%llx) LRU %lld Total %lld\n",(uint64_t)AccCache.AccPtr,DeviceLRUBytes,DeviceBytes);   | ||||||
|   } |   } | ||||||
|   uint64_t CpuPtr = AccCache.CpuPtr; |   uint64_t CpuPtr = AccCache.CpuPtr; | ||||||
|   EntryErase(CpuPtr); |   EntryErase(CpuPtr); | ||||||
| @@ -125,7 +126,7 @@ void MemoryManager::Evict(AcceleratorViewEntry &AccCache) | |||||||
|   /////////////////////////////////////////////////////////////////////////// |   /////////////////////////////////////////////////////////////////////////// | ||||||
|   assert(AccCache.state!=Empty); |   assert(AccCache.state!=Empty); | ||||||
|    |    | ||||||
|   //  dprintf("MemoryManager: Evict(%llx) %llx\n",(uint64_t)AccCache.CpuPtr,(uint64_t)AccCache.AccPtr);  |   dprintf("MemoryManager: Evict(%llx) %llx\n",(uint64_t)AccCache.CpuPtr,(uint64_t)AccCache.AccPtr);  | ||||||
|   assert(AccCache.accLock==0); |   assert(AccCache.accLock==0); | ||||||
|   assert(AccCache.cpuLock==0); |   assert(AccCache.cpuLock==0); | ||||||
|   if(AccCache.state==AccDirty) { |   if(AccCache.state==AccDirty) { | ||||||
| @@ -136,7 +137,7 @@ void MemoryManager::Evict(AcceleratorViewEntry &AccCache) | |||||||
|     AcceleratorFree((void *)AccCache.AccPtr,AccCache.bytes); |     AcceleratorFree((void *)AccCache.AccPtr,AccCache.bytes); | ||||||
|     DeviceBytes   -=AccCache.bytes; |     DeviceBytes   -=AccCache.bytes; | ||||||
|     LRUremove(AccCache); |     LRUremove(AccCache); | ||||||
|     //    dprintf("MemoryManager: Free(%llx) footprint now %lld \n",(uint64_t)AccCache.AccPtr,DeviceBytes);   |     dprintf("MemoryManager: Free(%llx) footprint now %lld \n",(uint64_t)AccCache.AccPtr,DeviceBytes);   | ||||||
|   } |   } | ||||||
|   uint64_t CpuPtr = AccCache.CpuPtr; |   uint64_t CpuPtr = AccCache.CpuPtr; | ||||||
|   EntryErase(CpuPtr); |   EntryErase(CpuPtr); | ||||||
| @@ -149,7 +150,7 @@ void MemoryManager::Flush(AcceleratorViewEntry &AccCache) | |||||||
|   assert(AccCache.AccPtr!=(uint64_t)NULL); |   assert(AccCache.AccPtr!=(uint64_t)NULL); | ||||||
|   assert(AccCache.CpuPtr!=(uint64_t)NULL); |   assert(AccCache.CpuPtr!=(uint64_t)NULL); | ||||||
|   acceleratorCopyFromDevice((void *)AccCache.AccPtr,(void *)AccCache.CpuPtr,AccCache.bytes); |   acceleratorCopyFromDevice((void *)AccCache.AccPtr,(void *)AccCache.CpuPtr,AccCache.bytes); | ||||||
|   //  dprintf("MemoryManager: Flush  %llx -> %llx\n",(uint64_t)AccCache.AccPtr,(uint64_t)AccCache.CpuPtr); fflush(stdout); |   dprintf("MemoryManager: Flush  %llx -> %llx\n",(uint64_t)AccCache.AccPtr,(uint64_t)AccCache.CpuPtr); fflush(stdout); | ||||||
|   DeviceToHostBytes+=AccCache.bytes; |   DeviceToHostBytes+=AccCache.bytes; | ||||||
|   DeviceToHostXfer++; |   DeviceToHostXfer++; | ||||||
|   AccCache.state=Consistent; |   AccCache.state=Consistent; | ||||||
| @@ -164,7 +165,7 @@ void MemoryManager::Clone(AcceleratorViewEntry &AccCache) | |||||||
|     AccCache.AccPtr=(uint64_t)AcceleratorAllocate(AccCache.bytes); |     AccCache.AccPtr=(uint64_t)AcceleratorAllocate(AccCache.bytes); | ||||||
|     DeviceBytes+=AccCache.bytes; |     DeviceBytes+=AccCache.bytes; | ||||||
|   } |   } | ||||||
|   //  dprintf("MemoryManager: Clone %llx <- %llx\n",(uint64_t)AccCache.AccPtr,(uint64_t)AccCache.CpuPtr); fflush(stdout); |   dprintf("MemoryManager: Clone %llx <- %llx\n",(uint64_t)AccCache.AccPtr,(uint64_t)AccCache.CpuPtr); fflush(stdout); | ||||||
|   acceleratorCopyToDevice((void *)AccCache.CpuPtr,(void *)AccCache.AccPtr,AccCache.bytes); |   acceleratorCopyToDevice((void *)AccCache.CpuPtr,(void *)AccCache.AccPtr,AccCache.bytes); | ||||||
|   HostToDeviceBytes+=AccCache.bytes; |   HostToDeviceBytes+=AccCache.bytes; | ||||||
|   HostToDeviceXfer++; |   HostToDeviceXfer++; | ||||||
| @@ -227,18 +228,24 @@ uint64_t MemoryManager::AcceleratorViewOpen(uint64_t CpuPtr,size_t bytes,ViewMod | |||||||
|   // Find if present, otherwise get or force an empty |   // Find if present, otherwise get or force an empty | ||||||
|   //////////////////////////////////////////////////////////////////////////// |   //////////////////////////////////////////////////////////////////////////// | ||||||
|   if ( EntryPresent(CpuPtr)==0 ){ |   if ( EntryPresent(CpuPtr)==0 ){ | ||||||
|     EvictVictims(bytes); |  | ||||||
|     EntryCreate(CpuPtr,bytes,mode,hint); |     EntryCreate(CpuPtr,bytes,mode,hint); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   auto AccCacheIterator = EntryLookup(CpuPtr); |   auto AccCacheIterator = EntryLookup(CpuPtr); | ||||||
|   auto & AccCache = AccCacheIterator->second; |   auto & AccCache = AccCacheIterator->second; | ||||||
|    |   if (!AccCache.AccPtr) { | ||||||
|  |     EvictVictims(bytes);  | ||||||
|  |   }  | ||||||
|   assert((mode==AcceleratorRead)||(mode==AcceleratorWrite)||(mode==AcceleratorWriteDiscard)); |   assert((mode==AcceleratorRead)||(mode==AcceleratorWrite)||(mode==AcceleratorWriteDiscard)); | ||||||
|  |  | ||||||
|   assert(AccCache.cpuLock==0);  // Programming error |   assert(AccCache.cpuLock==0);  // Programming error | ||||||
|  |  | ||||||
|   if(AccCache.state!=Empty) { |   if(AccCache.state!=Empty) { | ||||||
|  |     dprintf("ViewOpen found entry %llx %llx : %lld %lld\n", | ||||||
|  | 		    (uint64_t)AccCache.CpuPtr, | ||||||
|  | 		    (uint64_t)CpuPtr, | ||||||
|  | 		    (uint64_t)AccCache.bytes, | ||||||
|  | 		    (uint64_t)bytes); | ||||||
|     assert(AccCache.CpuPtr == CpuPtr); |     assert(AccCache.CpuPtr == CpuPtr); | ||||||
|     assert(AccCache.bytes  ==bytes); |     assert(AccCache.bytes  ==bytes); | ||||||
|   } |   } | ||||||
| @@ -285,21 +292,21 @@ uint64_t MemoryManager::AcceleratorViewOpen(uint64_t CpuPtr,size_t bytes,ViewMod | |||||||
|       AccCache.state  = Consistent; // CpuDirty + AccRead => Consistent |       AccCache.state  = Consistent; // CpuDirty + AccRead => Consistent | ||||||
|     } |     } | ||||||
|     AccCache.accLock++; |     AccCache.accLock++; | ||||||
|     //    printf("Copied CpuDirty entry into device accLock %d\n",AccCache.accLock); |     dprintf("Copied CpuDirty entry into device accLock %d\n",AccCache.accLock); | ||||||
|   } else if(AccCache.state==Consistent) { |   } else if(AccCache.state==Consistent) { | ||||||
|     if((mode==AcceleratorWrite)||(mode==AcceleratorWriteDiscard)) |     if((mode==AcceleratorWrite)||(mode==AcceleratorWriteDiscard)) | ||||||
|       AccCache.state  = AccDirty;   // Consistent + AcceleratorWrite=> AccDirty |       AccCache.state  = AccDirty;   // Consistent + AcceleratorWrite=> AccDirty | ||||||
|     else |     else | ||||||
|       AccCache.state  = Consistent; // Consistent + AccRead => Consistent |       AccCache.state  = Consistent; // Consistent + AccRead => Consistent | ||||||
|     AccCache.accLock++; |     AccCache.accLock++; | ||||||
|     //    printf("Consistent entry into device accLock %d\n",AccCache.accLock); |     dprintf("Consistent entry into device accLock %d\n",AccCache.accLock); | ||||||
|   } else if(AccCache.state==AccDirty) { |   } else if(AccCache.state==AccDirty) { | ||||||
|     if((mode==AcceleratorWrite)||(mode==AcceleratorWriteDiscard)) |     if((mode==AcceleratorWrite)||(mode==AcceleratorWriteDiscard)) | ||||||
|       AccCache.state  = AccDirty; // AccDirty + AcceleratorWrite=> AccDirty |       AccCache.state  = AccDirty; // AccDirty + AcceleratorWrite=> AccDirty | ||||||
|     else |     else | ||||||
|       AccCache.state  = AccDirty; // AccDirty + AccRead => AccDirty |       AccCache.state  = AccDirty; // AccDirty + AccRead => AccDirty | ||||||
|     AccCache.accLock++; |     AccCache.accLock++; | ||||||
|     //    printf("AccDirty entry into device accLock %d\n",AccCache.accLock); |     dprintf("AccDirty entry into device accLock %d\n",AccCache.accLock); | ||||||
|   } else { |   } else { | ||||||
|     assert(0); |     assert(0); | ||||||
|   } |   } | ||||||
| @@ -361,13 +368,16 @@ uint64_t MemoryManager::CpuViewOpen(uint64_t CpuPtr,size_t bytes,ViewMode mode,V | |||||||
|   // Find if present, otherwise get or force an empty |   // Find if present, otherwise get or force an empty | ||||||
|   //////////////////////////////////////////////////////////////////////////// |   //////////////////////////////////////////////////////////////////////////// | ||||||
|   if ( EntryPresent(CpuPtr)==0 ){ |   if ( EntryPresent(CpuPtr)==0 ){ | ||||||
|     EvictVictims(bytes); |  | ||||||
|     EntryCreate(CpuPtr,bytes,mode,transient); |     EntryCreate(CpuPtr,bytes,mode,transient); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   auto AccCacheIterator = EntryLookup(CpuPtr); |   auto AccCacheIterator = EntryLookup(CpuPtr); | ||||||
|   auto & AccCache = AccCacheIterator->second; |   auto & AccCache = AccCacheIterator->second; | ||||||
|    |  | ||||||
|  |   if (!AccCache.AccPtr) { | ||||||
|  |      EvictVictims(bytes); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   assert((mode==CpuRead)||(mode==CpuWrite)); |   assert((mode==CpuRead)||(mode==CpuWrite)); | ||||||
|   assert(AccCache.accLock==0);  // Programming error |   assert(AccCache.accLock==0);  // Programming error | ||||||
|  |  | ||||||
| @@ -419,6 +429,7 @@ void  MemoryManager::NotifyDeletion(void *_ptr) | |||||||
| } | } | ||||||
| void  MemoryManager::Print(void) | void  MemoryManager::Print(void) | ||||||
| { | { | ||||||
|  |   PrintBytes(); | ||||||
|   std::cout << GridLogDebug << "--------------------------------------------" << std::endl; |   std::cout << GridLogDebug << "--------------------------------------------" << std::endl; | ||||||
|   std::cout << GridLogDebug << "Memory Manager                             " << std::endl; |   std::cout << GridLogDebug << "Memory Manager                             " << std::endl; | ||||||
|   std::cout << GridLogDebug << "--------------------------------------------" << std::endl; |   std::cout << GridLogDebug << "--------------------------------------------" << std::endl; | ||||||
|   | |||||||
| @@ -1,7 +1,6 @@ | |||||||
| #include <Grid/GridCore.h> | #include <Grid/GridCore.h> | ||||||
| #ifdef GRID_UVM | #ifdef GRID_UVM | ||||||
|  |  | ||||||
| #warning "Grid is assuming unified virtual memory address space" |  | ||||||
| NAMESPACE_BEGIN(Grid); | NAMESPACE_BEGIN(Grid); | ||||||
| ///////////////////////////////////////////////////////////////////////////////// | ///////////////////////////////////////////////////////////////////////////////// | ||||||
| // View management is 1:1 address space mapping | // View management is 1:1 address space mapping | ||||||
|   | |||||||
| @@ -36,7 +36,7 @@ static const int CbBlack=1; | |||||||
| static const int Even   =CbRed; | static const int Even   =CbRed; | ||||||
| static const int Odd    =CbBlack; | static const int Odd    =CbBlack; | ||||||
|  |  | ||||||
| accelerator_inline int RedBlackCheckerBoardFromOindex (int oindex, Coordinate &rdim, Coordinate &chk_dim_msk) | accelerator_inline int RedBlackCheckerBoardFromOindex (int oindex,const Coordinate &rdim,const Coordinate &chk_dim_msk) | ||||||
| { | { | ||||||
|   int nd=rdim.size(); |   int nd=rdim.size(); | ||||||
|   Coordinate coor(nd); |   Coordinate coor(nd); | ||||||
|   | |||||||
| @@ -33,6 +33,8 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk> | |||||||
|  |  | ||||||
| NAMESPACE_BEGIN(Grid); | NAMESPACE_BEGIN(Grid); | ||||||
|  |  | ||||||
|  | bool Stencil_force_mpi = true; | ||||||
|  |  | ||||||
| /////////////////////////////////////////////////////////////// | /////////////////////////////////////////////////////////////// | ||||||
| // Info that is setup once and indept of cartesian layout | // Info that is setup once and indept of cartesian layout | ||||||
| /////////////////////////////////////////////////////////////// | /////////////////////////////////////////////////////////////// | ||||||
|   | |||||||
| @@ -1,4 +1,3 @@ | |||||||
|  |  | ||||||
| /************************************************************************************* | /************************************************************************************* | ||||||
|  |  | ||||||
|     Grid physics library, www.github.com/paboyle/Grid  |     Grid physics library, www.github.com/paboyle/Grid  | ||||||
| @@ -36,6 +35,8 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk> | |||||||
|  |  | ||||||
| NAMESPACE_BEGIN(Grid); | NAMESPACE_BEGIN(Grid); | ||||||
|  |  | ||||||
|  | extern bool Stencil_force_mpi ; | ||||||
|  |  | ||||||
| class CartesianCommunicator : public SharedMemory { | class CartesianCommunicator : public SharedMemory { | ||||||
|  |  | ||||||
| public:     | public:     | ||||||
| @@ -108,6 +109,8 @@ public: | |||||||
|   //////////////////////////////////////////////////////////// |   //////////////////////////////////////////////////////////// | ||||||
|   // Reduction |   // Reduction | ||||||
|   //////////////////////////////////////////////////////////// |   //////////////////////////////////////////////////////////// | ||||||
|  |   void GlobalMax(RealD &); | ||||||
|  |   void GlobalMax(RealF &); | ||||||
|   void GlobalSum(RealF &); |   void GlobalSum(RealF &); | ||||||
|   void GlobalSumVector(RealF *,int N); |   void GlobalSumVector(RealF *,int N); | ||||||
|   void GlobalSum(RealD &); |   void GlobalSum(RealD &); | ||||||
|   | |||||||
| @@ -275,6 +275,16 @@ void CartesianCommunicator::GlobalXOR(uint64_t &u){ | |||||||
|   int ierr=MPI_Allreduce(MPI_IN_PLACE,&u,1,MPI_UINT64_T,MPI_BXOR,communicator); |   int ierr=MPI_Allreduce(MPI_IN_PLACE,&u,1,MPI_UINT64_T,MPI_BXOR,communicator); | ||||||
|   assert(ierr==0); |   assert(ierr==0); | ||||||
| } | } | ||||||
|  | void CartesianCommunicator::GlobalMax(float &f) | ||||||
|  | { | ||||||
|  |   int ierr=MPI_Allreduce(MPI_IN_PLACE,&f,1,MPI_FLOAT,MPI_MAX,communicator); | ||||||
|  |   assert(ierr==0); | ||||||
|  | } | ||||||
|  | void CartesianCommunicator::GlobalMax(double &d) | ||||||
|  | { | ||||||
|  |   int ierr = MPI_Allreduce(MPI_IN_PLACE,&d,1,MPI_DOUBLE,MPI_MAX,communicator); | ||||||
|  |   assert(ierr==0); | ||||||
|  | } | ||||||
| void CartesianCommunicator::GlobalSum(float &f){ | void CartesianCommunicator::GlobalSum(float &f){ | ||||||
|   int ierr=MPI_Allreduce(MPI_IN_PLACE,&f,1,MPI_FLOAT,MPI_SUM,communicator); |   int ierr=MPI_Allreduce(MPI_IN_PLACE,&f,1,MPI_FLOAT,MPI_SUM,communicator); | ||||||
|   assert(ierr==0); |   assert(ierr==0); | ||||||
| @@ -360,7 +370,7 @@ double CartesianCommunicator::StencilSendToRecvFromBegin(std::vector<CommsReques | |||||||
|   double off_node_bytes=0.0; |   double off_node_bytes=0.0; | ||||||
|   int tag; |   int tag; | ||||||
|  |  | ||||||
|   if ( gfrom ==MPI_UNDEFINED) { |   if ( (gfrom ==MPI_UNDEFINED) || Stencil_force_mpi ) { | ||||||
|     tag= dir+from*32; |     tag= dir+from*32; | ||||||
|     ierr=MPI_Irecv(recv, bytes, MPI_CHAR,from,tag,communicator_halo[commdir],&rrq); |     ierr=MPI_Irecv(recv, bytes, MPI_CHAR,from,tag,communicator_halo[commdir],&rrq); | ||||||
|     assert(ierr==0); |     assert(ierr==0); | ||||||
| @@ -368,12 +378,18 @@ double CartesianCommunicator::StencilSendToRecvFromBegin(std::vector<CommsReques | |||||||
|     off_node_bytes+=bytes; |     off_node_bytes+=bytes; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   if ( gdest == MPI_UNDEFINED ) { |   if ( (gdest == MPI_UNDEFINED) || Stencil_force_mpi ) { | ||||||
|     tag= dir+_processor*32; |     tag= dir+_processor*32; | ||||||
|     ierr =MPI_Isend(xmit, bytes, MPI_CHAR,dest,tag,communicator_halo[commdir],&xrq); |     ierr =MPI_Isend(xmit, bytes, MPI_CHAR,dest,tag,communicator_halo[commdir],&xrq); | ||||||
|     assert(ierr==0); |     assert(ierr==0); | ||||||
|     list.push_back(xrq); |     list.push_back(xrq); | ||||||
|     off_node_bytes+=bytes; |     off_node_bytes+=bytes; | ||||||
|  |   } else { | ||||||
|  |     // TODO : make a OMP loop on CPU, call threaded bcopy | ||||||
|  |     void *shm = (void *) this->ShmBufferTranslate(dest,recv); | ||||||
|  |     assert(shm!=NULL); | ||||||
|  |     acceleratorCopyDeviceToDeviceAsynch(xmit,shm,bytes); | ||||||
|  |     acceleratorCopySynchronise(); // MPI prob slower | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   if ( CommunicatorPolicy == CommunicatorPolicySequential ) { |   if ( CommunicatorPolicy == CommunicatorPolicySequential ) { | ||||||
|   | |||||||
| @@ -67,6 +67,8 @@ CartesianCommunicator::CartesianCommunicator(const Coordinate &processors) | |||||||
|  |  | ||||||
| CartesianCommunicator::~CartesianCommunicator(){} | CartesianCommunicator::~CartesianCommunicator(){} | ||||||
|  |  | ||||||
|  | void CartesianCommunicator::GlobalMax(float &){} | ||||||
|  | void CartesianCommunicator::GlobalMax(double &){} | ||||||
| void CartesianCommunicator::GlobalSum(float &){} | void CartesianCommunicator::GlobalSum(float &){} | ||||||
| void CartesianCommunicator::GlobalSumVector(float *,int N){} | void CartesianCommunicator::GlobalSumVector(float *,int N){} | ||||||
| void CartesianCommunicator::GlobalSum(double &){} | void CartesianCommunicator::GlobalSum(double &){} | ||||||
|   | |||||||
| @@ -102,7 +102,7 @@ public: | |||||||
|   /////////////////////////////////////////////////// |   /////////////////////////////////////////////////// | ||||||
|   static void SharedMemoryAllocate(uint64_t bytes, int flags); |   static void SharedMemoryAllocate(uint64_t bytes, int flags); | ||||||
|   static void SharedMemoryFree(void); |   static void SharedMemoryFree(void); | ||||||
|   static void SharedMemoryCopy(void *dest,const void *src,size_t bytes); |   static void SharedMemoryCopy(void *dest,void *src,size_t bytes); | ||||||
|   static void SharedMemoryZero(void *dest,size_t bytes); |   static void SharedMemoryZero(void *dest,size_t bytes); | ||||||
|  |  | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -7,6 +7,7 @@ | |||||||
|     Copyright (C) 2015 |     Copyright (C) 2015 | ||||||
|  |  | ||||||
| Author: Peter Boyle <paboyle@ph.ed.ac.uk> | Author: Peter Boyle <paboyle@ph.ed.ac.uk> | ||||||
|  | Author: Christoph Lehner <christoph@lhnr.de> | ||||||
|  |  | ||||||
|     This program is free software; you can redistribute it and/or modify |     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 |     it under the terms of the GNU General Public License as published by | ||||||
| @@ -34,6 +35,9 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk> | |||||||
| #endif | #endif | ||||||
| #ifdef GRID_HIP | #ifdef GRID_HIP | ||||||
| #include <hip/hip_runtime_api.h> | #include <hip/hip_runtime_api.h> | ||||||
|  | #endif | ||||||
|  | #ifdef GRID_SYCl | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| NAMESPACE_BEGIN(Grid);  | NAMESPACE_BEGIN(Grid);  | ||||||
| @@ -69,6 +73,7 @@ void GlobalSharedMemory::Init(Grid_MPI_Comm comm) | |||||||
|   WorldNodes = WorldSize/WorldShmSize; |   WorldNodes = WorldSize/WorldShmSize; | ||||||
|   assert( (WorldNodes * WorldShmSize) == WorldSize ); |   assert( (WorldNodes * WorldShmSize) == WorldSize ); | ||||||
|  |  | ||||||
|  |  | ||||||
|   // FIXME: Check all WorldShmSize are the same ? |   // FIXME: Check all WorldShmSize are the same ? | ||||||
|  |  | ||||||
|   ///////////////////////////////////////////////////////////////////// |   ///////////////////////////////////////////////////////////////////// | ||||||
| @@ -169,6 +174,23 @@ static inline int divides(int a,int b) | |||||||
| } | } | ||||||
| void GlobalSharedMemory::GetShmDims(const Coordinate &WorldDims,Coordinate &ShmDims) | void GlobalSharedMemory::GetShmDims(const Coordinate &WorldDims,Coordinate &ShmDims) | ||||||
| { | { | ||||||
|  |   //////////////////////////////////////////////////////////////// | ||||||
|  |   // Allow user to configure through environment variable | ||||||
|  |   //////////////////////////////////////////////////////////////// | ||||||
|  |   char* str = getenv(("GRID_SHM_DIMS_" + std::to_string(ShmDims.size())).c_str()); | ||||||
|  |   if ( str ) { | ||||||
|  |     std::vector<int> IntShmDims; | ||||||
|  |     GridCmdOptionIntVector(std::string(str),IntShmDims); | ||||||
|  |     assert(IntShmDims.size() == WorldDims.size()); | ||||||
|  |     long ShmSize = 1; | ||||||
|  |     for (int dim=0;dim<WorldDims.size();dim++) { | ||||||
|  |       ShmSize *= (ShmDims[dim] = IntShmDims[dim]); | ||||||
|  |       assert(divides(ShmDims[dim],WorldDims[dim])); | ||||||
|  |     } | ||||||
|  |     assert(ShmSize == WorldShmSize); | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |    | ||||||
|   //////////////////////////////////////////////////////////////// |   //////////////////////////////////////////////////////////////// | ||||||
|   // Powers of 2,3,5 only in prime decomposition for now |   // Powers of 2,3,5 only in prime decomposition for now | ||||||
|   //////////////////////////////////////////////////////////////// |   //////////////////////////////////////////////////////////////// | ||||||
| @@ -428,7 +450,47 @@ void GlobalSharedMemory::SharedMemoryAllocate(uint64_t bytes, int flags) | |||||||
| //////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////// | ||||||
| // Hugetlbfs mapping intended | // Hugetlbfs mapping intended | ||||||
| //////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////// | ||||||
| #if defined(GRID_CUDA) ||defined(GRID_HIP) | #if defined(GRID_CUDA) ||defined(GRID_HIP)  || defined(GRID_SYCL) | ||||||
|  |  | ||||||
|  | //if defined(GRID_SYCL) | ||||||
|  | #if 0 | ||||||
|  | void GlobalSharedMemory::SharedMemoryAllocate(uint64_t bytes, int flags) | ||||||
|  | { | ||||||
|  |   void * ShmCommBuf ;  | ||||||
|  |   assert(_ShmSetup==1); | ||||||
|  |   assert(_ShmAlloc==0); | ||||||
|  |  | ||||||
|  |   ////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||||
|  |   // allocate the pointer array for shared windows for our group | ||||||
|  |   ////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||||
|  |   MPI_Barrier(WorldShmComm); | ||||||
|  |   WorldShmCommBufs.resize(WorldShmSize); | ||||||
|  |  | ||||||
|  |   /////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||||
|  |   // Each MPI rank should allocate our own buffer | ||||||
|  |   /////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||||
|  |   ShmCommBuf = acceleratorAllocDevice(bytes); | ||||||
|  |  | ||||||
|  |   if (ShmCommBuf == (void *)NULL ) { | ||||||
|  |     std::cerr << " SharedMemoryMPI.cc acceleratorAllocDevice failed NULL pointer for " << bytes<<" bytes " << std::endl; | ||||||
|  |     exit(EXIT_FAILURE);   | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   std::cout << WorldRank << header " SharedMemoryMPI.cc acceleratorAllocDevice "<< bytes  | ||||||
|  | 	    << "bytes at "<< std::hex<< ShmCommBuf <<std::dec<<" for comms buffers " <<std::endl; | ||||||
|  |  | ||||||
|  |   SharedMemoryZero(ShmCommBuf,bytes); | ||||||
|  |  | ||||||
|  |   assert(WorldShmSize == 1); | ||||||
|  |   for(int r=0;r<WorldShmSize;r++){ | ||||||
|  |     WorldShmCommBufs[r] = ShmCommBuf; | ||||||
|  |   } | ||||||
|  |   _ShmAllocBytes=bytes; | ||||||
|  |   _ShmAlloc=1; | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #if defined(GRID_CUDA) ||defined(GRID_HIP) ||defined(GRID_SYCL)   | ||||||
| void GlobalSharedMemory::SharedMemoryAllocate(uint64_t bytes, int flags) | void GlobalSharedMemory::SharedMemoryAllocate(uint64_t bytes, int flags) | ||||||
| { | { | ||||||
|   void * ShmCommBuf ;  |   void * ShmCommBuf ;  | ||||||
| @@ -452,18 +514,16 @@ void GlobalSharedMemory::SharedMemoryAllocate(uint64_t bytes, int flags) | |||||||
|   // Each MPI rank should allocate our own buffer |   // Each MPI rank should allocate our own buffer | ||||||
|   /////////////////////////////////////////////////////////////////////////////////////////////////////////// |   /////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||||
|   ShmCommBuf = acceleratorAllocDevice(bytes); |   ShmCommBuf = acceleratorAllocDevice(bytes); | ||||||
|  |  | ||||||
|   if (ShmCommBuf == (void *)NULL ) { |   if (ShmCommBuf == (void *)NULL ) { | ||||||
|     std::cerr << " SharedMemoryMPI.cc acceleratorAllocDevice failed NULL pointer for " << bytes<<" bytes " << std::endl; |     std::cerr << " SharedMemoryMPI.cc acceleratorAllocDevice failed NULL pointer for " << bytes<<" bytes " << std::endl; | ||||||
|     exit(EXIT_FAILURE);   |     exit(EXIT_FAILURE);   | ||||||
|   } |   } | ||||||
|   //  if ( WorldRank == 0 ){ |   if ( WorldRank == 0 ){ | ||||||
|   if ( 1 ){ |  | ||||||
|     std::cout << WorldRank << header " SharedMemoryMPI.cc acceleratorAllocDevice "<< bytes  |     std::cout << WorldRank << header " SharedMemoryMPI.cc acceleratorAllocDevice "<< bytes  | ||||||
| 	      << "bytes at "<< std::hex<< ShmCommBuf <<std::dec<<" for comms buffers " <<std::endl; | 	      << "bytes at "<< std::hex<< ShmCommBuf <<std::dec<<" for comms buffers " <<std::endl; | ||||||
|   } |   } | ||||||
|   SharedMemoryZero(ShmCommBuf,bytes); |   SharedMemoryZero(ShmCommBuf,bytes); | ||||||
|  |   std::cout<< "Setting up IPC"<<std::endl; | ||||||
|   /////////////////////////////////////////////////////////////////////////////////////////////////////////// |   /////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||||
|   // Loop over ranks/gpu's on our node |   // Loop over ranks/gpu's on our node | ||||||
|   /////////////////////////////////////////////////////////////////////////////////////////////////////////// |   /////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||||
| @@ -473,6 +533,29 @@ void GlobalSharedMemory::SharedMemoryAllocate(uint64_t bytes, int flags) | |||||||
|     ////////////////////////////////////////////////// |     ////////////////////////////////////////////////// | ||||||
|     // If it is me, pass around the IPC access key |     // If it is me, pass around the IPC access key | ||||||
|     ////////////////////////////////////////////////// |     ////////////////////////////////////////////////// | ||||||
|  |     void * thisBuf = ShmCommBuf; | ||||||
|  |     if(!Stencil_force_mpi) { | ||||||
|  | #ifdef GRID_SYCL_LEVEL_ZERO_IPC | ||||||
|  |     typedef struct { int fd; pid_t pid ; } clone_mem_t; | ||||||
|  |  | ||||||
|  |     auto zeDevice    = cl::sycl::get_native<cl::sycl::backend::level_zero>(theGridAccelerator->get_device()); | ||||||
|  |     auto zeContext   = cl::sycl::get_native<cl::sycl::backend::level_zero>(theGridAccelerator->get_context()); | ||||||
|  |        | ||||||
|  |     ze_ipc_mem_handle_t ihandle; | ||||||
|  |     clone_mem_t handle; | ||||||
|  |  | ||||||
|  |     if ( r==WorldShmRank ) {  | ||||||
|  |       auto err = zeMemGetIpcHandle(zeContext,ShmCommBuf,&ihandle); | ||||||
|  |       if ( err != ZE_RESULT_SUCCESS ) { | ||||||
|  | 	std::cout << "SharedMemoryMPI.cc zeMemGetIpcHandle failed for rank "<<r<<" "<<std::hex<<err<<std::dec<<std::endl; | ||||||
|  | 	exit(EXIT_FAILURE); | ||||||
|  |       } else { | ||||||
|  | 	std::cout << "SharedMemoryMPI.cc zeMemGetIpcHandle succeeded for rank "<<r<<" "<<std::hex<<err<<std::dec<<std::endl; | ||||||
|  |       } | ||||||
|  |       memcpy((void *)&handle.fd,(void *)&ihandle,sizeof(int)); | ||||||
|  |       handle.pid = getpid(); | ||||||
|  |     } | ||||||
|  | #endif | ||||||
| #ifdef GRID_CUDA | #ifdef GRID_CUDA | ||||||
|     cudaIpcMemHandle_t handle; |     cudaIpcMemHandle_t handle; | ||||||
|     if ( r==WorldShmRank ) {  |     if ( r==WorldShmRank ) {  | ||||||
| @@ -493,6 +576,7 @@ void GlobalSharedMemory::SharedMemoryAllocate(uint64_t bytes, int flags) | |||||||
|       } |       } | ||||||
|     } |     } | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|     ////////////////////////////////////////////////// |     ////////////////////////////////////////////////// | ||||||
|     // Share this IPC handle across the Shm Comm |     // Share this IPC handle across the Shm Comm | ||||||
|     ////////////////////////////////////////////////// |     ////////////////////////////////////////////////// | ||||||
| @@ -508,7 +592,35 @@ void GlobalSharedMemory::SharedMemoryAllocate(uint64_t bytes, int flags) | |||||||
|     /////////////////////////////////////////////////////////////// |     /////////////////////////////////////////////////////////////// | ||||||
|     // If I am not the source, overwrite thisBuf with remote buffer |     // If I am not the source, overwrite thisBuf with remote buffer | ||||||
|     /////////////////////////////////////////////////////////////// |     /////////////////////////////////////////////////////////////// | ||||||
|     void * thisBuf = ShmCommBuf; |  | ||||||
|  | #ifdef GRID_SYCL_LEVEL_ZERO_IPC | ||||||
|  |     if ( r!=WorldShmRank ) { | ||||||
|  |       thisBuf = nullptr; | ||||||
|  |       std::cout<<"mapping seeking remote pid/fd " | ||||||
|  | 	       <<handle.pid<<"/" | ||||||
|  | 	       <<handle.fd<<std::endl; | ||||||
|  |  | ||||||
|  |       int pidfd = syscall(SYS_pidfd_open,handle.pid,0); | ||||||
|  |       std::cout<<"Using IpcHandle pidfd "<<pidfd<<"\n"; | ||||||
|  |       //      int myfd  = syscall(SYS_pidfd_getfd,pidfd,handle.fd,0); | ||||||
|  |       int myfd  = syscall(438,pidfd,handle.fd,0); | ||||||
|  |  | ||||||
|  |       std::cout<<"Using IpcHandle myfd "<<myfd<<"\n"; | ||||||
|  |        | ||||||
|  |       memcpy((void *)&ihandle,(void *)&myfd,sizeof(int)); | ||||||
|  |  | ||||||
|  |       auto err = zeMemOpenIpcHandle(zeContext,zeDevice,ihandle,0,&thisBuf); | ||||||
|  |       if ( err != ZE_RESULT_SUCCESS ) { | ||||||
|  | 	std::cout << "SharedMemoryMPI.cc "<<zeContext<<" "<<zeDevice<<std::endl; | ||||||
|  | 	std::cout << "SharedMemoryMPI.cc zeMemOpenIpcHandle failed for rank "<<r<<" "<<std::hex<<err<<std::dec<<std::endl;  | ||||||
|  | 	exit(EXIT_FAILURE); | ||||||
|  |       } else { | ||||||
|  | 	std::cout << "SharedMemoryMPI.cc zeMemOpenIpcHandle succeeded for rank "<<r<<std::endl; | ||||||
|  | 	std::cout << "SharedMemoryMPI.cc zeMemOpenIpcHandle pointer is "<<std::hex<<thisBuf<<std::dec<<std::endl; | ||||||
|  |       } | ||||||
|  |       assert(thisBuf!=nullptr); | ||||||
|  |     } | ||||||
|  | #endif | ||||||
| #ifdef GRID_CUDA | #ifdef GRID_CUDA | ||||||
|     if ( r!=WorldShmRank ) {  |     if ( r!=WorldShmRank ) {  | ||||||
|       auto err = cudaIpcOpenMemHandle(&thisBuf,handle,cudaIpcMemLazyEnablePeerAccess); |       auto err = cudaIpcOpenMemHandle(&thisBuf,handle,cudaIpcMemLazyEnablePeerAccess); | ||||||
| @@ -530,6 +642,7 @@ void GlobalSharedMemory::SharedMemoryAllocate(uint64_t bytes, int flags) | |||||||
|     /////////////////////////////////////////////////////////////// |     /////////////////////////////////////////////////////////////// | ||||||
|     // Save a copy of the device buffers |     // Save a copy of the device buffers | ||||||
|     /////////////////////////////////////////////////////////////// |     /////////////////////////////////////////////////////////////// | ||||||
|  |     } | ||||||
|     WorldShmCommBufs[r] = thisBuf; |     WorldShmCommBufs[r] = thisBuf; | ||||||
| #else | #else | ||||||
|     WorldShmCommBufs[r] = ShmCommBuf; |     WorldShmCommBufs[r] = ShmCommBuf; | ||||||
| @@ -539,6 +652,8 @@ void GlobalSharedMemory::SharedMemoryAllocate(uint64_t bytes, int flags) | |||||||
|   _ShmAllocBytes=bytes; |   _ShmAllocBytes=bytes; | ||||||
|   _ShmAlloc=1; |   _ShmAlloc=1; | ||||||
| } | } | ||||||
|  | #endif | ||||||
|  |  | ||||||
| #else  | #else  | ||||||
| #ifdef GRID_MPI3_SHMMMAP | #ifdef GRID_MPI3_SHMMMAP | ||||||
| void GlobalSharedMemory::SharedMemoryAllocate(uint64_t bytes, int flags) | void GlobalSharedMemory::SharedMemoryAllocate(uint64_t bytes, int flags) | ||||||
| @@ -709,16 +824,16 @@ void GlobalSharedMemory::SharedMemoryAllocate(uint64_t bytes, int flags) | |||||||
| ///////////////////////////////////////////////////////////////////////// | ///////////////////////////////////////////////////////////////////////// | ||||||
| void GlobalSharedMemory::SharedMemoryZero(void *dest,size_t bytes) | void GlobalSharedMemory::SharedMemoryZero(void *dest,size_t bytes) | ||||||
| { | { | ||||||
| #ifdef GRID_CUDA | #if defined(GRID_CUDA) || defined(GRID_HIP) || defined(GRID_SYCL) | ||||||
|   cudaMemset(dest,0,bytes); |   acceleratorMemSet(dest,0,bytes); | ||||||
| #else | #else | ||||||
|   bzero(dest,bytes); |   bzero(dest,bytes); | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
| void GlobalSharedMemory::SharedMemoryCopy(void *dest,const void *src,size_t bytes) | void GlobalSharedMemory::SharedMemoryCopy(void *dest,void *src,size_t bytes) | ||||||
| { | { | ||||||
| #ifdef GRID_CUDA | #if defined(GRID_CUDA) || defined(GRID_HIP) || defined(GRID_SYCL) | ||||||
|   cudaMemcpy(dest,src,bytes,cudaMemcpyDefault); |   acceleratorCopyToDevice(src,dest,bytes); | ||||||
| #else    | #else    | ||||||
|   bcopy(src,dest,bytes); |   bcopy(src,dest,bytes); | ||||||
| #endif | #endif | ||||||
| @@ -782,7 +897,7 @@ void SharedMemory::SetCommunicator(Grid_MPI_Comm comm) | |||||||
|   } |   } | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|   SharedMemoryTest(); |   //SharedMemoryTest(); | ||||||
| } | } | ||||||
| ////////////////////////////////////////////////////////////////// | ////////////////////////////////////////////////////////////////// | ||||||
| // On node barrier | // On node barrier | ||||||
|   | |||||||
| @@ -29,6 +29,7 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk> | |||||||
| #include <Grid/GridCore.h> | #include <Grid/GridCore.h> | ||||||
|  |  | ||||||
| NAMESPACE_BEGIN(Grid);  | NAMESPACE_BEGIN(Grid);  | ||||||
|  | #define header "SharedMemoryNone: " | ||||||
|  |  | ||||||
| /*Construct from an MPI communicator*/ | /*Construct from an MPI communicator*/ | ||||||
| void GlobalSharedMemory::Init(Grid_MPI_Comm comm) | void GlobalSharedMemory::Init(Grid_MPI_Comm comm) | ||||||
| @@ -55,6 +56,38 @@ void GlobalSharedMemory::OptimalCommunicator(const Coordinate &processors,Grid_M | |||||||
| //////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////// | ||||||
| // Hugetlbfs mapping intended, use anonymous mmap | // Hugetlbfs mapping intended, use anonymous mmap | ||||||
| //////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////// | ||||||
|  | #if 1 | ||||||
|  | void GlobalSharedMemory::SharedMemoryAllocate(uint64_t bytes, int flags) | ||||||
|  | { | ||||||
|  |   std::cout << header "SharedMemoryAllocate "<< bytes<< " GPU implementation "<<std::endl; | ||||||
|  |   void * ShmCommBuf ;  | ||||||
|  |   assert(_ShmSetup==1); | ||||||
|  |   assert(_ShmAlloc==0); | ||||||
|  |  | ||||||
|  |   /////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||||
|  |   // Each MPI rank should allocate our own buffer | ||||||
|  |   /////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||||
|  |   ShmCommBuf = acceleratorAllocDevice(bytes); | ||||||
|  |  | ||||||
|  |   if (ShmCommBuf == (void *)NULL ) { | ||||||
|  |     std::cerr << " SharedMemoryNone.cc acceleratorAllocDevice failed NULL pointer for " << bytes<<" bytes " << std::endl; | ||||||
|  |     exit(EXIT_FAILURE);   | ||||||
|  |   } | ||||||
|  |   if ( WorldRank == 0 ){ | ||||||
|  |     std::cout << WorldRank << header " SharedMemoryNone.cc acceleratorAllocDevice "<< bytes  | ||||||
|  | 	      << "bytes at "<< std::hex<< ShmCommBuf <<std::dec<<" for comms buffers " <<std::endl; | ||||||
|  |   } | ||||||
|  |   SharedMemoryZero(ShmCommBuf,bytes); | ||||||
|  |  | ||||||
|  |   /////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||||
|  |   // Loop over ranks/gpu's on our node | ||||||
|  |   /////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||||
|  |   WorldShmCommBufs[0] = ShmCommBuf; | ||||||
|  |  | ||||||
|  |   _ShmAllocBytes=bytes; | ||||||
|  |   _ShmAlloc=1; | ||||||
|  | } | ||||||
|  | #else | ||||||
| void GlobalSharedMemory::SharedMemoryAllocate(uint64_t bytes, int flags) | void GlobalSharedMemory::SharedMemoryAllocate(uint64_t bytes, int flags) | ||||||
| { | { | ||||||
|   void * ShmCommBuf ;  |   void * ShmCommBuf ;  | ||||||
| @@ -83,7 +116,15 @@ void GlobalSharedMemory::SharedMemoryAllocate(uint64_t bytes, int flags) | |||||||
|   _ShmAllocBytes=bytes; |   _ShmAllocBytes=bytes; | ||||||
|   _ShmAlloc=1; |   _ShmAlloc=1; | ||||||
| }; | }; | ||||||
|  | #endif | ||||||
|  | void GlobalSharedMemory::SharedMemoryZero(void *dest,size_t bytes) | ||||||
|  | { | ||||||
|  |   acceleratorMemSet(dest,0,bytes); | ||||||
|  | } | ||||||
|  | void GlobalSharedMemory::SharedMemoryCopy(void *dest,void *src,size_t bytes) | ||||||
|  | { | ||||||
|  |   acceleratorCopyToDevice(src,dest,bytes); | ||||||
|  | } | ||||||
| //////////////////////////////////////////////////////// | //////////////////////////////////////////////////////// | ||||||
| // Global shared functionality finished | // Global shared functionality finished | ||||||
| // Now move to per communicator functionality | // Now move to per communicator functionality | ||||||
|   | |||||||
| @@ -110,9 +110,11 @@ Gather_plane_extract(const Lattice<vobj> &rhs, | |||||||
|   int n1=rhs.Grid()->_slice_stride[dimension]; |   int n1=rhs.Grid()->_slice_stride[dimension]; | ||||||
|  |  | ||||||
|   if ( cbmask ==0x3){ |   if ( cbmask ==0x3){ | ||||||
| #ifdef ACCELERATOR_CSHIFT     | #ifdef ACCELERATOR_CSHIFT | ||||||
|     autoView(rhs_v , rhs, AcceleratorRead); |     autoView(rhs_v , rhs, AcceleratorRead); | ||||||
|     accelerator_for2d(n,e1,b,e2,1,{ |     accelerator_for(nn,e1*e2,1,{ | ||||||
|  | 	int n = nn%e1; | ||||||
|  | 	int b = nn/e1; | ||||||
| 	int o      =   n*n1; | 	int o      =   n*n1; | ||||||
| 	int offset = b+n*e2; | 	int offset = b+n*e2; | ||||||
| 	 | 	 | ||||||
| @@ -135,7 +137,9 @@ Gather_plane_extract(const Lattice<vobj> &rhs, | |||||||
|     std::cout << " Dense packed buffer WARNING " <<std::endl; // Does this get called twice once for each cb? |     std::cout << " Dense packed buffer WARNING " <<std::endl; // Does this get called twice once for each cb? | ||||||
| #ifdef ACCELERATOR_CSHIFT     | #ifdef ACCELERATOR_CSHIFT     | ||||||
|     autoView(rhs_v , rhs, AcceleratorRead); |     autoView(rhs_v , rhs, AcceleratorRead); | ||||||
|     accelerator_for2d(n,e1,b,e2,1,{ |     accelerator_for(nn,e1*e2,1,{ | ||||||
|  | 	int n = nn%e1; | ||||||
|  | 	int b = nn/e1; | ||||||
|  |  | ||||||
| 	Coordinate coor; | 	Coordinate coor; | ||||||
|  |  | ||||||
| @@ -257,7 +261,9 @@ template<class vobj> void Scatter_plane_merge(Lattice<vobj> &rhs,ExtractPointerA | |||||||
|     int _slice_block = rhs.Grid()->_slice_block[dimension]; |     int _slice_block = rhs.Grid()->_slice_block[dimension]; | ||||||
| #ifdef ACCELERATOR_CSHIFT     | #ifdef ACCELERATOR_CSHIFT     | ||||||
|     autoView( rhs_v , rhs, AcceleratorWrite); |     autoView( rhs_v , rhs, AcceleratorWrite); | ||||||
|     accelerator_for2d(n,e1,b,e2,1,{ |     accelerator_for(nn,e1*e2,1,{ | ||||||
|  | 	int n = nn%e1; | ||||||
|  | 	int b = nn/e1; | ||||||
| 	int o      = n*_slice_stride; | 	int o      = n*_slice_stride; | ||||||
| 	int offset = b+n*_slice_block; | 	int offset = b+n*_slice_block; | ||||||
| 	merge(rhs_v[so+o+b],pointers,offset); | 	merge(rhs_v[so+o+b],pointers,offset); | ||||||
| @@ -274,7 +280,7 @@ template<class vobj> void Scatter_plane_merge(Lattice<vobj> &rhs,ExtractPointerA | |||||||
|  |  | ||||||
|     // Case of SIMD split AND checker dim cannot currently be hit, except in  |     // Case of SIMD split AND checker dim cannot currently be hit, except in  | ||||||
|     // Test_cshift_red_black code. |     // Test_cshift_red_black code. | ||||||
|     //    std::cout << "Scatter_plane merge assert(0); think this is buggy FIXME "<< std::endl;// think this is buggy FIXME |     std::cout << "Scatter_plane merge assert(0); think this is buggy FIXME "<< std::endl;// think this is buggy FIXME | ||||||
|     std::cout<<" Unthreaded warning -- buffer is not densely packed ??"<<std::endl; |     std::cout<<" Unthreaded warning -- buffer is not densely packed ??"<<std::endl; | ||||||
|     assert(0); // This will fail if hit on GPU |     assert(0); // This will fail if hit on GPU | ||||||
|     autoView( rhs_v, rhs, CpuWrite); |     autoView( rhs_v, rhs, CpuWrite); | ||||||
|   | |||||||
| @@ -122,8 +122,8 @@ template<class vobj> void Cshift_comms(Lattice<vobj> &ret,const Lattice<vobj> &r | |||||||
|   assert(shift<fd); |   assert(shift<fd); | ||||||
|    |    | ||||||
|   int buffer_size = rhs.Grid()->_slice_nblock[dimension]*rhs.Grid()->_slice_block[dimension]; |   int buffer_size = rhs.Grid()->_slice_nblock[dimension]*rhs.Grid()->_slice_block[dimension]; | ||||||
|   cshiftVector<vobj> send_buf(buffer_size); |   static cshiftVector<vobj> send_buf; send_buf.resize(buffer_size); | ||||||
|   cshiftVector<vobj> recv_buf(buffer_size); |   static cshiftVector<vobj> recv_buf; recv_buf.resize(buffer_size); | ||||||
|      |      | ||||||
|   int cb= (cbmask==0x2)? Odd : Even; |   int cb= (cbmask==0x2)? Odd : Even; | ||||||
|   int sshift= rhs.Grid()->CheckerBoardShiftForCB(rhs.Checkerboard(),dimension,shift,cb); |   int sshift= rhs.Grid()->CheckerBoardShiftForCB(rhs.Checkerboard(),dimension,shift,cb); | ||||||
| @@ -198,8 +198,8 @@ template<class vobj> void  Cshift_comms_simd(Lattice<vobj> &ret,const Lattice<vo | |||||||
|   int buffer_size = grid->_slice_nblock[dimension]*grid->_slice_block[dimension]; |   int buffer_size = grid->_slice_nblock[dimension]*grid->_slice_block[dimension]; | ||||||
|   //  int words = sizeof(vobj)/sizeof(vector_type); |   //  int words = sizeof(vobj)/sizeof(vector_type); | ||||||
|  |  | ||||||
|   std::vector<cshiftVector<scalar_object> >  send_buf_extract(Nsimd); |   static std::vector<cshiftVector<scalar_object> >  send_buf_extract; send_buf_extract.resize(Nsimd); | ||||||
|   std::vector<cshiftVector<scalar_object> >  recv_buf_extract(Nsimd); |   static std::vector<cshiftVector<scalar_object> >  recv_buf_extract; recv_buf_extract.resize(Nsimd); | ||||||
|   scalar_object *  recv_buf_extract_mpi; |   scalar_object *  recv_buf_extract_mpi; | ||||||
|   scalar_object *  send_buf_extract_mpi; |   scalar_object *  send_buf_extract_mpi; | ||||||
|   |   | ||||||
| @@ -294,8 +294,8 @@ template<class vobj> void Cshift_comms(Lattice<vobj> &ret,const Lattice<vobj> &r | |||||||
|   assert(shift<fd); |   assert(shift<fd); | ||||||
|    |    | ||||||
|   int buffer_size = rhs.Grid()->_slice_nblock[dimension]*rhs.Grid()->_slice_block[dimension]; |   int buffer_size = rhs.Grid()->_slice_nblock[dimension]*rhs.Grid()->_slice_block[dimension]; | ||||||
|   cshiftVector<vobj> send_buf_v(buffer_size); |   static cshiftVector<vobj> send_buf_v; send_buf_v.resize(buffer_size); | ||||||
|   cshiftVector<vobj> recv_buf_v(buffer_size); |   static cshiftVector<vobj> recv_buf_v; recv_buf_v.resize(buffer_size); | ||||||
|   vobj *send_buf; |   vobj *send_buf; | ||||||
|   vobj *recv_buf; |   vobj *recv_buf; | ||||||
|   { |   { | ||||||
| @@ -381,8 +381,8 @@ template<class vobj> void  Cshift_comms_simd(Lattice<vobj> &ret,const Lattice<vo | |||||||
|   int buffer_size = grid->_slice_nblock[dimension]*grid->_slice_block[dimension]; |   int buffer_size = grid->_slice_nblock[dimension]*grid->_slice_block[dimension]; | ||||||
|   //  int words = sizeof(vobj)/sizeof(vector_type); |   //  int words = sizeof(vobj)/sizeof(vector_type); | ||||||
|  |  | ||||||
|   std::vector<cshiftVector<scalar_object> >  send_buf_extract(Nsimd); |   static std::vector<cshiftVector<scalar_object> >  send_buf_extract; send_buf_extract.resize(Nsimd); | ||||||
|   std::vector<cshiftVector<scalar_object> >  recv_buf_extract(Nsimd); |   static std::vector<cshiftVector<scalar_object> >  recv_buf_extract; recv_buf_extract.resize(Nsimd); | ||||||
|   scalar_object *  recv_buf_extract_mpi; |   scalar_object *  recv_buf_extract_mpi; | ||||||
|   scalar_object *  send_buf_extract_mpi; |   scalar_object *  send_buf_extract_mpi; | ||||||
|   { |   { | ||||||
|   | |||||||
| @@ -46,3 +46,4 @@ Author: Peter Boyle <paboyle@ph.ed.ac.uk> | |||||||
| #include <Grid/lattice/Lattice_unary.h> | #include <Grid/lattice/Lattice_unary.h> | ||||||
| #include <Grid/lattice/Lattice_transfer.h> | #include <Grid/lattice/Lattice_transfer.h> | ||||||
| #include <Grid/lattice/Lattice_basis.h> | #include <Grid/lattice/Lattice_basis.h> | ||||||
|  | #include <Grid/lattice/Lattice_crc.h> | ||||||
|   | |||||||
| @@ -225,7 +225,7 @@ void axpy(Lattice<vobj> &ret,sobj a,const Lattice<vobj> &x,const Lattice<vobj> & | |||||||
|   autoView( x_v , x, AcceleratorRead); |   autoView( x_v , x, AcceleratorRead); | ||||||
|   autoView( y_v , y, AcceleratorRead); |   autoView( y_v , y, AcceleratorRead); | ||||||
|   accelerator_for(ss,x_v.size(),vobj::Nsimd(),{ |   accelerator_for(ss,x_v.size(),vobj::Nsimd(),{ | ||||||
|     auto tmp = a*x_v(ss)+y_v(ss); |     auto tmp = a*coalescedRead(x_v[ss])+coalescedRead(y_v[ss]); | ||||||
|     coalescedWrite(ret_v[ss],tmp); |     coalescedWrite(ret_v[ss],tmp); | ||||||
|   }); |   }); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -62,7 +62,7 @@ void basisRotate(VField &basis,Matrix& Qt,int j0, int j1, int k0,int k1,int Nm) | |||||||
|     basis_v.push_back(basis[k].View(AcceleratorWrite)); |     basis_v.push_back(basis[k].View(AcceleratorWrite)); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| #if ( (!defined(GRID_SYCL)) && (!defined(GRID_CUDA)) ) | #if ( (!defined(GRID_CUDA)) ) | ||||||
|   int max_threads = thread_max(); |   int max_threads = thread_max(); | ||||||
|   Vector < vobj > Bt(Nm * max_threads); |   Vector < vobj > Bt(Nm * max_threads); | ||||||
|   thread_region |   thread_region | ||||||
| @@ -125,7 +125,7 @@ void basisRotate(VField &basis,Matrix& Qt,int j0, int j1, int k0,int k1,int Nm) | |||||||
|  |  | ||||||
| 	for(int k=k0; k<k1; ++k){ | 	for(int k=k0; k<k1; ++k){ | ||||||
| 	  auto tmp = coalescedRead(Bp[ss*nrot+j]); | 	  auto tmp = coalescedRead(Bp[ss*nrot+j]); | ||||||
| 	  coalescedWrite(Bp[ss*nrot+j],tmp+ Qt_p[jj*Nm+k] * coalescedRead(basis_v[k][sss])); | 	  coalescedWrite(Bp[ss*nrot+j],tmp+ Qt_p[jj*Nm+k] * coalescedRead(basis_vp[k][sss])); | ||||||
| 	} | 	} | ||||||
|       }); |       }); | ||||||
|  |  | ||||||
| @@ -134,7 +134,7 @@ void basisRotate(VField &basis,Matrix& Qt,int j0, int j1, int k0,int k1,int Nm) | |||||||
| 	int jj  =j0+j; | 	int jj  =j0+j; | ||||||
| 	int ss =sj/nrot; | 	int ss =sj/nrot; | ||||||
| 	int sss=ss+s; | 	int sss=ss+s; | ||||||
| 	coalescedWrite(basis_v[jj][sss],coalescedRead(Bp[ss*nrot+j])); | 	coalescedWrite(basis_vp[jj][sss],coalescedRead(Bp[ss*nrot+j])); | ||||||
|       }); |       }); | ||||||
|   } |   } | ||||||
| #endif | #endif | ||||||
| @@ -164,7 +164,8 @@ void basisRotateJ(Field &result,std::vector<Field> &basis,Eigen::MatrixXd& Qt,in | |||||||
|   auto basis_vp=& basis_v[0]; |   auto basis_vp=& basis_v[0]; | ||||||
|   autoView(result_v,result,AcceleratorWrite); |   autoView(result_v,result,AcceleratorWrite); | ||||||
|   accelerator_for(ss, grid->oSites(),vobj::Nsimd(),{ |   accelerator_for(ss, grid->oSites(),vobj::Nsimd(),{ | ||||||
|     auto B=coalescedRead(zz); |     vobj zzz=Zero(); | ||||||
|  |     auto B=coalescedRead(zzz); | ||||||
|     for(int k=k0; k<k1; ++k){ |     for(int k=k0; k<k1; ++k){ | ||||||
|       B +=Qt_j[k] * coalescedRead(basis_vp[k][ss]); |       B +=Qt_j[k] * coalescedRead(basis_vp[k][ss]); | ||||||
|     } |     } | ||||||
|   | |||||||
							
								
								
									
										55
									
								
								Grid/lattice/Lattice_crc.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								Grid/lattice/Lattice_crc.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | |||||||
|  | /************************************************************************************* | ||||||
|  |  | ||||||
|  |     Grid physics library, www.github.com/paboyle/Grid  | ||||||
|  |  | ||||||
|  |     Source file: ./lib/lattice/Lattice_crc.h | ||||||
|  |  | ||||||
|  |     Copyright (C) 2021 | ||||||
|  |  | ||||||
|  | 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 */ | ||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | NAMESPACE_BEGIN(Grid); | ||||||
|  |  | ||||||
|  | template<class vobj> void DumpSliceNorm(std::string s,Lattice<vobj> &f,int mu=-1) | ||||||
|  | { | ||||||
|  |   auto ff = localNorm2(f); | ||||||
|  |   if ( mu==-1 ) mu = f.Grid()->Nd()-1; | ||||||
|  |   typedef typename vobj::tensor_reduced normtype; | ||||||
|  |   typedef typename normtype::scalar_object scalar; | ||||||
|  |   std::vector<scalar> sff; | ||||||
|  |   sliceSum(ff,sff,mu); | ||||||
|  |   for(int t=0;t<sff.size();t++){ | ||||||
|  |     std::cout << s<<" "<<t<<" "<<sff[t]<<std::endl; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | template<class vobj> uint32_t crc(Lattice<vobj> & buf) | ||||||
|  | { | ||||||
|  |   autoView( buf_v , buf, CpuRead); | ||||||
|  |   return ::crc32(0L,(unsigned char *)&buf_v[0],(size_t)sizeof(vobj)*buf.oSites()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #define CRC(U) std::cout << "FingerPrint "<<__FILE__ <<" "<< __LINE__ <<" "<< #U <<" "<<crc(U)<<std::endl; | ||||||
|  |  | ||||||
|  | NAMESPACE_END(Grid); | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -96,8 +96,34 @@ inline typename vobj::scalar_objectD sumD_cpu(const vobj *arg, Integer osites) | |||||||
|   ssobj ret = ssum; |   ssobj ret = ssum; | ||||||
|   return ret; |   return ret; | ||||||
| } | } | ||||||
|  | /* | ||||||
|  | Threaded max, don't use for now | ||||||
|  | template<class Double> | ||||||
|  | inline Double max(const Double *arg, Integer osites) | ||||||
|  | { | ||||||
|  |   //  const int Nsimd = vobj::Nsimd(); | ||||||
|  |   const int nthread = GridThread::GetThreads(); | ||||||
|  |  | ||||||
|  |   std::vector<Double> maxarray(nthread); | ||||||
|  |    | ||||||
|  |   thread_for(thr,nthread, { | ||||||
|  |     int nwork, mywork, myoff; | ||||||
|  |     nwork = osites; | ||||||
|  |     GridThread::GetWork(nwork,thr,mywork,myoff); | ||||||
|  |     Double max=arg[0]; | ||||||
|  |     for(int ss=myoff;ss<mywork+myoff; ss++){ | ||||||
|  |       if( arg[ss] > max ) max = arg[ss]; | ||||||
|  |     } | ||||||
|  |     maxarray[thr]=max; | ||||||
|  |   }); | ||||||
|  |    | ||||||
|  |   Double tmax=maxarray[0]; | ||||||
|  |   for(int i=0;i<nthread;i++){ | ||||||
|  |     if (maxarray[i]>tmax) tmax = maxarray[i]; | ||||||
|  |   }  | ||||||
|  |   return tmax; | ||||||
|  | } | ||||||
|  | */ | ||||||
| template<class vobj> | template<class vobj> | ||||||
| inline typename vobj::scalar_object sum(const vobj *arg, Integer osites) | inline typename vobj::scalar_object sum(const vobj *arg, Integer osites) | ||||||
| { | { | ||||||
| @@ -141,6 +167,32 @@ template<class vobj> inline RealD norm2(const Lattice<vobj> &arg){ | |||||||
|   return real(nrm);  |   return real(nrm);  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | //The global maximum of the site norm2 | ||||||
|  | template<class vobj> inline RealD maxLocalNorm2(const Lattice<vobj> &arg) | ||||||
|  | { | ||||||
|  |   typedef typename vobj::tensor_reduced vscalar;  //iScalar<iScalar<.... <vPODtype> > > | ||||||
|  |   typedef typename vscalar::scalar_object  scalar;   //iScalar<iScalar<.... <PODtype> > > | ||||||
|  |  | ||||||
|  |   Lattice<vscalar> inner = localNorm2(arg); | ||||||
|  |  | ||||||
|  |   auto grid = arg.Grid(); | ||||||
|  |  | ||||||
|  |   RealD max; | ||||||
|  |   for(int l=0;l<grid->lSites();l++){ | ||||||
|  |     Coordinate coor; | ||||||
|  |     scalar val; | ||||||
|  |     RealD r; | ||||||
|  |     grid->LocalIndexToLocalCoor(l,coor); | ||||||
|  |     peekLocalSite(val,inner,coor); | ||||||
|  |     r=real(TensorRemove(val)); | ||||||
|  |     if( (l==0) || (r>max)){ | ||||||
|  |       max=r; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   grid->GlobalMax(max); | ||||||
|  |   return max; | ||||||
|  | } | ||||||
|  |  | ||||||
| // Double inner product | // Double inner product | ||||||
| template<class vobj> | template<class vobj> | ||||||
| inline ComplexD rankInnerProduct(const Lattice<vobj> &left,const Lattice<vobj> &right) | inline ComplexD rankInnerProduct(const Lattice<vobj> &left,const Lattice<vobj> &right) | ||||||
| @@ -309,6 +361,7 @@ template<class vobj> inline void sliceSum(const Lattice<vobj> &Data,std::vector< | |||||||
|   // But easily avoided by using double precision fields |   // But easily avoided by using double precision fields | ||||||
|   /////////////////////////////////////////////////////// |   /////////////////////////////////////////////////////// | ||||||
|   typedef typename vobj::scalar_object sobj; |   typedef typename vobj::scalar_object sobj; | ||||||
|  |   typedef typename vobj::scalar_object::scalar_type scalar_type; | ||||||
|   GridBase  *grid = Data.Grid(); |   GridBase  *grid = Data.Grid(); | ||||||
|   assert(grid!=NULL); |   assert(grid!=NULL); | ||||||
|  |  | ||||||
| @@ -367,20 +420,19 @@ template<class vobj> inline void sliceSum(const Lattice<vobj> &Data,std::vector< | |||||||
|   } |   } | ||||||
|    |    | ||||||
|   // sum over nodes. |   // sum over nodes. | ||||||
|   sobj gsum; |  | ||||||
|   for(int t=0;t<fd;t++){ |   for(int t=0;t<fd;t++){ | ||||||
|     int pt = t/ld; // processor plane |     int pt = t/ld; // processor plane | ||||||
|     int lt = t%ld; |     int lt = t%ld; | ||||||
|     if ( pt == grid->_processor_coor[orthogdim] ) { |     if ( pt == grid->_processor_coor[orthogdim] ) { | ||||||
|       gsum=lsSum[lt]; |       result[t]=lsSum[lt]; | ||||||
|     } else { |     } else { | ||||||
|       gsum=Zero(); |       result[t]=Zero(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     grid->GlobalSum(gsum); |  | ||||||
|  |  | ||||||
|     result[t]=gsum; |  | ||||||
|   } |   } | ||||||
|  |   scalar_type * ptr = (scalar_type *) &result[0]; | ||||||
|  |   int words = fd*sizeof(sobj)/sizeof(scalar_type); | ||||||
|  |   grid->GlobalSumVector(ptr, words); | ||||||
| } | } | ||||||
|  |  | ||||||
| template<class vobj> | template<class vobj> | ||||||
|   | |||||||
| @@ -32,8 +32,9 @@ | |||||||
| #include <random> | #include <random> | ||||||
|  |  | ||||||
| #ifdef RNG_SITMO | #ifdef RNG_SITMO | ||||||
| #include <Grid/sitmo_rng/sitmo_prng_engine.hpp> | #include <Grid/random/sitmo_prng_engine.hpp> | ||||||
| #endif  | #endif  | ||||||
|  | #include <Grid/random/gaussian.h> | ||||||
|  |  | ||||||
| #if defined(RNG_SITMO) | #if defined(RNG_SITMO) | ||||||
| #define RNG_FAST_DISCARD | #define RNG_FAST_DISCARD | ||||||
| @@ -142,7 +143,7 @@ public: | |||||||
|  |  | ||||||
|   std::vector<RngEngine>                             _generators; |   std::vector<RngEngine>                             _generators; | ||||||
|   std::vector<std::uniform_real_distribution<RealD> > _uniform; |   std::vector<std::uniform_real_distribution<RealD> > _uniform; | ||||||
|   std::vector<std::normal_distribution<RealD> >       _gaussian; |   std::vector<Grid::gaussian_distribution<RealD> >    _gaussian; | ||||||
|   std::vector<std::discrete_distribution<int32_t> >   _bernoulli; |   std::vector<std::discrete_distribution<int32_t> >   _bernoulli; | ||||||
|   std::vector<std::uniform_int_distribution<uint32_t> > _uid; |   std::vector<std::uniform_int_distribution<uint32_t> > _uid; | ||||||
|  |  | ||||||
| @@ -243,7 +244,7 @@ public: | |||||||
|   GridSerialRNG() : GridRNGbase() { |   GridSerialRNG() : GridRNGbase() { | ||||||
|     _generators.resize(1); |     _generators.resize(1); | ||||||
|     _uniform.resize(1,std::uniform_real_distribution<RealD>{0,1}); |     _uniform.resize(1,std::uniform_real_distribution<RealD>{0,1}); | ||||||
|     _gaussian.resize(1,std::normal_distribution<RealD>(0.0,1.0) ); |     _gaussian.resize(1,gaussian_distribution<RealD>(0.0,1.0) ); | ||||||
|     _bernoulli.resize(1,std::discrete_distribution<int32_t>{1,1}); |     _bernoulli.resize(1,std::discrete_distribution<int32_t>{1,1}); | ||||||
|     _uid.resize(1,std::uniform_int_distribution<uint32_t>() ); |     _uid.resize(1,std::uniform_int_distribution<uint32_t>() ); | ||||||
|   } |   } | ||||||
| @@ -357,7 +358,7 @@ public: | |||||||
|  |  | ||||||
|     _generators.resize(_vol); |     _generators.resize(_vol); | ||||||
|     _uniform.resize(_vol,std::uniform_real_distribution<RealD>{0,1}); |     _uniform.resize(_vol,std::uniform_real_distribution<RealD>{0,1}); | ||||||
|     _gaussian.resize(_vol,std::normal_distribution<RealD>(0.0,1.0) ); |     _gaussian.resize(_vol,gaussian_distribution<RealD>(0.0,1.0) ); | ||||||
|     _bernoulli.resize(_vol,std::discrete_distribution<int32_t>{1,1}); |     _bernoulli.resize(_vol,std::discrete_distribution<int32_t>{1,1}); | ||||||
|     _uid.resize(_vol,std::uniform_int_distribution<uint32_t>() ); |     _uid.resize(_vol,std::uniform_int_distribution<uint32_t>() ); | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -97,6 +97,20 @@ accelerator_inline void convertType(ComplexF & out, const std::complex<float> & | |||||||
|   out = in; |   out = in; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | template<typename T> | ||||||
|  | accelerator_inline EnableIf<isGridFundamental<T>> convertType(T & out, const T & in) { | ||||||
|  |   out = in; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // This would allow for conversions between GridFundamental types, but is not strictly needed as yet | ||||||
|  | /*template<typename T1, typename T2> | ||||||
|  | accelerator_inline typename std::enable_if<isGridFundamental<T1>::value && isGridFundamental<T2>::value>::type | ||||||
|  | // Or to make this very broad, conversions between anything that's not a GridTensor could be allowed | ||||||
|  | //accelerator_inline typename std::enable_if<!isGridTensor<T1>::value && !isGridTensor<T2>::value>::type | ||||||
|  | convertType(T1 & out, const T2 & in) { | ||||||
|  |   out = in; | ||||||
|  | }*/ | ||||||
|  |  | ||||||
| #ifdef GRID_SIMT | #ifdef GRID_SIMT | ||||||
| accelerator_inline void convertType(vComplexF & out, const ComplexF & in) { | accelerator_inline void convertType(vComplexF & out, const ComplexF & in) { | ||||||
|   ((ComplexF*)&out)[acceleratorSIMTlane(vComplexF::Nsimd())] = in; |   ((ComplexF*)&out)[acceleratorSIMTlane(vComplexF::Nsimd())] = in; | ||||||
| @@ -117,18 +131,18 @@ accelerator_inline void convertType(vComplexD2 & out, const vComplexF & in) { | |||||||
|   Optimization::PrecisionChange::StoD(in.v,out._internal[0].v,out._internal[1].v); |   Optimization::PrecisionChange::StoD(in.v,out._internal[0].v,out._internal[1].v); | ||||||
| } | } | ||||||
|  |  | ||||||
| template<typename T1,typename T2,int N> | template<typename T1,typename T2> | ||||||
|   accelerator_inline void convertType(iMatrix<T1,N> & out, const iMatrix<T2,N> & in); | accelerator_inline void convertType(iScalar<T1> & out, const iScalar<T2> & in) { | ||||||
| template<typename T1,typename T2,int N> |   convertType(out._internal,in._internal); | ||||||
|   accelerator_inline void convertType(iVector<T1,N> & out, const iVector<T2,N> & in); | } | ||||||
|  |  | ||||||
| template<typename T1,typename T2, typename std::enable_if<!isGridScalar<T1>::value, T1>::type* = nullptr> | template<typename T1,typename T2> | ||||||
| accelerator_inline void convertType(T1 & out, const iScalar<T2> & in) { | accelerator_inline NotEnableIf<isGridScalar<T1>> convertType(T1 & out, const iScalar<T2> & in) { | ||||||
|   convertType(out,in._internal); |   convertType(out,in._internal); | ||||||
| } | } | ||||||
|  |  | ||||||
| template<typename T1,typename T2> | template<typename T1,typename T2> | ||||||
| accelerator_inline void convertType(iScalar<T1> & out, const T2 & in) { | accelerator_inline NotEnableIf<isGridScalar<T2>> convertType(iScalar<T1> & out, const T2 & in) { | ||||||
|   convertType(out._internal,in); |   convertType(out._internal,in); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -145,11 +159,6 @@ accelerator_inline void convertType(iVector<T1,N> & out, const iVector<T2,N> & i | |||||||
|     convertType(out._internal[i],in._internal[i]); |     convertType(out._internal[i],in._internal[i]); | ||||||
| } | } | ||||||
|  |  | ||||||
| template<typename T, typename std::enable_if<isGridFundamental<T>::value, T>::type* = nullptr> |  | ||||||
| accelerator_inline void convertType(T & out, const T & in) { |  | ||||||
|   out = in; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| template<typename T1,typename T2> | template<typename T1,typename T2> | ||||||
| accelerator_inline void convertType(Lattice<T1> & out, const Lattice<T2> & in) { | accelerator_inline void convertType(Lattice<T1> & out, const Lattice<T2> & in) { | ||||||
|   autoView( out_v , out,AcceleratorWrite); |   autoView( out_v , out,AcceleratorWrite); | ||||||
| @@ -355,16 +364,22 @@ inline void blockSum(Lattice<vobj> &coarseData,const Lattice<vobj> &fineData) | |||||||
|   autoView( coarseData_ , coarseData, AcceleratorWrite); |   autoView( coarseData_ , coarseData, AcceleratorWrite); | ||||||
|   autoView( fineData_   , fineData, AcceleratorRead); |   autoView( fineData_   , fineData, AcceleratorRead); | ||||||
|  |  | ||||||
|  |   auto coarseData_p = &coarseData_[0]; | ||||||
|  |   auto fineData_p = &fineData_[0]; | ||||||
|  |    | ||||||
|   Coordinate fine_rdimensions = fine->_rdimensions; |   Coordinate fine_rdimensions = fine->_rdimensions; | ||||||
|   Coordinate coarse_rdimensions = coarse->_rdimensions; |   Coordinate coarse_rdimensions = coarse->_rdimensions; | ||||||
|  |  | ||||||
|  |   vobj zz = Zero(); | ||||||
|    |    | ||||||
|   accelerator_for(sc,coarse->oSites(),1,{ |   accelerator_for(sc,coarse->oSites(),1,{ | ||||||
|  |  | ||||||
|       // One thread per sub block |       // One thread per sub block | ||||||
|       Coordinate coor_c(_ndimension); |       Coordinate coor_c(_ndimension); | ||||||
|       Lexicographic::CoorFromIndex(coor_c,sc,coarse_rdimensions);  // Block coordinate |       Lexicographic::CoorFromIndex(coor_c,sc,coarse_rdimensions);  // Block coordinate | ||||||
|       coarseData_[sc]=Zero(); |  | ||||||
|  |  | ||||||
|  |       vobj cd = zz; | ||||||
|  |        | ||||||
|       for(int sb=0;sb<blockVol;sb++){ |       for(int sb=0;sb<blockVol;sb++){ | ||||||
|  |  | ||||||
| 	int sf; | 	int sf; | ||||||
| @@ -374,9 +389,11 @@ inline void blockSum(Lattice<vobj> &coarseData,const Lattice<vobj> &fineData) | |||||||
| 	for(int d=0;d<_ndimension;d++) coor_f[d]=coor_c[d]*block_r[d] + coor_b[d]; | 	for(int d=0;d<_ndimension;d++) coor_f[d]=coor_c[d]*block_r[d] + coor_b[d]; | ||||||
| 	Lexicographic::IndexFromCoor(coor_f,sf,fine_rdimensions); | 	Lexicographic::IndexFromCoor(coor_f,sf,fine_rdimensions); | ||||||
|  |  | ||||||
| 	coarseData_[sc]=coarseData_[sc]+fineData_[sf]; | 	cd=cd+fineData_p[sf]; | ||||||
|       } |       } | ||||||
|  |  | ||||||
|  |       coarseData_p[sc] = cd; | ||||||
|  |  | ||||||
|     }); |     }); | ||||||
|   return; |   return; | ||||||
| } | } | ||||||
| @@ -768,7 +785,7 @@ void ExtractSliceLocal(Lattice<vobj> &lowDim,const Lattice<vobj> & higherDim,int | |||||||
|  |  | ||||||
|  |  | ||||||
| template<class vobj> | template<class vobj> | ||||||
| void Replicate(Lattice<vobj> &coarse,Lattice<vobj> & fine) | void Replicate(const Lattice<vobj> &coarse,Lattice<vobj> & fine) | ||||||
| { | { | ||||||
|   typedef typename vobj::scalar_object sobj; |   typedef typename vobj::scalar_object sobj; | ||||||
|  |  | ||||||
| @@ -993,54 +1010,96 @@ vectorizeFromRevLexOrdArray( std::vector<sobj> &in, Lattice<vobj> &out) | |||||||
|   }); |   }); | ||||||
| } | } | ||||||
|  |  | ||||||
| //Convert a Lattice from one precision to another | //The workspace for a precision change operation allowing for the reuse of the mapping to save time on subsequent calls | ||||||
| template<class VobjOut, class VobjIn> | class precisionChangeWorkspace{ | ||||||
| void precisionChange(Lattice<VobjOut> &out, const Lattice<VobjIn> &in) |   std::pair<Integer,Integer>* fmap_device; //device pointer | ||||||
| { | public: | ||||||
|   assert(out.Grid()->Nd() == in.Grid()->Nd()); |   precisionChangeWorkspace(GridBase *out_grid, GridBase *in_grid){ | ||||||
|   for(int d=0;d<out.Grid()->Nd();d++){ |     //Build a map between the sites and lanes of the output field and the input field as we cannot use the Grids on the device | ||||||
|     assert(out.Grid()->FullDimensions()[d] == in.Grid()->FullDimensions()[d]); |     assert(out_grid->Nd() == in_grid->Nd()); | ||||||
|   } |     for(int d=0;d<out_grid->Nd();d++){ | ||||||
|   out.Checkerboard() = in.Checkerboard(); |       assert(out_grid->FullDimensions()[d] == in_grid->FullDimensions()[d]); | ||||||
|   GridBase *in_grid=in.Grid(); |  | ||||||
|   GridBase *out_grid = out.Grid(); |  | ||||||
|  |  | ||||||
|   typedef typename VobjOut::scalar_object SobjOut; |  | ||||||
|   typedef typename VobjIn::scalar_object SobjIn; |  | ||||||
|  |  | ||||||
|   int ndim = out.Grid()->Nd(); |  | ||||||
|   int out_nsimd = out_grid->Nsimd(); |  | ||||||
|      |  | ||||||
|   std::vector<Coordinate > out_icoor(out_nsimd); |  | ||||||
|        |  | ||||||
|   for(int lane=0; lane < out_nsimd; lane++){ |  | ||||||
|     out_icoor[lane].resize(ndim); |  | ||||||
|     out_grid->iCoorFromIindex(out_icoor[lane], lane); |  | ||||||
|   } |  | ||||||
|          |  | ||||||
|   std::vector<SobjOut> in_slex_conv(in_grid->lSites()); |  | ||||||
|   unvectorizeToLexOrdArray(in_slex_conv, in); |  | ||||||
|      |  | ||||||
|   autoView( out_v , out, CpuWrite); |  | ||||||
|   thread_for(out_oidx,out_grid->oSites(),{ |  | ||||||
|     Coordinate out_ocoor(ndim); |  | ||||||
|     out_grid->oCoorFromOindex(out_ocoor, out_oidx); |  | ||||||
|  |  | ||||||
|     ExtractPointerArray<SobjOut> ptrs(out_nsimd);       |  | ||||||
|  |  | ||||||
|     Coordinate lcoor(out_grid->Nd()); |  | ||||||
|        |  | ||||||
|     for(int lane=0; lane < out_nsimd; lane++){ |  | ||||||
|       for(int mu=0;mu<ndim;mu++) |  | ||||||
| 	lcoor[mu] = out_ocoor[mu] + out_grid->_rdimensions[mu]*out_icoor[lane][mu]; |  | ||||||
| 	 |  | ||||||
|       int llex; Lexicographic::IndexFromCoor(lcoor, llex, out_grid->_ldimensions); |  | ||||||
|       ptrs[lane] = &in_slex_conv[llex]; |  | ||||||
|     } |     } | ||||||
|     merge(out_v[out_oidx], ptrs, 0); |     int Nsimd_out = out_grid->Nsimd(); | ||||||
|   }); |  | ||||||
|  |     std::vector<Coordinate> out_icorrs(out_grid->Nsimd()); //reuse these | ||||||
|  |     for(int lane=0; lane < out_grid->Nsimd(); lane++) | ||||||
|  |       out_grid->iCoorFromIindex(out_icorrs[lane], lane); | ||||||
|  |    | ||||||
|  |     std::vector<std::pair<Integer,Integer> > fmap_host(out_grid->lSites()); //lsites = osites*Nsimd | ||||||
|  |     thread_for(out_oidx,out_grid->oSites(),{ | ||||||
|  | 	Coordinate out_ocorr;  | ||||||
|  | 	out_grid->oCoorFromOindex(out_ocorr, out_oidx); | ||||||
|  |        | ||||||
|  | 	Coordinate lcorr; //the local coordinate (common to both in and out as full coordinate) | ||||||
|  | 	for(int out_lane=0; out_lane < Nsimd_out; out_lane++){ | ||||||
|  | 	  out_grid->InOutCoorToLocalCoor(out_ocorr, out_icorrs[out_lane], lcorr); | ||||||
|  | 	 | ||||||
|  | 	  //int in_oidx = in_grid->oIndex(lcorr), in_lane = in_grid->iIndex(lcorr); | ||||||
|  | 	  //Note oIndex and OcorrFromOindex (and same for iIndex) are not inverse for checkerboarded lattice, the former coordinates being defined on the full lattice and the latter on the reduced lattice | ||||||
|  | 	  //Until this is fixed we need to circumvent the problem locally. Here I will use the coordinates defined on the reduced lattice for simplicity | ||||||
|  | 	  int in_oidx = 0, in_lane = 0; | ||||||
|  | 	  for(int d=0;d<in_grid->_ndimension;d++){ | ||||||
|  | 	    in_oidx += in_grid->_ostride[d] * ( lcorr[d] % in_grid->_rdimensions[d] ); | ||||||
|  | 	    in_lane += in_grid->_istride[d] * ( lcorr[d] / in_grid->_rdimensions[d] ); | ||||||
|  | 	  } | ||||||
|  | 	  fmap_host[out_lane + Nsimd_out*out_oidx] = std::pair<Integer,Integer>( in_oidx, in_lane ); | ||||||
|  | 	} | ||||||
|  |       }); | ||||||
|  |  | ||||||
|  |     //Copy the map to the device (if we had a way to tell if an accelerator is in use we could avoid this copy for CPU-only machines) | ||||||
|  |     size_t fmap_bytes = out_grid->lSites() * sizeof(std::pair<Integer,Integer>); | ||||||
|  |     fmap_device = (std::pair<Integer,Integer>*)acceleratorAllocDevice(fmap_bytes); | ||||||
|  |     acceleratorCopyToDevice(fmap_host.data(), fmap_device, fmap_bytes);  | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   //Prevent moving or copying | ||||||
|  |   precisionChangeWorkspace(const precisionChangeWorkspace &r) = delete; | ||||||
|  |   precisionChangeWorkspace(precisionChangeWorkspace &&r) = delete; | ||||||
|  |   precisionChangeWorkspace &operator=(const precisionChangeWorkspace &r) = delete; | ||||||
|  |   precisionChangeWorkspace &operator=(precisionChangeWorkspace &&r) = delete; | ||||||
|  |    | ||||||
|  |   std::pair<Integer,Integer> const* getMap() const{ return fmap_device; } | ||||||
|  |  | ||||||
|  |   ~precisionChangeWorkspace(){ | ||||||
|  |     acceleratorFreeDevice(fmap_device); | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | //Convert a lattice of one precision to another. The input workspace contains the mapping data. | ||||||
|  | template<class VobjOut, class VobjIn> | ||||||
|  | void precisionChange(Lattice<VobjOut> &out, const Lattice<VobjIn> &in, const precisionChangeWorkspace &workspace){ | ||||||
|  |   static_assert( std::is_same<typename VobjOut::DoublePrecision, typename VobjIn::DoublePrecision>::value == 1, "copyLane: tensor types must be the same" ); //if tensor types are same the DoublePrecision type must be the same | ||||||
|  |  | ||||||
|  |   out.Checkerboard() = in.Checkerboard(); | ||||||
|  |   constexpr int Nsimd_out = VobjOut::Nsimd(); | ||||||
|  |  | ||||||
|  |   std::pair<Integer,Integer> const* fmap_device = workspace.getMap(); | ||||||
|  |  | ||||||
|  |   //Do the copy/precision change | ||||||
|  |   autoView( out_v , out, AcceleratorWrite); | ||||||
|  |   autoView( in_v , in, AcceleratorRead); | ||||||
|  |  | ||||||
|  |   accelerator_for(out_oidx, out.Grid()->oSites(), 1,{ | ||||||
|  |       std::pair<Integer,Integer> const* fmap_osite = fmap_device + out_oidx*Nsimd_out; | ||||||
|  |       for(int out_lane=0; out_lane < Nsimd_out; out_lane++){       | ||||||
|  | 	int in_oidx = fmap_osite[out_lane].first; | ||||||
|  | 	int in_lane = fmap_osite[out_lane].second; | ||||||
|  | 	copyLane(out_v[out_oidx], out_lane, in_v[in_oidx], in_lane); | ||||||
|  |       } | ||||||
|  |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | //Convert a Lattice from one precision to another | ||||||
|  | //Generate the workspace in place; if multiple calls with the same mapping are performed, consider pregenerating the workspace and reusing | ||||||
|  | template<class VobjOut, class VobjIn> | ||||||
|  | void precisionChange(Lattice<VobjOut> &out, const Lattice<VobjIn> &in){ | ||||||
|  |   precisionChangeWorkspace workspace(out.Grid(), in.Grid()); | ||||||
|  |   precisionChange(out, in, workspace); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
| //////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// | ||||||
| // Communicate between grids | // Communicate between grids | ||||||
| //////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// | ||||||
|   | |||||||
| @@ -67,9 +67,14 @@ public: | |||||||
|   accelerator_inline const vobj & operator()(size_t i) const { return this->_odata[i]; } |   accelerator_inline const vobj & operator()(size_t i) const { return this->_odata[i]; } | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | #if 1 | ||||||
|  |   //  accelerator_inline const vobj & operator[](size_t i) const { return this->_odata[i]; }; | ||||||
|  |   accelerator_inline vobj       & operator[](size_t i) const { return this->_odata[i]; }; | ||||||
|  | #else | ||||||
|   accelerator_inline const vobj & operator[](size_t i) const { return this->_odata[i]; }; |   accelerator_inline const vobj & operator[](size_t i) const { return this->_odata[i]; }; | ||||||
|   accelerator_inline vobj       & operator[](size_t i)       { return this->_odata[i]; }; |   accelerator_inline vobj       & operator[](size_t i)       { return this->_odata[i]; }; | ||||||
|  | #endif | ||||||
|  |    | ||||||
|   accelerator_inline uint64_t begin(void) const { return 0;}; |   accelerator_inline uint64_t begin(void) const { return 0;}; | ||||||
|   accelerator_inline uint64_t end(void)   const { return this->_odata_size; }; |   accelerator_inline uint64_t end(void)   const { return this->_odata_size; }; | ||||||
|   accelerator_inline uint64_t size(void)  const { return this->_odata_size; }; |   accelerator_inline uint64_t size(void)  const { return this->_odata_size; }; | ||||||
|   | |||||||
| @@ -43,7 +43,7 @@ inline void whereWolf(Lattice<vobj> &ret,const Lattice<iobj> &predicate,Lattice< | |||||||
|   conformable(iftrue,predicate); |   conformable(iftrue,predicate); | ||||||
|   conformable(iftrue,ret); |   conformable(iftrue,ret); | ||||||
|  |  | ||||||
|   GridBase *grid=iftrue._grid; |   GridBase *grid=iftrue.Grid(); | ||||||
|  |  | ||||||
|   typedef typename vobj::scalar_object scalar_object; |   typedef typename vobj::scalar_object scalar_object; | ||||||
|   typedef typename vobj::scalar_type scalar_type; |   typedef typename vobj::scalar_type scalar_type; | ||||||
| @@ -52,22 +52,23 @@ inline void whereWolf(Lattice<vobj> &ret,const Lattice<iobj> &predicate,Lattice< | |||||||
|  |  | ||||||
|   const int Nsimd = grid->Nsimd(); |   const int Nsimd = grid->Nsimd(); | ||||||
|  |  | ||||||
|   std::vector<Integer> mask(Nsimd); |   autoView(iftrue_v,iftrue,CpuRead); | ||||||
|   std::vector<scalar_object> truevals (Nsimd); |   autoView(iffalse_v,iffalse,CpuRead); | ||||||
|   std::vector<scalar_object> falsevals(Nsimd); |   autoView(predicate_v,predicate,CpuRead); | ||||||
|  |   autoView(ret_v,ret,CpuWrite); | ||||||
|   parallel_for(int ss=0;ss<iftrue._grid->oSites(); ss++){ |   Integer NN= grid->oSites(); | ||||||
|  |   thread_for(ss,NN,{ | ||||||
|     extract(iftrue._odata[ss]   ,truevals); |     Integer mask; | ||||||
|     extract(iffalse._odata[ss]  ,falsevals); |     scalar_object trueval; | ||||||
|     extract<vInteger,Integer>(TensorRemove(predicate._odata[ss]),mask); |     scalar_object falseval; | ||||||
|  |     for(int l=0;l<Nsimd;l++){ | ||||||
|     for(int s=0;s<Nsimd;s++){ |       trueval =extractLane(l,iftrue_v[ss]); | ||||||
|       if (mask[s]) falsevals[s]=truevals[s]; |       falseval=extractLane(l,iffalse_v[ss]); | ||||||
|  |       mask    =extractLane(l,predicate_v[ss]); | ||||||
|  |       if (mask) falseval=trueval; | ||||||
|  |       insertLane(l,ret_v[ss],falseval); | ||||||
|     } |     } | ||||||
|  |   }); | ||||||
|     merge(ret._odata[ss],falsevals); |  | ||||||
|   } |  | ||||||
| } | } | ||||||
|  |  | ||||||
| template<class vobj,class iobj> | template<class vobj,class iobj> | ||||||
| @@ -76,9 +77,9 @@ inline Lattice<vobj> whereWolf(const Lattice<iobj> &predicate,Lattice<vobj> &ift | |||||||
|   conformable(iftrue,iffalse); |   conformable(iftrue,iffalse); | ||||||
|   conformable(iftrue,predicate); |   conformable(iftrue,predicate); | ||||||
|  |  | ||||||
|   Lattice<vobj> ret(iftrue._grid); |   Lattice<vobj> ret(iftrue.Grid()); | ||||||
|  |  | ||||||
|   where(ret,predicate,iftrue,iffalse); |   whereWolf(ret,predicate,iftrue,iffalse); | ||||||
|  |  | ||||||
|   return ret; |   return ret; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -69,6 +69,7 @@ GridLogger GridLogDebug  (1, "Debug", GridLogColours, "PURPLE"); | |||||||
| GridLogger GridLogPerformance(1, "Performance", GridLogColours, "GREEN"); | GridLogger GridLogPerformance(1, "Performance", GridLogColours, "GREEN"); | ||||||
| GridLogger GridLogIterative  (1, "Iterative", GridLogColours, "BLUE"); | GridLogger GridLogIterative  (1, "Iterative", GridLogColours, "BLUE"); | ||||||
| GridLogger GridLogIntegrator (1, "Integrator", GridLogColours, "BLUE"); | GridLogger GridLogIntegrator (1, "Integrator", GridLogColours, "BLUE"); | ||||||
|  | GridLogger GridLogHMC (1, "HMC", GridLogColours, "BLUE"); | ||||||
|  |  | ||||||
| void GridLogConfigure(std::vector<std::string> &logstreams) { | void GridLogConfigure(std::vector<std::string> &logstreams) { | ||||||
|   GridLogError.Active(0); |   GridLogError.Active(0); | ||||||
| @@ -79,6 +80,7 @@ void GridLogConfigure(std::vector<std::string> &logstreams) { | |||||||
|   GridLogPerformance.Active(0); |   GridLogPerformance.Active(0); | ||||||
|   GridLogIntegrator.Active(1); |   GridLogIntegrator.Active(1); | ||||||
|   GridLogColours.Active(0); |   GridLogColours.Active(0); | ||||||
|  |   GridLogHMC.Active(1); | ||||||
|  |  | ||||||
|   for (int i = 0; i < logstreams.size(); i++) { |   for (int i = 0; i < logstreams.size(); i++) { | ||||||
|     if (logstreams[i] == std::string("Error"))       GridLogError.Active(1); |     if (logstreams[i] == std::string("Error"))       GridLogError.Active(1); | ||||||
| @@ -87,7 +89,8 @@ void GridLogConfigure(std::vector<std::string> &logstreams) { | |||||||
|     if (logstreams[i] == std::string("Iterative"))   GridLogIterative.Active(1); |     if (logstreams[i] == std::string("Iterative"))   GridLogIterative.Active(1); | ||||||
|     if (logstreams[i] == std::string("Debug"))       GridLogDebug.Active(1); |     if (logstreams[i] == std::string("Debug"))       GridLogDebug.Active(1); | ||||||
|     if (logstreams[i] == std::string("Performance")) GridLogPerformance.Active(1); |     if (logstreams[i] == std::string("Performance")) GridLogPerformance.Active(1); | ||||||
|     if (logstreams[i] == std::string("Integrator"))  GridLogIntegrator.Active(1); |     if (logstreams[i] == std::string("NoIntegrator"))  GridLogIntegrator.Active(0); | ||||||
|  |     if (logstreams[i] == std::string("NoHMC"))         GridLogHMC.Active(0); | ||||||
|     if (logstreams[i] == std::string("Colours"))     GridLogColours.Active(1); |     if (logstreams[i] == std::string("Colours"))     GridLogColours.Active(1); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -182,6 +182,7 @@ extern GridLogger GridLogDebug  ; | |||||||
| extern GridLogger GridLogPerformance; | extern GridLogger GridLogPerformance; | ||||||
| extern GridLogger GridLogIterative  ; | extern GridLogger GridLogIterative  ; | ||||||
| extern GridLogger GridLogIntegrator  ; | extern GridLogger GridLogIntegrator  ; | ||||||
|  | extern GridLogger GridLogHMC; | ||||||
| extern Colours    GridLogColours; | extern Colours    GridLogColours; | ||||||
|  |  | ||||||
| std::string demangle(const char* name) ; | std::string demangle(const char* name) ; | ||||||
|   | |||||||
| @@ -123,7 +123,7 @@ assert(GRID_FIELD_NORM_CALC(FieldNormMetaData_, n2ck) < 1.0e-5); | |||||||
|  //////////////////////////////////////////////////////////// |  //////////////////////////////////////////////////////////// | ||||||
|  // Helper to fill out metadata |  // Helper to fill out metadata | ||||||
|  //////////////////////////////////////////////////////////// |  //////////////////////////////////////////////////////////// | ||||||
|  template<class vobj> void ScidacMetaData(Lattice<vobj> & field, | template<class vobj> void ScidacMetaData(Lattice<vobj> & field, | ||||||
| 					  FieldMetaData &header, | 					  FieldMetaData &header, | ||||||
| 					  scidacRecord & _scidacRecord, | 					  scidacRecord & _scidacRecord, | ||||||
| 					  scidacFile   & _scidacFile)  | 					  scidacFile   & _scidacFile)  | ||||||
| @@ -619,12 +619,12 @@ class IldgWriter : public ScidacWriter { | |||||||
|   // Don't require scidac records EXCEPT checksum |   // Don't require scidac records EXCEPT checksum | ||||||
|   // Use Grid MetaData object if present. |   // Use Grid MetaData object if present. | ||||||
|   //////////////////////////////////////////////////////////////// |   //////////////////////////////////////////////////////////////// | ||||||
|   template <class vsimd> |   template <class stats = PeriodicGaugeStatistics> | ||||||
|   void writeConfiguration(Lattice<iLorentzColourMatrix<vsimd> > &Umu,int sequence,std::string LFN,std::string description)  |   void writeConfiguration(Lattice<vLorentzColourMatrixD > &Umu,int sequence,std::string LFN,std::string description)  | ||||||
|   { |   { | ||||||
|     GridBase * grid = Umu.Grid(); |     GridBase * grid = Umu.Grid(); | ||||||
|     typedef Lattice<iLorentzColourMatrix<vsimd> > GaugeField; |     typedef Lattice<vLorentzColourMatrixD> GaugeField; | ||||||
|     typedef iLorentzColourMatrix<vsimd> vobj; |     typedef vLorentzColourMatrixD vobj; | ||||||
|     typedef typename vobj::scalar_object sobj; |     typedef typename vobj::scalar_object sobj; | ||||||
|  |  | ||||||
|     //////////////////////////////////////// |     //////////////////////////////////////// | ||||||
| @@ -636,6 +636,9 @@ class IldgWriter : public ScidacWriter { | |||||||
|  |  | ||||||
|     ScidacMetaData(Umu,header,_scidacRecord,_scidacFile); |     ScidacMetaData(Umu,header,_scidacRecord,_scidacFile); | ||||||
|  |  | ||||||
|  |     stats Stats; | ||||||
|  |     Stats(Umu,header); | ||||||
|  |      | ||||||
|     std::string format = header.floating_point; |     std::string format = header.floating_point; | ||||||
|     header.ensemble_id    = description; |     header.ensemble_id    = description; | ||||||
|     header.ensemble_label = description; |     header.ensemble_label = description; | ||||||
| @@ -705,10 +708,10 @@ class IldgReader : public GridLimeReader { | |||||||
|   // Else use ILDG MetaData object if present. |   // Else use ILDG MetaData object if present. | ||||||
|   // Else use SciDAC MetaData object if present. |   // Else use SciDAC MetaData object if present. | ||||||
|   //////////////////////////////////////////////////////////////// |   //////////////////////////////////////////////////////////////// | ||||||
|   template <class vsimd> |   template <class stats = PeriodicGaugeStatistics> | ||||||
|   void readConfiguration(Lattice<iLorentzColourMatrix<vsimd> > &Umu, FieldMetaData &FieldMetaData_) { |   void readConfiguration(Lattice<vLorentzColourMatrixD> &Umu, FieldMetaData &FieldMetaData_) { | ||||||
|  |  | ||||||
|     typedef Lattice<iLorentzColourMatrix<vsimd> > GaugeField; |     typedef Lattice<vLorentzColourMatrixD > GaugeField; | ||||||
|     typedef typename GaugeField::vector_object  vobj; |     typedef typename GaugeField::vector_object  vobj; | ||||||
|     typedef typename vobj::scalar_object sobj; |     typedef typename vobj::scalar_object sobj; | ||||||
|  |  | ||||||
| @@ -921,7 +924,8 @@ class IldgReader : public GridLimeReader { | |||||||
|  |  | ||||||
|     if ( found_FieldMetaData || found_usqcdInfo ) { |     if ( found_FieldMetaData || found_usqcdInfo ) { | ||||||
|       FieldMetaData checker; |       FieldMetaData checker; | ||||||
|       GaugeStatistics(Umu,checker); |       stats Stats; | ||||||
|  |       Stats(Umu,checker); | ||||||
|       assert(fabs(checker.plaquette  - FieldMetaData_.plaquette )<1.0e-5); |       assert(fabs(checker.plaquette  - FieldMetaData_.plaquette )<1.0e-5); | ||||||
|       assert(fabs(checker.link_trace - FieldMetaData_.link_trace)<1.0e-5); |       assert(fabs(checker.link_trace - FieldMetaData_.link_trace)<1.0e-5); | ||||||
|       std::cout << GridLogMessage<<"Plaquette and link trace match " << std::endl; |       std::cout << GridLogMessage<<"Plaquette and link trace match " << std::endl; | ||||||
|   | |||||||
| @@ -128,7 +128,7 @@ inline void MachineCharacteristics(FieldMetaData &header) | |||||||
|   std::time_t t = std::time(nullptr); |   std::time_t t = std::time(nullptr); | ||||||
|   std::tm tm_ = *std::localtime(&t); |   std::tm tm_ = *std::localtime(&t); | ||||||
|   std::ostringstream oss;  |   std::ostringstream oss;  | ||||||
|   //      oss << std::put_time(&tm_, "%c %Z"); |   oss << std::put_time(&tm_, "%c %Z"); | ||||||
|   header.creation_date = oss.str(); |   header.creation_date = oss.str(); | ||||||
|   header.archive_date  = header.creation_date; |   header.archive_date  = header.creation_date; | ||||||
|  |  | ||||||
| @@ -176,29 +176,18 @@ template<class vobj> inline void PrepareMetaData(Lattice<vobj> & field, FieldMet | |||||||
|   GridMetaData(grid,header);  |   GridMetaData(grid,header);  | ||||||
|   MachineCharacteristics(header); |   MachineCharacteristics(header); | ||||||
| } | } | ||||||
| inline void GaugeStatistics(Lattice<vLorentzColourMatrixF> & data,FieldMetaData &header) | template<class Impl> | ||||||
|  | class GaugeStatistics | ||||||
| { | { | ||||||
|   // How to convert data precision etc... | public: | ||||||
|   header.link_trace=WilsonLoops<PeriodicGimplF>::linkTrace(data); |   void operator()(Lattice<vLorentzColourMatrixD> & data,FieldMetaData &header) | ||||||
|   header.plaquette =WilsonLoops<PeriodicGimplF>::avgPlaquette(data); |   { | ||||||
| } |     header.link_trace=WilsonLoops<Impl>::linkTrace(data); | ||||||
| inline void GaugeStatistics(Lattice<vLorentzColourMatrixD> & data,FieldMetaData &header) |     header.plaquette =WilsonLoops<Impl>::avgPlaquette(data); | ||||||
| { |   } | ||||||
|   // How to convert data precision etc... | }; | ||||||
|   header.link_trace=WilsonLoops<PeriodicGimplD>::linkTrace(data); | typedef GaugeStatistics<PeriodicGimplD> PeriodicGaugeStatistics; | ||||||
|   header.plaquette =WilsonLoops<PeriodicGimplD>::avgPlaquette(data); | typedef GaugeStatistics<ConjugateGimplD> ConjugateGaugeStatistics; | ||||||
| } |  | ||||||
| template<> inline void PrepareMetaData<vLorentzColourMatrixF>(Lattice<vLorentzColourMatrixF> & field, FieldMetaData &header) |  | ||||||
| { |  | ||||||
|     |  | ||||||
|   GridBase *grid = field.Grid(); |  | ||||||
|   std::string format = getFormatString<vLorentzColourMatrixF>(); |  | ||||||
|   header.floating_point = format; |  | ||||||
|   header.checksum = 0x0; // Nersc checksum unused in ILDG, Scidac |  | ||||||
|   GridMetaData(grid,header);  |  | ||||||
|   GaugeStatistics(field,header); |  | ||||||
|   MachineCharacteristics(header); |  | ||||||
| } |  | ||||||
| template<> inline void PrepareMetaData<vLorentzColourMatrixD>(Lattice<vLorentzColourMatrixD> & field, FieldMetaData &header) | template<> inline void PrepareMetaData<vLorentzColourMatrixD>(Lattice<vLorentzColourMatrixD> & field, FieldMetaData &header) | ||||||
| { | { | ||||||
|   GridBase *grid = field.Grid(); |   GridBase *grid = field.Grid(); | ||||||
| @@ -206,7 +195,6 @@ template<> inline void PrepareMetaData<vLorentzColourMatrixD>(Lattice<vLorentzCo | |||||||
|   header.floating_point = format; |   header.floating_point = format; | ||||||
|   header.checksum = 0x0; // Nersc checksum unused in ILDG, Scidac |   header.checksum = 0x0; // Nersc checksum unused in ILDG, Scidac | ||||||
|   GridMetaData(grid,header);  |   GridMetaData(grid,header);  | ||||||
|   GaugeStatistics(field,header); |  | ||||||
|   MachineCharacteristics(header); |   MachineCharacteristics(header); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -39,6 +39,10 @@ using namespace Grid; | |||||||
| //////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// | ||||||
| class NerscIO : public BinaryIO {  | class NerscIO : public BinaryIO {  | ||||||
| public: | public: | ||||||
|  |   typedef Lattice<vLorentzColourMatrixD> GaugeField; | ||||||
|  |  | ||||||
|  |   // Enable/disable exiting if the plaquette in the header does not match the value computed (default true) | ||||||
|  |   static bool & exitOnReadPlaquetteMismatch(){ static bool v=true; return v; } | ||||||
|  |  | ||||||
|   static inline void truncate(std::string file){ |   static inline void truncate(std::string file){ | ||||||
|     std::ofstream fout(file,std::ios::out); |     std::ofstream fout(file,std::ios::out); | ||||||
| @@ -129,12 +133,12 @@ public: | |||||||
|   // Now the meat: the object readers |   // Now the meat: the object readers | ||||||
|   ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |   ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||||
|  |  | ||||||
|   template<class vsimd> |   template<class GaugeStats=PeriodicGaugeStatistics> | ||||||
|   static inline void readConfiguration(Lattice<iLorentzColourMatrix<vsimd> > &Umu, |   static inline void readConfiguration(GaugeField &Umu, | ||||||
| 				       FieldMetaData& header, | 				       FieldMetaData& header, | ||||||
| 				       std::string file) | 				       std::string file, | ||||||
|  | 				       GaugeStats GaugeStatisticsCalculator=GaugeStats()) | ||||||
|   { |   { | ||||||
|     typedef Lattice<iLorentzColourMatrix<vsimd> > GaugeField; |  | ||||||
|  |  | ||||||
|     GridBase *grid = Umu.Grid(); |     GridBase *grid = Umu.Grid(); | ||||||
|     uint64_t offset = readHeader(file,Umu.Grid(),header); |     uint64_t offset = readHeader(file,Umu.Grid(),header); | ||||||
| @@ -153,23 +157,23 @@ public: | |||||||
|     // munger is a function of <floating point, Real, data_type> |     // munger is a function of <floating point, Real, data_type> | ||||||
|     if ( header.data_type == std::string("4D_SU3_GAUGE") ) { |     if ( header.data_type == std::string("4D_SU3_GAUGE") ) { | ||||||
|       if ( ieee32 || ieee32big ) { |       if ( ieee32 || ieee32big ) { | ||||||
| 	BinaryIO::readLatticeObject<iLorentzColourMatrix<vsimd>, LorentzColour2x3F>  | 	BinaryIO::readLatticeObject<vLorentzColourMatrixD, LorentzColour2x3F>  | ||||||
| 	  (Umu,file,Gauge3x2munger<LorentzColour2x3F,LorentzColourMatrix>(), offset,format, | 	  (Umu,file,Gauge3x2munger<LorentzColour2x3F,LorentzColourMatrix>(), offset,format, | ||||||
| 	   nersc_csum,scidac_csuma,scidac_csumb); | 	   nersc_csum,scidac_csuma,scidac_csumb); | ||||||
|       } |       } | ||||||
|       if ( ieee64 || ieee64big ) { |       if ( ieee64 || ieee64big ) { | ||||||
| 	BinaryIO::readLatticeObject<iLorentzColourMatrix<vsimd>, LorentzColour2x3D>  | 	BinaryIO::readLatticeObject<vLorentzColourMatrixD, LorentzColour2x3D>  | ||||||
| 	  (Umu,file,Gauge3x2munger<LorentzColour2x3D,LorentzColourMatrix>(),offset,format, | 	  (Umu,file,Gauge3x2munger<LorentzColour2x3D,LorentzColourMatrix>(),offset,format, | ||||||
| 	   nersc_csum,scidac_csuma,scidac_csumb); | 	   nersc_csum,scidac_csuma,scidac_csumb); | ||||||
|       } |       } | ||||||
|     } else if ( header.data_type == std::string("4D_SU3_GAUGE_3x3") ) { |     } else if ( header.data_type == std::string("4D_SU3_GAUGE_3x3") ) { | ||||||
|       if ( ieee32 || ieee32big ) { |       if ( ieee32 || ieee32big ) { | ||||||
| 	BinaryIO::readLatticeObject<iLorentzColourMatrix<vsimd>,LorentzColourMatrixF> | 	BinaryIO::readLatticeObject<vLorentzColourMatrixD,LorentzColourMatrixF> | ||||||
| 	  (Umu,file,GaugeSimpleMunger<LorentzColourMatrixF,LorentzColourMatrix>(),offset,format, | 	  (Umu,file,GaugeSimpleMunger<LorentzColourMatrixF,LorentzColourMatrix>(),offset,format, | ||||||
| 	   nersc_csum,scidac_csuma,scidac_csumb); | 	   nersc_csum,scidac_csuma,scidac_csumb); | ||||||
|       } |       } | ||||||
|       if ( ieee64 || ieee64big ) { |       if ( ieee64 || ieee64big ) { | ||||||
| 	BinaryIO::readLatticeObject<iLorentzColourMatrix<vsimd>,LorentzColourMatrixD> | 	BinaryIO::readLatticeObject<vLorentzColourMatrixD,LorentzColourMatrixD> | ||||||
| 	  (Umu,file,GaugeSimpleMunger<LorentzColourMatrixD,LorentzColourMatrix>(),offset,format, | 	  (Umu,file,GaugeSimpleMunger<LorentzColourMatrixD,LorentzColourMatrix>(),offset,format, | ||||||
| 	   nersc_csum,scidac_csuma,scidac_csumb); | 	   nersc_csum,scidac_csuma,scidac_csumb); | ||||||
|       } |       } | ||||||
| @@ -177,7 +181,7 @@ public: | |||||||
|       assert(0); |       assert(0); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     GaugeStatistics(Umu,clone); |     GaugeStats Stats; Stats(Umu,clone); | ||||||
|  |  | ||||||
|     std::cout<<GridLogMessage <<"NERSC Configuration "<<file<<" checksum "<<std::hex<<nersc_csum<< std::dec |     std::cout<<GridLogMessage <<"NERSC Configuration "<<file<<" checksum "<<std::hex<<nersc_csum<< std::dec | ||||||
| 	     <<" header   "<<std::hex<<header.checksum<<std::dec <<std::endl; | 	     <<" header   "<<std::hex<<header.checksum<<std::dec <<std::endl; | ||||||
| @@ -196,22 +200,29 @@ public: | |||||||
|       std::cerr << " nersc_csum  " <<std::hex<< nersc_csum << " " << header.checksum<< std::dec<< std::endl; |       std::cerr << " nersc_csum  " <<std::hex<< nersc_csum << " " << header.checksum<< std::dec<< std::endl; | ||||||
|       exit(0); |       exit(0); | ||||||
|     } |     } | ||||||
|     assert(fabs(clone.plaquette -header.plaquette ) < 1.0e-5 ); |     if(exitOnReadPlaquetteMismatch()) assert(fabs(clone.plaquette -header.plaquette ) < 1.0e-5 ); | ||||||
|     assert(fabs(clone.link_trace-header.link_trace) < 1.0e-6 ); |     assert(fabs(clone.link_trace-header.link_trace) < 1.0e-6 ); | ||||||
|     assert(nersc_csum == header.checksum ); |     assert(nersc_csum == header.checksum ); | ||||||
|        |        | ||||||
|     std::cout<<GridLogMessage <<"NERSC Configuration "<<file<< " and plaquette, link trace, and checksum agree"<<std::endl; |     std::cout<<GridLogMessage <<"NERSC Configuration "<<file<< " and plaquette, link trace, and checksum agree"<<std::endl; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   template<class vsimd> |   // Preferred interface | ||||||
|   static inline void writeConfiguration(Lattice<iLorentzColourMatrix<vsimd> > &Umu, |   template<class GaugeStats=PeriodicGaugeStatistics> | ||||||
|  |   static inline void writeConfiguration(Lattice<vLorentzColourMatrixD > &Umu, | ||||||
|  | 					std::string file,  | ||||||
|  | 					std::string ens_label = std::string("DWF")) | ||||||
|  |   { | ||||||
|  |     writeConfiguration(Umu,file,0,1,ens_label); | ||||||
|  |   } | ||||||
|  |   template<class GaugeStats=PeriodicGaugeStatistics> | ||||||
|  |   static inline void writeConfiguration(Lattice<vLorentzColourMatrixD > &Umu, | ||||||
| 					std::string file,  | 					std::string file,  | ||||||
| 					int two_row, | 					int two_row, | ||||||
| 					int bits32) | 					int bits32, | ||||||
|  | 					std::string ens_label = std::string("DWF")) | ||||||
|   { |   { | ||||||
|     typedef Lattice<iLorentzColourMatrix<vsimd> > GaugeField; |     typedef vLorentzColourMatrixD vobj; | ||||||
|  |  | ||||||
|     typedef iLorentzColourMatrix<vsimd> vobj; |  | ||||||
|     typedef typename vobj::scalar_object sobj; |     typedef typename vobj::scalar_object sobj; | ||||||
|  |  | ||||||
|     FieldMetaData header; |     FieldMetaData header; | ||||||
| @@ -219,8 +230,8 @@ public: | |||||||
|     // Following should become arguments |     // Following should become arguments | ||||||
|     /////////////////////////////////////////// |     /////////////////////////////////////////// | ||||||
|     header.sequence_number = 1; |     header.sequence_number = 1; | ||||||
|     header.ensemble_id     = "UKQCD"; |     header.ensemble_id     = std::string("UKQCD"); | ||||||
|     header.ensemble_label  = "DWF"; |     header.ensemble_label  = ens_label; | ||||||
|  |  | ||||||
|     typedef LorentzColourMatrixD fobj3D; |     typedef LorentzColourMatrixD fobj3D; | ||||||
|     typedef LorentzColour2x3D    fobj2D; |     typedef LorentzColour2x3D    fobj2D; | ||||||
| @@ -229,28 +240,28 @@ public: | |||||||
|  |  | ||||||
|     GridMetaData(grid,header); |     GridMetaData(grid,header); | ||||||
|     assert(header.nd==4); |     assert(header.nd==4); | ||||||
|     GaugeStatistics(Umu,header); |     GaugeStats Stats; Stats(Umu,header); | ||||||
|     MachineCharacteristics(header); |     MachineCharacteristics(header); | ||||||
|  |  | ||||||
| 	uint64_t offset; |     uint64_t offset; | ||||||
|  |  | ||||||
|     // Sod it -- always write 3x3 double |     // Sod it -- always write 3x3 double | ||||||
|     header.floating_point = std::string("IEEE64BIG"); |     header.floating_point = std::string("IEEE64BIG"); | ||||||
|     header.data_type      = std::string("4D_SU3_GAUGE_3x3"); |     header.data_type      = std::string("4D_SU3_GAUGE_3x3"); | ||||||
|     GaugeSimpleUnmunger<fobj3D,sobj> munge; |     GaugeSimpleUnmunger<fobj3D,sobj> munge; | ||||||
| 	if ( grid->IsBoss() ) {  |     if ( grid->IsBoss() ) {  | ||||||
| 	  truncate(file); |       truncate(file); | ||||||
|     offset = writeHeader(header,file); |       offset = writeHeader(header,file); | ||||||
| 	} |     } | ||||||
| 	grid->Broadcast(0,(void *)&offset,sizeof(offset)); |     grid->Broadcast(0,(void *)&offset,sizeof(offset)); | ||||||
|  |  | ||||||
|     uint32_t nersc_csum,scidac_csuma,scidac_csumb; |     uint32_t nersc_csum,scidac_csuma,scidac_csumb; | ||||||
|     BinaryIO::writeLatticeObject<vobj,fobj3D>(Umu,file,munge,offset,header.floating_point, |     BinaryIO::writeLatticeObject<vobj,fobj3D>(Umu,file,munge,offset,header.floating_point, | ||||||
| 					      nersc_csum,scidac_csuma,scidac_csumb); | 					      nersc_csum,scidac_csuma,scidac_csumb); | ||||||
|     header.checksum = nersc_csum; |     header.checksum = nersc_csum; | ||||||
| 	if ( grid->IsBoss() ) {  |     if ( grid->IsBoss() ) {  | ||||||
|     writeHeader(header,file); |       writeHeader(header,file); | ||||||
| 	} |     } | ||||||
|  |  | ||||||
|     std::cout<<GridLogMessage <<"Written NERSC Configuration on "<< file << " checksum " |     std::cout<<GridLogMessage <<"Written NERSC Configuration on "<< file << " checksum " | ||||||
| 	     <<std::hex<<header.checksum | 	     <<std::hex<<header.checksum | ||||||
|   | |||||||
| @@ -154,7 +154,7 @@ public: | |||||||
|     grid->Barrier(); timer.Stop(); |     grid->Barrier(); timer.Stop(); | ||||||
|     std::cout << Grid::GridLogMessage << "OpenQcdIO::readConfiguration: redistribute overhead " << timer.Elapsed() << std::endl; |     std::cout << Grid::GridLogMessage << "OpenQcdIO::readConfiguration: redistribute overhead " << timer.Elapsed() << std::endl; | ||||||
|  |  | ||||||
|     GaugeStatistics(Umu, clone); |     PeriodicGaugeStatistics Stats; Stats(Umu, clone); | ||||||
|  |  | ||||||
|     RealD plaq_diff = fabs(clone.plaquette - header.plaquette); |     RealD plaq_diff = fabs(clone.plaquette - header.plaquette); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -208,7 +208,7 @@ public: | |||||||
|  |  | ||||||
|     FieldMetaData clone(header); |     FieldMetaData clone(header); | ||||||
|  |  | ||||||
|     GaugeStatistics(Umu, clone); |     PeriodicGaugeStatistics Stats; Stats(Umu, clone); | ||||||
|  |  | ||||||
|     RealD plaq_diff = fabs(clone.plaquette - header.plaquette); |     RealD plaq_diff = fabs(clone.plaquette - header.plaquette); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -63,6 +63,7 @@ static constexpr int Ngp=2; // gparity index range | |||||||
| #define ColourIndex  (2) | #define ColourIndex  (2) | ||||||
| #define SpinIndex    (1) | #define SpinIndex    (1) | ||||||
| #define LorentzIndex (0) | #define LorentzIndex (0) | ||||||
|  | #define GparityFlavourIndex (0) | ||||||
|  |  | ||||||
| // Also should make these a named enum type | // Also should make these a named enum type | ||||||
| static constexpr int DaggerNo=0; | static constexpr int DaggerNo=0; | ||||||
| @@ -80,6 +81,15 @@ template<typename T> struct isSpinor { | |||||||
| template <typename T> using IfSpinor    = Invoke<std::enable_if< isSpinor<T>::value,int> > ; | template <typename T> using IfSpinor    = Invoke<std::enable_if< isSpinor<T>::value,int> > ; | ||||||
| template <typename T> using IfNotSpinor = Invoke<std::enable_if<!isSpinor<T>::value,int> > ; | template <typename T> using IfNotSpinor = Invoke<std::enable_if<!isSpinor<T>::value,int> > ; | ||||||
|  |  | ||||||
|  | const int CoarseIndex = 4; | ||||||
|  | template<typename T> struct isCoarsened { | ||||||
|  |    static constexpr bool value = (CoarseIndex<=T::TensorLevel); | ||||||
|  | }; | ||||||
|  | template <typename T> using IfCoarsened    = Invoke<std::enable_if< isCoarsened<T>::value,int> > ; | ||||||
|  | template <typename T> using IfNotCoarsened = Invoke<std::enable_if<!isCoarsened<T>::value,int> > ; | ||||||
|  |  | ||||||
|  | const int GparityFlavourTensorIndex = 3; //TensorLevel counts from the bottom! | ||||||
|  |  | ||||||
| // ChrisK very keen to add extra space for Gparity doubling. | // ChrisK very keen to add extra space for Gparity doubling. | ||||||
| // | // | ||||||
| // Also add domain wall index, in a way where Wilson operator  | // Also add domain wall index, in a way where Wilson operator  | ||||||
| @@ -94,6 +104,7 @@ template<typename vtype> using iSpinMatrix                = iScalar<iMatrix<iSca | |||||||
| template<typename vtype> using iColourMatrix              = iScalar<iScalar<iMatrix<vtype, Nc> > > ; | template<typename vtype> using iColourMatrix              = iScalar<iScalar<iMatrix<vtype, Nc> > > ; | ||||||
| template<typename vtype> using iSpinColourMatrix          = iScalar<iMatrix<iMatrix<vtype, Nc>, Ns> >; | template<typename vtype> using iSpinColourMatrix          = iScalar<iMatrix<iMatrix<vtype, Nc>, Ns> >; | ||||||
| template<typename vtype> using iLorentzColourMatrix       = iVector<iScalar<iMatrix<vtype, Nc> >, Nd > ; | template<typename vtype> using iLorentzColourMatrix       = iVector<iScalar<iMatrix<vtype, Nc> >, Nd > ; | ||||||
|  | template<typename vtype> using iLorentzVector             = iVector<iScalar<iScalar<vtype> >, Nd > ; | ||||||
| template<typename vtype> using iDoubleStoredColourMatrix  = iVector<iScalar<iMatrix<vtype, Nc> >, Nds > ; | template<typename vtype> using iDoubleStoredColourMatrix  = iVector<iScalar<iMatrix<vtype, Nc> >, Nds > ; | ||||||
| template<typename vtype> using iSpinVector                = iScalar<iVector<iScalar<vtype>, Ns> >; | template<typename vtype> using iSpinVector                = iScalar<iVector<iScalar<vtype>, Ns> >; | ||||||
| template<typename vtype> using iColourVector              = iScalar<iScalar<iVector<vtype, Nc> > >; | template<typename vtype> using iColourVector              = iScalar<iScalar<iVector<vtype, Nc> > >; | ||||||
| @@ -103,8 +114,10 @@ template<typename vtype> using iHalfSpinColourVector      = iScalar<iVector<iVec | |||||||
|     template<typename vtype> using iSpinColourSpinColourMatrix  = iScalar<iMatrix<iMatrix<iMatrix<iMatrix<vtype, Nc>, Ns>, Nc>, Ns> >; |     template<typename vtype> using iSpinColourSpinColourMatrix  = iScalar<iMatrix<iMatrix<iMatrix<iMatrix<vtype, Nc>, Ns>, Nc>, Ns> >; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | template<typename vtype> using iGparityFlavourVector                = iVector<iScalar<iScalar<vtype> >, Ngp>; | ||||||
| template<typename vtype> using iGparitySpinColourVector       = iVector<iVector<iVector<vtype, Nc>, Ns>, Ngp >; | template<typename vtype> using iGparitySpinColourVector       = iVector<iVector<iVector<vtype, Nc>, Ns>, Ngp >; | ||||||
| template<typename vtype> using iGparityHalfSpinColourVector   = iVector<iVector<iVector<vtype, Nc>, Nhs>, Ngp >; | template<typename vtype> using iGparityHalfSpinColourVector   = iVector<iVector<iVector<vtype, Nc>, Nhs>, Ngp >; | ||||||
|  | template<typename vtype> using iGparityFlavourMatrix = iMatrix<iScalar<iScalar<vtype> >, Ngp>; | ||||||
|  |  | ||||||
| // Spin matrix | // Spin matrix | ||||||
| typedef iSpinMatrix<Complex  >          SpinMatrix; | typedef iSpinMatrix<Complex  >          SpinMatrix; | ||||||
| @@ -151,7 +164,16 @@ typedef iSpinColourSpinColourMatrix<vComplex >    vSpinColourSpinColourMatrix; | |||||||
| typedef iSpinColourSpinColourMatrix<vComplexF>    vSpinColourSpinColourMatrixF; | typedef iSpinColourSpinColourMatrix<vComplexF>    vSpinColourSpinColourMatrixF; | ||||||
| typedef iSpinColourSpinColourMatrix<vComplexD>    vSpinColourSpinColourMatrixD; | typedef iSpinColourSpinColourMatrix<vComplexD>    vSpinColourSpinColourMatrixD; | ||||||
|  |  | ||||||
| // LorentzColour | // LorentzVector | ||||||
|  | typedef iLorentzVector<Complex  > LorentzVector; | ||||||
|  | typedef iLorentzVector<ComplexF > LorentzVectorF; | ||||||
|  | typedef iLorentzVector<ComplexD > LorentzVectorD; | ||||||
|  |  | ||||||
|  | typedef iLorentzVector<vComplex > vLorentzVector; | ||||||
|  | typedef iLorentzVector<vComplexF> vLorentzVectorF; | ||||||
|  | typedef iLorentzVector<vComplexD> vLorentzVectorD; | ||||||
|  |  | ||||||
|  | // LorentzColourMatrix | ||||||
| typedef iLorentzColourMatrix<Complex  > LorentzColourMatrix; | typedef iLorentzColourMatrix<Complex  > LorentzColourMatrix; | ||||||
| typedef iLorentzColourMatrix<ComplexF > LorentzColourMatrixF; | typedef iLorentzColourMatrix<ComplexF > LorentzColourMatrixF; | ||||||
| typedef iLorentzColourMatrix<ComplexD > LorentzColourMatrixD; | typedef iLorentzColourMatrix<ComplexD > LorentzColourMatrixD; | ||||||
| @@ -169,6 +191,16 @@ typedef iDoubleStoredColourMatrix<vComplex > vDoubleStoredColourMatrix; | |||||||
| typedef iDoubleStoredColourMatrix<vComplexF> vDoubleStoredColourMatrixF; | typedef iDoubleStoredColourMatrix<vComplexF> vDoubleStoredColourMatrixF; | ||||||
| typedef iDoubleStoredColourMatrix<vComplexD> vDoubleStoredColourMatrixD; | typedef iDoubleStoredColourMatrix<vComplexD> vDoubleStoredColourMatrixD; | ||||||
|  |  | ||||||
|  | //G-parity flavour matrix | ||||||
|  | typedef iGparityFlavourMatrix<Complex> GparityFlavourMatrix; | ||||||
|  | typedef iGparityFlavourMatrix<ComplexF> GparityFlavourMatrixF; | ||||||
|  | typedef iGparityFlavourMatrix<ComplexD> GparityFlavourMatrixD; | ||||||
|  |  | ||||||
|  | typedef iGparityFlavourMatrix<vComplex> vGparityFlavourMatrix; | ||||||
|  | typedef iGparityFlavourMatrix<vComplexF> vGparityFlavourMatrixF; | ||||||
|  | typedef iGparityFlavourMatrix<vComplexD> vGparityFlavourMatrixD; | ||||||
|  |  | ||||||
|  |  | ||||||
| // Spin vector | // Spin vector | ||||||
| typedef iSpinVector<Complex >           SpinVector; | typedef iSpinVector<Complex >           SpinVector; | ||||||
| typedef iSpinVector<ComplexF>           SpinVectorF; | typedef iSpinVector<ComplexF>           SpinVectorF; | ||||||
| @@ -213,6 +245,16 @@ typedef iHalfSpinColourVector<ComplexD> HalfSpinColourVectorD; | |||||||
| typedef iHalfSpinColourVector<vComplex > vHalfSpinColourVector; | typedef iHalfSpinColourVector<vComplex > vHalfSpinColourVector; | ||||||
| typedef iHalfSpinColourVector<vComplexF> vHalfSpinColourVectorF; | typedef iHalfSpinColourVector<vComplexF> vHalfSpinColourVectorF; | ||||||
| typedef iHalfSpinColourVector<vComplexD> vHalfSpinColourVectorD; | typedef iHalfSpinColourVector<vComplexD> vHalfSpinColourVectorD; | ||||||
|  |  | ||||||
|  | //G-parity flavour vector | ||||||
|  | typedef iGparityFlavourVector<Complex >         GparityFlavourVector; | ||||||
|  | typedef iGparityFlavourVector<ComplexF>         GparityFlavourVectorF; | ||||||
|  | typedef iGparityFlavourVector<ComplexD>         GparityFlavourVectorD; | ||||||
|  |  | ||||||
|  | typedef iGparityFlavourVector<vComplex >         vGparityFlavourVector; | ||||||
|  | typedef iGparityFlavourVector<vComplexF>         vGparityFlavourVectorF; | ||||||
|  | typedef iGparityFlavourVector<vComplexD>         vGparityFlavourVectorD; | ||||||
|  |  | ||||||
|      |      | ||||||
| // singlets | // singlets | ||||||
| typedef iSinglet<Complex >         TComplex;     // FIXME This is painful. Tensor singlet complex type. | typedef iSinglet<Complex >         TComplex;     // FIXME This is painful. Tensor singlet complex type. | ||||||
| @@ -256,6 +298,10 @@ typedef Lattice<vLorentzColourMatrix>  LatticeLorentzColourMatrix; | |||||||
| typedef Lattice<vLorentzColourMatrixF> LatticeLorentzColourMatrixF; | typedef Lattice<vLorentzColourMatrixF> LatticeLorentzColourMatrixF; | ||||||
| typedef Lattice<vLorentzColourMatrixD> LatticeLorentzColourMatrixD; | typedef Lattice<vLorentzColourMatrixD> LatticeLorentzColourMatrixD; | ||||||
|  |  | ||||||
|  | typedef Lattice<vLorentzVector>  LatticeLorentzVector; | ||||||
|  | typedef Lattice<vLorentzVectorF> LatticeLorentzVectorF; | ||||||
|  | typedef Lattice<vLorentzVectorD> LatticeLorentzVectorD; | ||||||
|  |  | ||||||
| // DoubleStored gauge field | // DoubleStored gauge field | ||||||
| typedef Lattice<vDoubleStoredColourMatrix>  LatticeDoubleStoredColourMatrix; | typedef Lattice<vDoubleStoredColourMatrix>  LatticeDoubleStoredColourMatrix; | ||||||
| typedef Lattice<vDoubleStoredColourMatrixF> LatticeDoubleStoredColourMatrixF; | typedef Lattice<vDoubleStoredColourMatrixF> LatticeDoubleStoredColourMatrixF; | ||||||
|   | |||||||
| @@ -30,8 +30,7 @@ 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 */ | ||||||
| #ifndef GRID_QCD_ACTION_H | #pragma once | ||||||
| #define GRID_QCD_ACTION_H |  | ||||||
|  |  | ||||||
| //////////////////////////////////////////// | //////////////////////////////////////////// | ||||||
| // Abstract base interface | // Abstract base interface | ||||||
| @@ -51,4 +50,4 @@ NAMESPACE_CHECK(Fermion); | |||||||
| #include <Grid/qcd/action/pseudofermion/PseudoFermion.h> | #include <Grid/qcd/action/pseudofermion/PseudoFermion.h> | ||||||
| NAMESPACE_CHECK(PseudoFermion); | NAMESPACE_CHECK(PseudoFermion); | ||||||
|  |  | ||||||
| #endif |  | ||||||
|   | |||||||
| @@ -40,8 +40,31 @@ class Action | |||||||
|  |  | ||||||
| public: | public: | ||||||
|   bool is_smeared = false; |   bool is_smeared = false; | ||||||
|  |   RealD deriv_norm_sum; | ||||||
|  |   RealD deriv_max_sum; | ||||||
|  |   int   deriv_num; | ||||||
|  |   RealD deriv_us; | ||||||
|  |   RealD S_us; | ||||||
|  |   RealD refresh_us; | ||||||
|  |   void  reset_timer(void)        { | ||||||
|  |     deriv_us = S_us = refresh_us = 0.0; | ||||||
|  |     deriv_num=0; | ||||||
|  |     deriv_norm_sum = deriv_max_sum=0.0; | ||||||
|  |   } | ||||||
|  |   void  deriv_log(RealD nrm, RealD max) { deriv_max_sum+=max; deriv_norm_sum+=nrm; deriv_num++;} | ||||||
|  |   RealD deriv_max_average(void)         { return deriv_max_sum/deriv_num; }; | ||||||
|  |   RealD deriv_norm_average(void)        { return deriv_norm_sum/deriv_num; }; | ||||||
|  |   RealD deriv_timer(void)        { return deriv_us; }; | ||||||
|  |   RealD S_timer(void)            { return deriv_us; }; | ||||||
|  |   RealD refresh_timer(void)      { return deriv_us; }; | ||||||
|  |   void deriv_timer_start(void)   { deriv_us-=usecond(); } | ||||||
|  |   void deriv_timer_stop(void)    { deriv_us+=usecond(); } | ||||||
|  |   void refresh_timer_start(void) { refresh_us-=usecond(); } | ||||||
|  |   void refresh_timer_stop(void)  { refresh_us+=usecond(); } | ||||||
|  |   void S_timer_start(void)       { S_us-=usecond(); } | ||||||
|  |   void S_timer_stop(void)        { S_us+=usecond(); } | ||||||
|   // Heatbath? |   // Heatbath? | ||||||
|   virtual void refresh(const GaugeField& U, GridParallelRNG& pRNG) = 0; // refresh pseudofermions |   virtual void refresh(const GaugeField& U, GridSerialRNG &sRNG, GridParallelRNG& pRNG) = 0; // refresh pseudofermions | ||||||
|   virtual RealD S(const GaugeField& U) = 0;                             // evaluate the action |   virtual RealD S(const GaugeField& U) = 0;                             // evaluate the action | ||||||
|   virtual void deriv(const GaugeField& U, GaugeField& dSdU) = 0;        // evaluate the action derivative |   virtual void deriv(const GaugeField& U, GaugeField& dSdU) = 0;        // evaluate the action derivative | ||||||
|   virtual std::string action_name()    = 0;                             // return the action name |   virtual std::string action_name()    = 0;                             // return the action name | ||||||
|   | |||||||
| @@ -58,6 +58,8 @@ NAMESPACE_CHECK(Scalar); | |||||||
| //////////////////////////////////////////// | //////////////////////////////////////////// | ||||||
| // Utility functions | // Utility functions | ||||||
| //////////////////////////////////////////// | //////////////////////////////////////////// | ||||||
|  | #include <Grid/qcd/action/domains/Domains.h> | ||||||
|  |  | ||||||
| #include <Grid/qcd/utils/Metric.h> | #include <Grid/qcd/utils/Metric.h> | ||||||
| NAMESPACE_CHECK(Metric); | NAMESPACE_CHECK(Metric); | ||||||
| #include <Grid/qcd/utils/CovariantLaplacian.h> | #include <Grid/qcd/utils/CovariantLaplacian.h> | ||||||
|   | |||||||
| @@ -36,28 +36,34 @@ NAMESPACE_BEGIN(Grid); | |||||||
|  |  | ||||||
| // These can move into a params header and be given MacroMagic serialisation | // These can move into a params header and be given MacroMagic serialisation | ||||||
| struct GparityWilsonImplParams { | struct GparityWilsonImplParams { | ||||||
|   Coordinate twists; |   Coordinate twists; //Here the first Nd-1 directions are treated as "spatial", and a twist value of 1 indicates G-parity BCs in that direction.  | ||||||
|   GparityWilsonImplParams() : twists(Nd, 0) {}; |                      //mu=Nd-1 is assumed to be the time direction and a twist value of 1 indicates antiperiodic BCs | ||||||
|  |   bool locally_periodic; | ||||||
|  |   GparityWilsonImplParams() : twists(Nd, 0), locally_periodic(false) {}; | ||||||
| }; | }; | ||||||
|    |    | ||||||
| struct WilsonImplParams { | struct WilsonImplParams { | ||||||
|   bool overlapCommsCompute; |   bool overlapCommsCompute; | ||||||
|  |   bool locally_periodic; | ||||||
|   AcceleratorVector<Real,Nd> twist_n_2pi_L; |   AcceleratorVector<Real,Nd> twist_n_2pi_L; | ||||||
|   AcceleratorVector<Complex,Nd> boundary_phases; |   AcceleratorVector<Complex,Nd> boundary_phases; | ||||||
|   WilsonImplParams()  { |   WilsonImplParams()  { | ||||||
|     boundary_phases.resize(Nd, 1.0); |     boundary_phases.resize(Nd, 1.0); | ||||||
|       twist_n_2pi_L.resize(Nd, 0.0); |       twist_n_2pi_L.resize(Nd, 0.0); | ||||||
|  |       locally_periodic = false; | ||||||
|   }; |   }; | ||||||
|   WilsonImplParams(const AcceleratorVector<Complex,Nd> phi) : boundary_phases(phi), overlapCommsCompute(false) { |   WilsonImplParams(const AcceleratorVector<Complex,Nd> phi) : boundary_phases(phi), overlapCommsCompute(false) { | ||||||
|     twist_n_2pi_L.resize(Nd, 0.0); |     twist_n_2pi_L.resize(Nd, 0.0); | ||||||
|  |     locally_periodic = false; | ||||||
|   } |   } | ||||||
| }; | }; | ||||||
|  |  | ||||||
| struct StaggeredImplParams { | struct StaggeredImplParams { | ||||||
|   StaggeredImplParams()  {}; |   bool locally_periodic; | ||||||
|  |   StaggeredImplParams() : locally_periodic(false) {}; | ||||||
| }; | }; | ||||||
|    |    | ||||||
|   struct OneFlavourRationalParams : Serializable { | struct OneFlavourRationalParams : Serializable { | ||||||
|     GRID_SERIALIZABLE_CLASS_MEMBERS(OneFlavourRationalParams,  |     GRID_SERIALIZABLE_CLASS_MEMBERS(OneFlavourRationalParams,  | ||||||
| 				    RealD, lo,  | 				    RealD, lo,  | ||||||
| 				    RealD, hi,  | 				    RealD, hi,  | ||||||
| @@ -85,6 +91,50 @@ struct StaggeredImplParams { | |||||||
|         precision(_precision), |         precision(_precision), | ||||||
|         BoundsCheckFreq(_BoundsCheckFreq){}; |         BoundsCheckFreq(_BoundsCheckFreq){}; | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   /*Action parameters for the generalized rational action | ||||||
|  |     The approximation is for (M^dag M)^{1/inv_pow} | ||||||
|  |     where inv_pow is the denominator of the fractional power. | ||||||
|  |     Default inv_pow=2 for square root, making this equivalent to  | ||||||
|  |     the OneFlavourRational action | ||||||
|  |   */ | ||||||
|  |     struct RationalActionParams : Serializable { | ||||||
|  |     GRID_SERIALIZABLE_CLASS_MEMBERS(RationalActionParams,  | ||||||
|  | 				    int, inv_pow,  | ||||||
|  | 				    RealD, lo, //low eigenvalue bound of rational approx | ||||||
|  | 				    RealD, hi, //high eigenvalue bound of rational approx | ||||||
|  | 				    int,   MaxIter,  //maximum iterations in msCG | ||||||
|  | 				    RealD, action_tolerance,  //msCG tolerance in action evaluation | ||||||
|  | 				    int,   action_degree, //rational approx tolerance in action evaluation | ||||||
|  | 				    RealD, md_tolerance,  //msCG tolerance in MD integration | ||||||
|  | 				    int,   md_degree, //rational approx tolerance in MD integration | ||||||
|  | 				    int,   precision, //precision of floating point arithmetic | ||||||
|  | 				    int,   BoundsCheckFreq); //frequency the approximation is tested (with Metropolis degree/tolerance); 0 disables the check | ||||||
|  |   // constructor  | ||||||
|  |   RationalActionParams(int _inv_pow = 2, | ||||||
|  | 		       RealD _lo      = 0.0,  | ||||||
|  | 		       RealD _hi      = 1.0,  | ||||||
|  | 		       int _maxit     = 1000, | ||||||
|  | 		       RealD _action_tolerance      = 1.0e-8,  | ||||||
|  | 		       int _action_degree    = 10, | ||||||
|  | 		       RealD _md_tolerance      = 1.0e-8,  | ||||||
|  | 		       int _md_degree    = 10, | ||||||
|  | 		       int _precision = 64, | ||||||
|  | 		       int _BoundsCheckFreq=20) | ||||||
|  |     : inv_pow(_inv_pow),  | ||||||
|  |       lo(_lo), | ||||||
|  |       hi(_hi), | ||||||
|  |       MaxIter(_maxit), | ||||||
|  |       action_tolerance(_action_tolerance), | ||||||
|  |       action_degree(_action_degree), | ||||||
|  |       md_tolerance(_md_tolerance), | ||||||
|  |       md_degree(_md_degree), | ||||||
|  |       precision(_precision), | ||||||
|  |       BoundsCheckFreq(_BoundsCheckFreq){}; | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |  | ||||||
|    |    | ||||||
| NAMESPACE_END(Grid); | NAMESPACE_END(Grid); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -2,14 +2,12 @@ | |||||||
| 
 | 
 | ||||||
| Grid physics library, www.github.com/paboyle/Grid | Grid physics library, www.github.com/paboyle/Grid | ||||||
| 
 | 
 | ||||||
| Source file: ./lib/qcd/action/fermion/WilsonKernels.cc | Source file: ./lib/qcd/hmc/DDHMC.h | ||||||
| 
 | 
 | ||||||
| Copyright (C) 2015, 2020 | Copyright (C) 2021 | ||||||
| 
 | 
 | ||||||
| Author: Peter Boyle <paboyle@ph.ed.ac.uk> | Author: Peter Boyle <paboyle@ph.ed.ac.uk> | ||||||
| Author: Peter Boyle <peterboyle@Peters-MacBook-Pro-2.local> | Author: Christopher Kelly | ||||||
| Author: paboyle <paboyle@ph.ed.ac.uk> |  | ||||||
| Author: Nils Meyer <nils.meyer@ur.de> Regensburg University |  | ||||||
| 
 | 
 | ||||||
| This program is free software; you can redistribute it and/or modify | 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 | it under the terms of the GNU General Public License as published by | ||||||
| @@ -28,24 +26,27 @@ with this program; if not, write to the Free Software Foundation, Inc., | |||||||
| See the full license in the file "LICENSE" in the top level distribution | See the full license in the file "LICENSE" in the top level distribution | ||||||
| directory | directory | ||||||
| *************************************************************************************/ | *************************************************************************************/ | ||||||
| /*  END LEGAL */ | 			   /*  END LEGAL */ | ||||||
| #include <Grid/qcd/action/fermion/FermionCore.h> |  | ||||||
| #include <Grid/qcd/action/fermion/implementation/WilsonKernelsImplementation.h> |  | ||||||
| #include <Grid/qcd/action/fermion/implementation/WilsonKernelsHandImplementation.h> |  | ||||||
| 
 |  | ||||||
| #ifndef AVX512 |  | ||||||
| #ifndef QPX |  | ||||||
| #ifndef A64FX |  | ||||||
| #ifndef A64FXFIXEDSIZE |  | ||||||
| #include <Grid/qcd/action/fermion/implementation/WilsonKernelsAsmImplementation.h> |  | ||||||
| #endif |  | ||||||
| #endif |  | ||||||
| #endif |  | ||||||
| #endif |  | ||||||
| 
 | 
 | ||||||
| NAMESPACE_BEGIN(Grid); | NAMESPACE_BEGIN(Grid); | ||||||
|  | ////////////////////////////////////////////////////
 | ||||||
|  | // DDHMC filter with sub-block size B[mu]
 | ||||||
|  | ////////////////////////////////////////////////////
 | ||||||
| 
 | 
 | ||||||
| #include "impl.h" | template<typename MomentaField> | ||||||
| template class WilsonKernels<IMPLEMENTATION>; | struct DDHMCFilter: public MomentumFilterBase<MomentaField> | ||||||
|  | { | ||||||
|  |   Coordinate Block; | ||||||
|  |   int Width; | ||||||
|  |    | ||||||
|  |   DDHMCFilter(const Coordinate &_Block): Block(_Block) {} | ||||||
|  | 
 | ||||||
|  |   void applyFilter(MomentaField &P) const override | ||||||
|  |   { | ||||||
|  |     DomainDecomposition Domains(Block); | ||||||
|  |     Domains.ProjectDDHMC(P); | ||||||
|  |   } | ||||||
|  | }; | ||||||
| 
 | 
 | ||||||
| NAMESPACE_END(Grid); | NAMESPACE_END(Grid); | ||||||
|  | 
 | ||||||
							
								
								
									
										98
									
								
								Grid/qcd/action/domains/DirichletFilter.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								Grid/qcd/action/domains/DirichletFilter.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,98 @@ | |||||||
|  | /************************************************************************************* | ||||||
|  |  | ||||||
|  | Grid physics library, www.github.com/paboyle/Grid | ||||||
|  |  | ||||||
|  | Source file: ./lib/qcd/action/momentum/DirichletFilter.h | ||||||
|  |  | ||||||
|  | Copyright (C) 2021 | ||||||
|  |  | ||||||
|  | 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 */ | ||||||
|  |  | ||||||
|  | //////////////////////////////////////////////////// | ||||||
|  | // Dirichlet filter with sub-block size B[mu] | ||||||
|  | //////////////////////////////////////////////////// | ||||||
|  | #pragma once  | ||||||
|  |  | ||||||
|  | #include <Grid/qcd/action/domains/DomainDecomposition.h> | ||||||
|  |  | ||||||
|  | NAMESPACE_BEGIN(Grid); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | template<typename MomentaField> | ||||||
|  | struct DirichletFilter: public MomentumFilterBase<MomentaField> | ||||||
|  | { | ||||||
|  |   Coordinate Block; | ||||||
|  |    | ||||||
|  |   DirichletFilter(const Coordinate &_Block): Block(_Block) {} | ||||||
|  |  | ||||||
|  |   // Edge detect using domain projectors | ||||||
|  |   void applyFilter (MomentaField &U) const override | ||||||
|  |   { | ||||||
|  |     DomainDecomposition Domains(Block); | ||||||
|  |     GridBase *grid = U.Grid(); | ||||||
|  |     LatticeInteger  coor(grid); | ||||||
|  |     LatticeInteger  face(grid); | ||||||
|  |     LatticeInteger  one(grid);   one = 1; | ||||||
|  |     LatticeInteger  zero(grid); zero = 0; | ||||||
|  |     LatticeInteger  omega(grid); | ||||||
|  |     LatticeInteger  omegabar(grid); | ||||||
|  |     LatticeInteger  tmp(grid); | ||||||
|  |  | ||||||
|  |     omega=one;    Domains.ProjectDomain(omega,0); | ||||||
|  |     omegabar=one; Domains.ProjectDomain(omegabar,1); | ||||||
|  |      | ||||||
|  |     LatticeInteger nface(grid); nface=Zero(); | ||||||
|  |      | ||||||
|  |     MomentaField projected(grid); projected=Zero(); | ||||||
|  |     typedef decltype(PeekIndex<LorentzIndex>(U,0)) MomentaLinkField; | ||||||
|  |     MomentaLinkField  Umu(grid); | ||||||
|  |     MomentaLinkField   zz(grid); zz=Zero(); | ||||||
|  |  | ||||||
|  |     int dims = grid->Nd(); | ||||||
|  |     Coordinate Global=grid->GlobalDimensions(); | ||||||
|  |     assert(dims==Nd); | ||||||
|  |  | ||||||
|  |     for(int mu=0;mu<Nd;mu++){ | ||||||
|  |  | ||||||
|  |       if ( Block[mu]!=0 ) { | ||||||
|  |  | ||||||
|  | 	Umu = PeekIndex<LorentzIndex>(U,mu); | ||||||
|  |  | ||||||
|  | 	// Upper face  | ||||||
|  |  	tmp = Cshift(omegabar,mu,1); | ||||||
|  | 	tmp = tmp + omega; | ||||||
|  | 	face = where(tmp == Integer(2),one,zero ); | ||||||
|  |  | ||||||
|  |  	tmp = Cshift(omega,mu,1); | ||||||
|  | 	tmp = tmp + omegabar; | ||||||
|  | 	face = where(tmp == Integer(2),one,face ); | ||||||
|  |  | ||||||
|  | 	Umu = where(face,zz,Umu); | ||||||
|  |  | ||||||
|  | 	PokeIndex<LorentzIndex>(U, Umu, mu); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |    | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | NAMESPACE_END(Grid); | ||||||
							
								
								
									
										187
									
								
								Grid/qcd/action/domains/DomainDecomposition.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										187
									
								
								Grid/qcd/action/domains/DomainDecomposition.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,187 @@ | |||||||
|  | /************************************************************************************* | ||||||
|  |  | ||||||
|  | Grid physics library, www.github.com/paboyle/Grid | ||||||
|  |  | ||||||
|  | Source file: ./lib/qcd/action/domains/DomainDecomposition.h | ||||||
|  |  | ||||||
|  | Copyright (C) 2021 | ||||||
|  |  | ||||||
|  | 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 */ | ||||||
|  |  | ||||||
|  | //////////////////////////////////////////////////// | ||||||
|  | // Dirichlet filter with sub-block size B[mu] | ||||||
|  | //////////////////////////////////////////////////// | ||||||
|  | #pragma once  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | NAMESPACE_BEGIN(Grid); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | struct DomainDecomposition | ||||||
|  | { | ||||||
|  |   Coordinate Block; | ||||||
|  |   static constexpr RealD factor = 0.6; | ||||||
|  |  | ||||||
|  |   DomainDecomposition(const Coordinate &_Block): Block(_Block){ assert(Block.size()==Nd);}; | ||||||
|  |    | ||||||
|  |   template<class Field> | ||||||
|  |   void ProjectDomain(Field &f,Integer domain) | ||||||
|  |   { | ||||||
|  |     GridBase *grid = f.Grid(); | ||||||
|  |     int dims = grid->Nd(); | ||||||
|  |     int isDWF= (dims==Nd+1); | ||||||
|  |     assert((dims==Nd)||(dims==Nd+1)); | ||||||
|  |  | ||||||
|  |     Field   zz(grid);  zz = Zero(); | ||||||
|  |     LatticeInteger coor(grid); | ||||||
|  |     LatticeInteger domaincoor(grid); | ||||||
|  |     LatticeInteger mask(grid); mask = Integer(1); | ||||||
|  |     LatticeInteger zi(grid);     zi = Integer(0); | ||||||
|  |     for(int d=0;d<Nd;d++){ | ||||||
|  |       Integer B= Block[d]; | ||||||
|  |       if ( B ) { | ||||||
|  | 	LatticeCoordinate(coor,d+isDWF); | ||||||
|  | 	domaincoor = mod(coor,B); | ||||||
|  | 	mask = where(domaincoor==Integer(0),zi,mask); | ||||||
|  | 	mask = where(domaincoor==Integer(B-1),zi,mask); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     if ( !domain ) | ||||||
|  |       f = where(mask==Integer(1),f,zz); | ||||||
|  |     else  | ||||||
|  |       f = where(mask==Integer(0),f,zz); | ||||||
|  |   }; | ||||||
|  |   template<class GaugeField> | ||||||
|  |   void ProjectDDHMC(GaugeField &U) | ||||||
|  |   { | ||||||
|  |     GridBase *grid = U.Grid(); | ||||||
|  |     Coordinate Global=grid->GlobalDimensions(); | ||||||
|  |     GaugeField zzz(grid); zzz = Zero(); | ||||||
|  |     LatticeInteger coor(grid);  | ||||||
|  |  | ||||||
|  |     GaugeField Uorg(grid); Uorg = U; | ||||||
|  |      | ||||||
|  |     auto zzz_mu = PeekIndex<LorentzIndex>(zzz,0); | ||||||
|  |     //////////////////////////////////////////////////// | ||||||
|  |     // Zero BDY layers | ||||||
|  |     //////////////////////////////////////////////////// | ||||||
|  |     for(int mu=0;mu<Nd;mu++) { | ||||||
|  |       Integer B1 = Block[mu]; | ||||||
|  |       if ( B1 && (B1 <= Global[mu]) ) { | ||||||
|  | 	LatticeCoordinate(coor,mu); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 	//////////////////////////////// | ||||||
|  | 	// OmegaBar - zero all links contained in slice B-1,0 and | ||||||
|  | 	// mu links connecting to Omega | ||||||
|  | 	//////////////////////////////// | ||||||
|  |  | ||||||
|  | 	U    = where(mod(coor,B1)==Integer(B1-1),zzz,U); | ||||||
|  | 	U    = where(mod(coor,B1)==Integer(0)   ,zzz,U);  | ||||||
|  |  | ||||||
|  | 	auto U_mu   = PeekIndex<LorentzIndex>(U,mu); | ||||||
|  | 	U_mu = where(mod(coor,B1)==Integer(B1-2),zzz_mu,U_mu);  | ||||||
|  | 	PokeIndex<LorentzIndex>(U, U_mu, mu); | ||||||
|  |  | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     | ||||||
|  |     //////////////////////////////////////////// | ||||||
|  |     // Omega interior slow the evolution | ||||||
|  |     // Tricky as we need to take the smallest of values imposed by each cut | ||||||
|  |     // Do them in order or largest to smallest and smallest writes last | ||||||
|  |     //////////////////////////////////////////// | ||||||
|  |     RealD f= factor; | ||||||
|  | #if 0     | ||||||
|  |     for(int mu=0;mu<Nd;mu++) { | ||||||
|  |       Integer B1 = Block[mu]; | ||||||
|  |       if ( B1 && (B1 <= Global[mu]) ) { | ||||||
|  |  | ||||||
|  | 	auto U_mu   = PeekIndex<LorentzIndex>(U,mu); | ||||||
|  | 	auto Uorg_mu= PeekIndex<LorentzIndex>(Uorg,mu); | ||||||
|  | 	// In the plane | ||||||
|  | 	U = where(mod(coor,B1)==Integer(B1-5),Uorg*f,U);  | ||||||
|  | 	U = where(mod(coor,B1)==Integer(4)   ,Uorg*f,U);  | ||||||
|  |  | ||||||
|  | 	// Perp links | ||||||
|  |        	U_mu = where(mod(coor,B1)==Integer(B1-6),Uorg_mu*f,U_mu); | ||||||
|  | 	U_mu = where(mod(coor,B1)==Integer(4)   ,Uorg_mu*f,U_mu); | ||||||
|  |  | ||||||
|  | 	PokeIndex<LorentzIndex>(U, U_mu, mu); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  | #endif | ||||||
|  |     for(int mu=0;mu<Nd;mu++) { | ||||||
|  |       Integer B1 = Block[mu]; | ||||||
|  |       if ( B1 && (B1 <= Global[mu]) ) { | ||||||
|  |  | ||||||
|  | 	auto U_mu   = PeekIndex<LorentzIndex>(U,mu); | ||||||
|  | 	auto Uorg_mu= PeekIndex<LorentzIndex>(Uorg,mu); | ||||||
|  | 	// In the plane | ||||||
|  | 	U = where(mod(coor,B1)==Integer(B1-4),Uorg*f*f,U);  | ||||||
|  | 	U = where(mod(coor,B1)==Integer(3)   ,Uorg*f*f,U);  | ||||||
|  |  | ||||||
|  | 	// Perp links | ||||||
|  |        	U_mu = where(mod(coor,B1)==Integer(B1-5),Uorg_mu*f*f,U_mu); | ||||||
|  | 	U_mu = where(mod(coor,B1)==Integer(3)   ,Uorg_mu*f*f,U_mu); | ||||||
|  |  | ||||||
|  | 	PokeIndex<LorentzIndex>(U, U_mu, mu); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     for(int mu=0;mu<Nd;mu++) { | ||||||
|  |       Integer B1 = Block[mu]; | ||||||
|  |       if ( B1 && (B1 <= Global[mu]) ) { | ||||||
|  |  | ||||||
|  | 	auto U_mu   = PeekIndex<LorentzIndex>(U,mu); | ||||||
|  | 	auto Uorg_mu= PeekIndex<LorentzIndex>(Uorg,mu); | ||||||
|  | 	// In the plane | ||||||
|  | 	U = where(mod(coor,B1)==Integer(B1-3),Uorg*f*f*f,U);  | ||||||
|  | 	U = where(mod(coor,B1)==Integer(2)   ,Uorg*f*f*f,U);  | ||||||
|  |  | ||||||
|  | 	// Perp links | ||||||
|  |        	U_mu = where(mod(coor,B1)==Integer(B1-4),Uorg_mu*f*f*f,U_mu); | ||||||
|  | 	U_mu = where(mod(coor,B1)==Integer(2)   ,Uorg_mu*f*f*f,U_mu); | ||||||
|  |  | ||||||
|  | 	PokeIndex<LorentzIndex>(U, U_mu, mu); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     for(int mu=0;mu<Nd;mu++) { | ||||||
|  |       Integer B1 = Block[mu]; | ||||||
|  |       if ( B1 && (B1 <= Global[mu]) ) { | ||||||
|  |  | ||||||
|  | 	auto U_mu   = PeekIndex<LorentzIndex>(U,mu); | ||||||
|  | 	auto Uorg_mu= PeekIndex<LorentzIndex>(Uorg,mu); | ||||||
|  | 	// In the plane | ||||||
|  | 	U = where(mod(coor,B1)==Integer(B1-2),zzz,U);  | ||||||
|  | 	U = where(mod(coor,B1)==Integer(1)   ,zzz,U);  | ||||||
|  |  | ||||||
|  | 	// Perp links | ||||||
|  | 	U_mu = where(mod(coor,B1)==Integer(B1-3),Uorg_mu*f*f*f*f,U_mu); | ||||||
|  | 	U_mu = where(mod(coor,B1)==Integer(1)   ,Uorg_mu*f*f*f*f,U_mu); | ||||||
|  |  | ||||||
|  | 	PokeIndex<LorentzIndex>(U, U_mu, mu); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | NAMESPACE_END(Grid); | ||||||
| @@ -2,14 +2,11 @@ | |||||||
| 
 | 
 | ||||||
| Grid physics library, www.github.com/paboyle/Grid | Grid physics library, www.github.com/paboyle/Grid | ||||||
| 
 | 
 | ||||||
| Source file: ./lib/qcd/action/fermion/WilsonKernels.cc | Source file: ./lib/qcd/action/momentum/Domains.h | ||||||
| 
 | 
 | ||||||
| Copyright (C) 2015, 2020 | Copyright (C) 2021 | ||||||
| 
 | 
 | ||||||
| Author: Peter Boyle <paboyle@ph.ed.ac.uk> | Author: Peter Boyle <paboyle@ph.ed.ac.uk> | ||||||
| Author: Peter Boyle <peterboyle@Peters-MacBook-Pro-2.local> |  | ||||||
| Author: paboyle <paboyle@ph.ed.ac.uk> |  | ||||||
| Author: Nils Meyer <nils.meyer@ur.de> Regensburg University |  | ||||||
| 
 | 
 | ||||||
| This program is free software; you can redistribute it and/or modify | 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 | it under the terms of the GNU General Public License as published by | ||||||
| @@ -28,24 +25,15 @@ with this program; if not, write to the Free Software Foundation, Inc., | |||||||
| See the full license in the file "LICENSE" in the top level distribution | See the full license in the file "LICENSE" in the top level distribution | ||||||
| directory | directory | ||||||
| *************************************************************************************/ | *************************************************************************************/ | ||||||
| /*  END LEGAL */ | 			   /*  END LEGAL */ | ||||||
| #include <Grid/qcd/action/fermion/FermionCore.h> |  | ||||||
| #include <Grid/qcd/action/fermion/implementation/WilsonKernelsImplementation.h> |  | ||||||
| #include <Grid/qcd/action/fermion/implementation/WilsonKernelsHandImplementation.h> |  | ||||||
| 
 | 
 | ||||||
| #ifndef AVX512 | ////////////////////////////////////////////////////
 | ||||||
| #ifndef QPX | // Dirichlet filter with sub-block size B[mu]
 | ||||||
| #ifndef A64FX | ////////////////////////////////////////////////////
 | ||||||
| #ifndef A64FXFIXEDSIZE | #pragma once  | ||||||
| #include <Grid/qcd/action/fermion/implementation/WilsonKernelsAsmImplementation.h> |  | ||||||
| #endif |  | ||||||
| #endif |  | ||||||
| #endif |  | ||||||
| #endif |  | ||||||
| 
 | 
 | ||||||
| NAMESPACE_BEGIN(Grid); | #include <Grid/qcd/action/domains/DomainDecomposition.h> | ||||||
|  | #include <Grid/qcd/action/domains/MomentumFilter.h> | ||||||
|  | #include <Grid/qcd/action/domains/DirichletFilter.h> | ||||||
|  | #include <Grid/qcd/action/domains/DDHMCFilter.h> | ||||||
| 
 | 
 | ||||||
| #include "impl.h" |  | ||||||
| template class WilsonKernels<IMPLEMENTATION>; |  | ||||||
| 
 |  | ||||||
| NAMESPACE_END(Grid); |  | ||||||
							
								
								
									
										91
									
								
								Grid/qcd/action/domains/MomentumFilter.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								Grid/qcd/action/domains/MomentumFilter.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,91 @@ | |||||||
|  | /************************************************************************************* | ||||||
|  |  | ||||||
|  | Grid physics library, www.github.com/paboyle/Grid | ||||||
|  |  | ||||||
|  | Source file: ./lib/qcd/hmc/integrators/MomentumFilter.h | ||||||
|  |  | ||||||
|  | Copyright (C) 2015 | ||||||
|  |  | ||||||
|  | Author: Christopher Kelly <ckelly@bnl.gov> | ||||||
|  | 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 */ | ||||||
|  | //-------------------------------------------------------------------- | ||||||
|  | #pragma once  | ||||||
|  |  | ||||||
|  | NAMESPACE_BEGIN(Grid); | ||||||
|  |  | ||||||
|  | //These filter objects allow the user to manipulate the conjugate momentum as part of the update / refresh | ||||||
|  |  | ||||||
|  | template<typename MomentaField> | ||||||
|  | struct MomentumFilterBase{ | ||||||
|  |   virtual void applyFilter(MomentaField &P) const = 0; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | //Do nothing | ||||||
|  | template<typename MomentaField> | ||||||
|  | struct MomentumFilterNone: public MomentumFilterBase<MomentaField>{ | ||||||
|  |   void applyFilter(MomentaField &P) const override{} | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | //Multiply each site/direction by a Lorentz vector complex number field | ||||||
|  | //Can be used to implement a mask, zeroing out sites | ||||||
|  | template<typename MomentaField> | ||||||
|  | struct MomentumFilterApplyPhase: public MomentumFilterBase<MomentaField>{ | ||||||
|  |   typedef typename MomentaField::vector_type vector_type; //SIMD-vectorized complex type | ||||||
|  |   typedef typename MomentaField::scalar_type scalar_type; //scalar complex type | ||||||
|  |   typedef iVector<iScalar<iScalar<vector_type> >, Nd > LorentzScalarType; //complex phase for each site/direction | ||||||
|  |   typedef Lattice<LorentzScalarType> LatticeLorentzScalarType; | ||||||
|  |    | ||||||
|  |   LatticeLorentzScalarType phase; | ||||||
|  |   | ||||||
|  |   MomentumFilterApplyPhase(const LatticeLorentzScalarType _phase): phase(_phase){} | ||||||
|  |  | ||||||
|  |   //Default to uniform field of (1,0) | ||||||
|  |   MomentumFilterApplyPhase(GridBase* _grid): phase(_grid){ | ||||||
|  |     LorentzScalarType one; | ||||||
|  |     for(int mu=0;mu<Nd;mu++) | ||||||
|  |       one(mu)()() = scalar_type(1.); | ||||||
|  |      | ||||||
|  |     phase = one; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void applyFilter(MomentaField &P) const override{ | ||||||
|  |     conformable(P,phase); | ||||||
|  |     autoView( P_v , P, AcceleratorWrite); | ||||||
|  |     autoView( phase_v , phase, AcceleratorRead); | ||||||
|  |  | ||||||
|  |     accelerator_for(ss,P_v.size(),MomentaField::vector_type::Nsimd(),{ | ||||||
|  |     	auto site_mom = P_v(ss); | ||||||
|  |     	auto site_phase = phase_v(ss); | ||||||
|  | 	for(int mu=0;mu<Nd;mu++) | ||||||
|  | 	  site_mom(mu) = site_mom(mu) * site_phase(mu); | ||||||
|  |     	coalescedWrite(P_v[ss], site_mom); | ||||||
|  |       }); | ||||||
|  |      | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | }; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | NAMESPACE_END(Grid); | ||||||
| @@ -60,6 +60,8 @@ public: | |||||||
|   /////////////////////////////////////////////////////////////// |   /////////////////////////////////////////////////////////////// | ||||||
|   virtual void Dminus(const FermionField &psi, FermionField &chi); |   virtual void Dminus(const FermionField &psi, FermionField &chi); | ||||||
|   virtual void DminusDag(const FermionField &psi, FermionField &chi); |   virtual void DminusDag(const FermionField &psi, FermionField &chi); | ||||||
|  |   virtual void ImportFourDimPseudoFermion(const FermionField &input,FermionField &imported); | ||||||
|  |   virtual void ExportFourDimPseudoFermion(const FermionField &solution,FermionField &exported); | ||||||
|   virtual void ExportPhysicalFermionSolution(const FermionField &solution5d,FermionField &exported4d); |   virtual void ExportPhysicalFermionSolution(const FermionField &solution5d,FermionField &exported4d); | ||||||
|   virtual void ExportPhysicalFermionSource(const FermionField &solution5d, FermionField &exported4d); |   virtual void ExportPhysicalFermionSource(const FermionField &solution5d, FermionField &exported4d); | ||||||
|   virtual void ImportPhysicalFermionSource(const FermionField &input4d,FermionField &imported5d); |   virtual void ImportPhysicalFermionSource(const FermionField &input4d,FermionField &imported5d); | ||||||
|   | |||||||
							
								
								
									
										185
									
								
								Grid/qcd/action/fermion/DirichletFermionOperator.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										185
									
								
								Grid/qcd/action/fermion/DirichletFermionOperator.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,185 @@ | |||||||
|  | /************************************************************************************* | ||||||
|  |  | ||||||
|  |     Grid physics library, www.github.com/paboyle/Grid  | ||||||
|  |  | ||||||
|  |     Source file: ./lib/qcd/action/fermion/DirichletFermionOperator.h | ||||||
|  |  | ||||||
|  |     Copyright (C) 2021 | ||||||
|  |  | ||||||
|  | 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 */ | ||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | NAMESPACE_BEGIN(Grid); | ||||||
|  |  | ||||||
|  | //////////////////////////////////////////////////////////////// | ||||||
|  | // Wrap a fermion operator in Dirichlet BC's at node boundary | ||||||
|  | //////////////////////////////////////////////////////////////// | ||||||
|  |      | ||||||
|  | template<class Impl> | ||||||
|  | class DirichletFermionOperator : public FermionOperator<Impl> | ||||||
|  | { | ||||||
|  | public: | ||||||
|  |  | ||||||
|  |   INHERIT_IMPL_TYPES(Impl); | ||||||
|  |  | ||||||
|  |   // Data members | ||||||
|  |   int CommsMode; | ||||||
|  |   Coordinate Block; | ||||||
|  |   DirichletFilter<GaugeField> Filter; | ||||||
|  |   FermionOperator<Impl> & FermOp; | ||||||
|  |    | ||||||
|  |   // Constructor / bespoke | ||||||
|  |   DirichletFermionOperator(FermionOperator<Impl> & _FermOp, Coordinate &_Block) | ||||||
|  |     : FermOp(_FermOp), Block(_Block), Filter(Block) | ||||||
|  |   { | ||||||
|  |     // Save what the comms mode should be under normal BCs | ||||||
|  |     CommsMode = WilsonKernelsStatic::Comms; | ||||||
|  |     assert((CommsMode == WilsonKernelsStatic::CommsAndCompute) | ||||||
|  |          ||(CommsMode == WilsonKernelsStatic::CommsThenCompute)); | ||||||
|  |  | ||||||
|  |     // Check the block size divides local lattice | ||||||
|  |     GridBase *grid = FermOp.GaugeGrid(); | ||||||
|  |  | ||||||
|  |     int blocks_per_rank = 1; | ||||||
|  |     Coordinate LocalDims = grid->LocalDimensions(); | ||||||
|  |     Coordinate GlobalDims= grid->GlobalDimensions(); | ||||||
|  |     assert(Block.size()==LocalDims.size()); | ||||||
|  |  | ||||||
|  |     for(int d=0;d<LocalDims.size();d++){ | ||||||
|  |       if (Block[d]&&(Block[d]<=GlobalDims[d])){ | ||||||
|  | 	int r = LocalDims[d] % Block[d]; | ||||||
|  | 	assert(r == 0); | ||||||
|  | 	blocks_per_rank *= (LocalDims[d] / Block[d]); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     // Even blocks per node required // could be relaxed but inefficient use of hardware as idle nodes in boundary operator R | ||||||
|  |     assert( blocks_per_rank != 0); | ||||||
|  |  | ||||||
|  |     // Possible checks that SIMD lanes are used with full occupancy??? | ||||||
|  |   }; | ||||||
|  |   virtual ~DirichletFermionOperator(void) = default; | ||||||
|  |  | ||||||
|  |   void DirichletOn(void)   { | ||||||
|  |     assert(WilsonKernelsStatic::Comms!= WilsonKernelsStatic::CommsDirichlet); | ||||||
|  |     //    WilsonKernelsStatic::Comms = WilsonKernelsStatic::CommsDirichlet; | ||||||
|  |   } | ||||||
|  |   void DirichletOff(void)  { | ||||||
|  |     //    assert(WilsonKernelsStatic::Comms== WilsonKernelsStatic::CommsDirichlet); | ||||||
|  |     //    WilsonKernelsStatic::Comms = CommsMode; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // Implement the full interface | ||||||
|  |   virtual FermionField &tmp(void) { return FermOp.tmp(); }; | ||||||
|  |  | ||||||
|  |   virtual GridBase *FermionGrid(void)         { return FermOp.FermionGrid(); } | ||||||
|  |   virtual GridBase *FermionRedBlackGrid(void) { return FermOp.FermionRedBlackGrid(); } | ||||||
|  |   virtual GridBase *GaugeGrid(void)           { return FermOp.GaugeGrid(); } | ||||||
|  |   virtual GridBase *GaugeRedBlackGrid(void)   { return FermOp.GaugeRedBlackGrid(); } | ||||||
|  |    | ||||||
|  |   // override multiply | ||||||
|  |   virtual void  M    (const FermionField &in, FermionField &out) { DirichletOn(); FermOp.M(in,out);    DirichletOff();  }; | ||||||
|  |   virtual void  Mdag (const FermionField &in, FermionField &out) { DirichletOn(); FermOp.Mdag(in,out); DirichletOff();  }; | ||||||
|  |  | ||||||
|  |   // half checkerboard operaions | ||||||
|  |   virtual void   Meooe       (const FermionField &in, FermionField &out) { DirichletOn(); FermOp.Meooe(in,out);    DirichletOff(); };   | ||||||
|  |   virtual void   MeooeDag    (const FermionField &in, FermionField &out) { DirichletOn(); FermOp.MeooeDag(in,out); DirichletOff(); }; | ||||||
|  |   virtual void   Mooee       (const FermionField &in, FermionField &out) { DirichletOn(); FermOp.Mooee(in,out);    DirichletOff(); }; | ||||||
|  |   virtual void   MooeeDag    (const FermionField &in, FermionField &out) { DirichletOn(); FermOp.MooeeDag(in,out); DirichletOff(); }; | ||||||
|  |   virtual void   MooeeInv    (const FermionField &in, FermionField &out) { DirichletOn(); FermOp.MooeeInv(in,out); DirichletOff(); }; | ||||||
|  |   virtual void   MooeeInvDag (const FermionField &in, FermionField &out) { DirichletOn(); FermOp.MooeeInvDag(in,out); DirichletOff(); }; | ||||||
|  |  | ||||||
|  |   // non-hermitian hopping term; half cb or both | ||||||
|  |   virtual void Dhop  (const FermionField &in, FermionField &out,int dag) { DirichletOn(); FermOp.Dhop(in,out,dag);    DirichletOff(); }; | ||||||
|  |   virtual void DhopOE(const FermionField &in, FermionField &out,int dag) { DirichletOn(); FermOp.DhopOE(in,out,dag);  DirichletOff(); }; | ||||||
|  |   virtual void DhopEO(const FermionField &in, FermionField &out,int dag) { DirichletOn(); FermOp.DhopEO(in,out,dag);  DirichletOff(); }; | ||||||
|  |   virtual void DhopDir(const FermionField &in, FermionField &out,int dir,int disp) { DirichletOn(); FermOp.DhopDir(in,out,dir,disp);  DirichletOff(); }; | ||||||
|  |  | ||||||
|  |   // force terms; five routines; default to Dhop on diagonal | ||||||
|  |   virtual void MDeriv  (GaugeField &mat,const FermionField &U,const FermionField &V,int dag){FermOp.MDeriv(mat,U,V,dag);}; | ||||||
|  |   virtual void MoeDeriv(GaugeField &mat,const FermionField &U,const FermionField &V,int dag){FermOp.MoeDeriv(mat,U,V,dag);}; | ||||||
|  |   virtual void MeoDeriv(GaugeField &mat,const FermionField &U,const FermionField &V,int dag){FermOp.MeoDeriv(mat,U,V,dag);}; | ||||||
|  |   virtual void MooDeriv(GaugeField &mat,const FermionField &U,const FermionField &V,int dag){FermOp.MooDeriv(mat,U,V,dag);}; | ||||||
|  |   virtual void MeeDeriv(GaugeField &mat,const FermionField &U,const FermionField &V,int dag){FermOp.MeeDeriv(mat,U,V,dag);}; | ||||||
|  |  | ||||||
|  |   virtual void DhopDeriv  (GaugeField &mat,const FermionField &U,const FermionField &V,int dag){FermOp.DhopDeriv(mat,U,V,dag);}; | ||||||
|  |   virtual void DhopDerivEO(GaugeField &mat,const FermionField &U,const FermionField &V,int dag){FermOp.DhopDerivEO(mat,U,V,dag);}; | ||||||
|  |   virtual void DhopDerivOE(GaugeField &mat,const FermionField &U,const FermionField &V,int dag){FermOp.DhopDerivOE(mat,U,V,dag);}; | ||||||
|  |  | ||||||
|  |   virtual void  Mdiag  (const FermionField &in, FermionField &out) { Mooee(in,out);}; | ||||||
|  |   virtual void  Mdir   (const FermionField &in, FermionField &out,int dir,int disp){FermOp.Mdir(in,out,dir,disp);}; | ||||||
|  |   virtual void  MdirAll(const FermionField &in, std::vector<FermionField> &out)    {FermOp.MdirAll(in,out);}; | ||||||
|  |  | ||||||
|  |   /////////////////////////////////////////////// | ||||||
|  |   // Updates gauge field during HMC | ||||||
|  |   /////////////////////////////////////////////// | ||||||
|  |   DoubledGaugeField &GetDoubledGaugeField(void){ return FermOp.GetDoubledGaugeField(); }; | ||||||
|  |   DoubledGaugeField &GetDoubledGaugeFieldE(void){ return FermOp.GetDoubledGaugeFieldE(); }; | ||||||
|  |   DoubledGaugeField &GetDoubledGaugeFieldO(void){ return FermOp.GetDoubledGaugeFieldO(); }; | ||||||
|  |   virtual void ImportGauge(const GaugeField & _U) | ||||||
|  |   { | ||||||
|  |     GaugeField U = _U; | ||||||
|  |     // Filter gauge field to apply Dirichlet | ||||||
|  |     Filter.applyFilter(U); | ||||||
|  |     FermOp.ImportGauge(U); | ||||||
|  |   } | ||||||
|  |   /////////////////////////////////////////////// | ||||||
|  |   // Physical field import/export | ||||||
|  |   /////////////////////////////////////////////// | ||||||
|  |   virtual void Dminus(const FermionField &psi, FermionField &chi)    { FermOp.Dminus(psi,chi); } | ||||||
|  |   virtual void DminusDag(const FermionField &psi, FermionField &chi) { FermOp.DminusDag(psi,chi); } | ||||||
|  |   virtual void ImportFourDimPseudoFermion(const FermionField &input,FermionField &imported)   { FermOp.ImportFourDimPseudoFermion(input,imported);} | ||||||
|  |   virtual void ExportFourDimPseudoFermion(const FermionField &solution,FermionField &exported){ FermOp.ExportFourDimPseudoFermion(solution,exported);} | ||||||
|  |   virtual void ImportPhysicalFermionSource(const FermionField &input,FermionField &imported)  { FermOp.ImportPhysicalFermionSource(input,imported);} | ||||||
|  |   virtual void ImportUnphysicalFermion(const FermionField &input,FermionField &imported)      { FermOp.ImportUnphysicalFermion(input,imported);} | ||||||
|  |   virtual void ExportPhysicalFermionSolution(const FermionField &solution,FermionField &exported) {FermOp.ExportPhysicalFermionSolution(solution,exported);} | ||||||
|  |   virtual void ExportPhysicalFermionSource(const FermionField &solution,FermionField &exported)   {FermOp.ExportPhysicalFermionSource(solution,exported);} | ||||||
|  |   ////////////////////////////////////////////////////////////////////// | ||||||
|  |   // Should never be used | ||||||
|  |   ////////////////////////////////////////////////////////////////////// | ||||||
|  |   virtual void MomentumSpacePropagator(FermionField &out,const FermionField &in,RealD _m,std::vector<double> twist) { assert(0);}; | ||||||
|  |   virtual void FreePropagator(const FermionField &in,FermionField &out,RealD mass,std::vector<Complex> boundary,std::vector<double> twist) {assert(0);} | ||||||
|  |   virtual void FreePropagator(const FermionField &in,FermionField &out,RealD mass) { assert(0);} | ||||||
|  |   virtual void ContractConservedCurrent(PropagatorField &q_in_1, | ||||||
|  | 					PropagatorField &q_in_2, | ||||||
|  | 					PropagatorField &q_out, | ||||||
|  | 					PropagatorField &phys_src, | ||||||
|  | 					Current curr_type, | ||||||
|  | 					unsigned int mu) | ||||||
|  |   {assert(0);}; | ||||||
|  |   virtual void SeqConservedCurrent(PropagatorField &q_in,  | ||||||
|  | 				   PropagatorField &q_out, | ||||||
|  | 				   PropagatorField &phys_src, | ||||||
|  | 				   Current curr_type, | ||||||
|  | 				   unsigned int mu, | ||||||
|  | 				   unsigned int tmin,  | ||||||
|  | 				   unsigned int tmax, | ||||||
|  | 				   ComplexField &lattice_cmplx) | ||||||
|  |   {assert(0);}; | ||||||
|  |       // Only reimplemented in Wilson5D  | ||||||
|  |       // Default to just a zero correlation function | ||||||
|  |   virtual void ContractJ5q(FermionField &q_in   ,ComplexField &J5q) { J5q=Zero(); }; | ||||||
|  |   virtual void ContractJ5q(PropagatorField &q_in,ComplexField &J5q) { J5q=Zero(); }; | ||||||
|  |    | ||||||
|  | }; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | NAMESPACE_END(Grid); | ||||||
|  |  | ||||||
| @@ -101,6 +101,12 @@ NAMESPACE_CHECK(WilsonTM5); | |||||||
| #include <Grid/qcd/action/fermion/PauliVillarsInverters.h> | #include <Grid/qcd/action/fermion/PauliVillarsInverters.h> | ||||||
| #include <Grid/qcd/action/fermion/Reconstruct5Dprop.h> | #include <Grid/qcd/action/fermion/Reconstruct5Dprop.h> | ||||||
| #include <Grid/qcd/action/fermion/MADWF.h> | #include <Grid/qcd/action/fermion/MADWF.h> | ||||||
|  | //////////////////////////////////////////////////////////////////// | ||||||
|  | // DDHMC related  | ||||||
|  | //////////////////////////////////////////////////////////////////// | ||||||
|  | #include <Grid/qcd/action/fermion/DirichletFermionOperator.h> | ||||||
|  | #include <Grid/qcd/action/fermion/SchurFactoredFermionOperator.h> | ||||||
|  |  | ||||||
| NAMESPACE_CHECK(DWFutils); | NAMESPACE_CHECK(DWFutils); | ||||||
|  |  | ||||||
| //////////////////////////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////////////////////////// | ||||||
| @@ -115,9 +121,9 @@ typedef WilsonFermion<WilsonImplR> WilsonFermionR; | |||||||
| typedef WilsonFermion<WilsonImplF> WilsonFermionF; | typedef WilsonFermion<WilsonImplF> WilsonFermionF; | ||||||
| typedef WilsonFermion<WilsonImplD> WilsonFermionD; | typedef WilsonFermion<WilsonImplD> WilsonFermionD; | ||||||
|  |  | ||||||
| typedef WilsonFermion<WilsonImplRL> WilsonFermionRL; | //typedef WilsonFermion<WilsonImplRL> WilsonFermionRL; | ||||||
| typedef WilsonFermion<WilsonImplFH> WilsonFermionFH; | //typedef WilsonFermion<WilsonImplFH> WilsonFermionFH; | ||||||
| typedef WilsonFermion<WilsonImplDF> WilsonFermionDF; | //typedef WilsonFermion<WilsonImplDF> WilsonFermionDF; | ||||||
|  |  | ||||||
| typedef WilsonFermion<WilsonAdjImplR> WilsonAdjFermionR; | typedef WilsonFermion<WilsonAdjImplR> WilsonAdjFermionR; | ||||||
| typedef WilsonFermion<WilsonAdjImplF> WilsonAdjFermionF; | typedef WilsonFermion<WilsonAdjImplF> WilsonAdjFermionF; | ||||||
| @@ -158,41 +164,41 @@ typedef DomainWallFermion<WilsonImplR> DomainWallFermionR; | |||||||
| typedef DomainWallFermion<WilsonImplF> DomainWallFermionF; | typedef DomainWallFermion<WilsonImplF> DomainWallFermionF; | ||||||
| typedef DomainWallFermion<WilsonImplD> DomainWallFermionD; | typedef DomainWallFermion<WilsonImplD> DomainWallFermionD; | ||||||
|  |  | ||||||
| typedef DomainWallFermion<WilsonImplRL> DomainWallFermionRL; | //typedef DomainWallFermion<WilsonImplRL> DomainWallFermionRL; | ||||||
| typedef DomainWallFermion<WilsonImplFH> DomainWallFermionFH; | //typedef DomainWallFermion<WilsonImplFH> DomainWallFermionFH; | ||||||
| typedef DomainWallFermion<WilsonImplDF> DomainWallFermionDF; | //typedef DomainWallFermion<WilsonImplDF> DomainWallFermionDF; | ||||||
|  |  | ||||||
| typedef DomainWallEOFAFermion<WilsonImplR> DomainWallEOFAFermionR; | typedef DomainWallEOFAFermion<WilsonImplR> DomainWallEOFAFermionR; | ||||||
| typedef DomainWallEOFAFermion<WilsonImplF> DomainWallEOFAFermionF; | typedef DomainWallEOFAFermion<WilsonImplF> DomainWallEOFAFermionF; | ||||||
| typedef DomainWallEOFAFermion<WilsonImplD> DomainWallEOFAFermionD; | typedef DomainWallEOFAFermion<WilsonImplD> DomainWallEOFAFermionD; | ||||||
|  |  | ||||||
| typedef DomainWallEOFAFermion<WilsonImplRL> DomainWallEOFAFermionRL; | //typedef DomainWallEOFAFermion<WilsonImplRL> DomainWallEOFAFermionRL; | ||||||
| typedef DomainWallEOFAFermion<WilsonImplFH> DomainWallEOFAFermionFH; | //typedef DomainWallEOFAFermion<WilsonImplFH> DomainWallEOFAFermionFH; | ||||||
| typedef DomainWallEOFAFermion<WilsonImplDF> DomainWallEOFAFermionDF; | //typedef DomainWallEOFAFermion<WilsonImplDF> DomainWallEOFAFermionDF; | ||||||
|  |  | ||||||
| typedef MobiusFermion<WilsonImplR> MobiusFermionR; | typedef MobiusFermion<WilsonImplR> MobiusFermionR; | ||||||
| typedef MobiusFermion<WilsonImplF> MobiusFermionF; | typedef MobiusFermion<WilsonImplF> MobiusFermionF; | ||||||
| typedef MobiusFermion<WilsonImplD> MobiusFermionD; | typedef MobiusFermion<WilsonImplD> MobiusFermionD; | ||||||
|  |  | ||||||
| typedef MobiusFermion<WilsonImplRL> MobiusFermionRL; | //typedef MobiusFermion<WilsonImplRL> MobiusFermionRL; | ||||||
| typedef MobiusFermion<WilsonImplFH> MobiusFermionFH; | //typedef MobiusFermion<WilsonImplFH> MobiusFermionFH; | ||||||
| typedef MobiusFermion<WilsonImplDF> MobiusFermionDF; | //typedef MobiusFermion<WilsonImplDF> MobiusFermionDF; | ||||||
|  |  | ||||||
| typedef MobiusEOFAFermion<WilsonImplR> MobiusEOFAFermionR; | typedef MobiusEOFAFermion<WilsonImplR> MobiusEOFAFermionR; | ||||||
| typedef MobiusEOFAFermion<WilsonImplF> MobiusEOFAFermionF; | typedef MobiusEOFAFermion<WilsonImplF> MobiusEOFAFermionF; | ||||||
| typedef MobiusEOFAFermion<WilsonImplD> MobiusEOFAFermionD; | typedef MobiusEOFAFermion<WilsonImplD> MobiusEOFAFermionD; | ||||||
|  |  | ||||||
| typedef MobiusEOFAFermion<WilsonImplRL> MobiusEOFAFermionRL; | //typedef MobiusEOFAFermion<WilsonImplRL> MobiusEOFAFermionRL; | ||||||
| typedef MobiusEOFAFermion<WilsonImplFH> MobiusEOFAFermionFH; | //typedef MobiusEOFAFermion<WilsonImplFH> MobiusEOFAFermionFH; | ||||||
| typedef MobiusEOFAFermion<WilsonImplDF> MobiusEOFAFermionDF; | //typedef MobiusEOFAFermion<WilsonImplDF> MobiusEOFAFermionDF; | ||||||
|  |  | ||||||
| typedef ZMobiusFermion<ZWilsonImplR> ZMobiusFermionR; | typedef ZMobiusFermion<ZWilsonImplR> ZMobiusFermionR; | ||||||
| typedef ZMobiusFermion<ZWilsonImplF> ZMobiusFermionF; | typedef ZMobiusFermion<ZWilsonImplF> ZMobiusFermionF; | ||||||
| typedef ZMobiusFermion<ZWilsonImplD> ZMobiusFermionD; | typedef ZMobiusFermion<ZWilsonImplD> ZMobiusFermionD; | ||||||
|  |  | ||||||
| typedef ZMobiusFermion<ZWilsonImplRL> ZMobiusFermionRL; | //typedef ZMobiusFermion<ZWilsonImplRL> ZMobiusFermionRL; | ||||||
| typedef ZMobiusFermion<ZWilsonImplFH> ZMobiusFermionFH; | //typedef ZMobiusFermion<ZWilsonImplFH> ZMobiusFermionFH; | ||||||
| typedef ZMobiusFermion<ZWilsonImplDF> ZMobiusFermionDF; | //typedef ZMobiusFermion<ZWilsonImplDF> ZMobiusFermionDF; | ||||||
|  |  | ||||||
| // Ls vectorised | // Ls vectorised | ||||||
| typedef ScaledShamirFermion<WilsonImplR> ScaledShamirFermionR; | typedef ScaledShamirFermion<WilsonImplR> ScaledShamirFermionR; | ||||||
| @@ -235,49 +241,49 @@ typedef WilsonFermion<GparityWilsonImplR>     GparityWilsonFermionR; | |||||||
| typedef WilsonFermion<GparityWilsonImplF>     GparityWilsonFermionF; | typedef WilsonFermion<GparityWilsonImplF>     GparityWilsonFermionF; | ||||||
| typedef WilsonFermion<GparityWilsonImplD>     GparityWilsonFermionD; | typedef WilsonFermion<GparityWilsonImplD>     GparityWilsonFermionD; | ||||||
|  |  | ||||||
| typedef WilsonFermion<GparityWilsonImplRL>     GparityWilsonFermionRL; | //typedef WilsonFermion<GparityWilsonImplRL>     GparityWilsonFermionRL; | ||||||
| typedef WilsonFermion<GparityWilsonImplFH>     GparityWilsonFermionFH; | //typedef WilsonFermion<GparityWilsonImplFH>     GparityWilsonFermionFH; | ||||||
| typedef WilsonFermion<GparityWilsonImplDF>     GparityWilsonFermionDF; | //typedef WilsonFermion<GparityWilsonImplDF>     GparityWilsonFermionDF; | ||||||
|  |  | ||||||
| typedef DomainWallFermion<GparityWilsonImplR> GparityDomainWallFermionR; | typedef DomainWallFermion<GparityWilsonImplR> GparityDomainWallFermionR; | ||||||
| typedef DomainWallFermion<GparityWilsonImplF> GparityDomainWallFermionF; | typedef DomainWallFermion<GparityWilsonImplF> GparityDomainWallFermionF; | ||||||
| typedef DomainWallFermion<GparityWilsonImplD> GparityDomainWallFermionD; | typedef DomainWallFermion<GparityWilsonImplD> GparityDomainWallFermionD; | ||||||
|  |  | ||||||
| typedef DomainWallFermion<GparityWilsonImplRL> GparityDomainWallFermionRL; | //typedef DomainWallFermion<GparityWilsonImplRL> GparityDomainWallFermionRL; | ||||||
| typedef DomainWallFermion<GparityWilsonImplFH> GparityDomainWallFermionFH; | //typedef DomainWallFermion<GparityWilsonImplFH> GparityDomainWallFermionFH; | ||||||
| typedef DomainWallFermion<GparityWilsonImplDF> GparityDomainWallFermionDF; | //typedef DomainWallFermion<GparityWilsonImplDF> GparityDomainWallFermionDF; | ||||||
|  |  | ||||||
| typedef DomainWallEOFAFermion<GparityWilsonImplR> GparityDomainWallEOFAFermionR; | typedef DomainWallEOFAFermion<GparityWilsonImplR> GparityDomainWallEOFAFermionR; | ||||||
| typedef DomainWallEOFAFermion<GparityWilsonImplF> GparityDomainWallEOFAFermionF; | typedef DomainWallEOFAFermion<GparityWilsonImplF> GparityDomainWallEOFAFermionF; | ||||||
| typedef DomainWallEOFAFermion<GparityWilsonImplD> GparityDomainWallEOFAFermionD; | typedef DomainWallEOFAFermion<GparityWilsonImplD> GparityDomainWallEOFAFermionD; | ||||||
|  |  | ||||||
| typedef DomainWallEOFAFermion<GparityWilsonImplRL> GparityDomainWallEOFAFermionRL; | //typedef DomainWallEOFAFermion<GparityWilsonImplRL> GparityDomainWallEOFAFermionRL; | ||||||
| typedef DomainWallEOFAFermion<GparityWilsonImplFH> GparityDomainWallEOFAFermionFH; | //typedef DomainWallEOFAFermion<GparityWilsonImplFH> GparityDomainWallEOFAFermionFH; | ||||||
| typedef DomainWallEOFAFermion<GparityWilsonImplDF> GparityDomainWallEOFAFermionDF; | //typedef DomainWallEOFAFermion<GparityWilsonImplDF> GparityDomainWallEOFAFermionDF; | ||||||
|  |  | ||||||
| typedef WilsonTMFermion<GparityWilsonImplR> GparityWilsonTMFermionR; | typedef WilsonTMFermion<GparityWilsonImplR> GparityWilsonTMFermionR; | ||||||
| typedef WilsonTMFermion<GparityWilsonImplF> GparityWilsonTMFermionF; | typedef WilsonTMFermion<GparityWilsonImplF> GparityWilsonTMFermionF; | ||||||
| typedef WilsonTMFermion<GparityWilsonImplD> GparityWilsonTMFermionD; | typedef WilsonTMFermion<GparityWilsonImplD> GparityWilsonTMFermionD; | ||||||
|  |  | ||||||
| typedef WilsonTMFermion<GparityWilsonImplRL> GparityWilsonTMFermionRL; | //typedef WilsonTMFermion<GparityWilsonImplRL> GparityWilsonTMFermionRL; | ||||||
| typedef WilsonTMFermion<GparityWilsonImplFH> GparityWilsonTMFermionFH; | //typedef WilsonTMFermion<GparityWilsonImplFH> GparityWilsonTMFermionFH; | ||||||
| typedef WilsonTMFermion<GparityWilsonImplDF> GparityWilsonTMFermionDF; | //typedef WilsonTMFermion<GparityWilsonImplDF> GparityWilsonTMFermionDF; | ||||||
|  |  | ||||||
| typedef MobiusFermion<GparityWilsonImplR> GparityMobiusFermionR; | typedef MobiusFermion<GparityWilsonImplR> GparityMobiusFermionR; | ||||||
| typedef MobiusFermion<GparityWilsonImplF> GparityMobiusFermionF; | typedef MobiusFermion<GparityWilsonImplF> GparityMobiusFermionF; | ||||||
| typedef MobiusFermion<GparityWilsonImplD> GparityMobiusFermionD; | typedef MobiusFermion<GparityWilsonImplD> GparityMobiusFermionD; | ||||||
|  |  | ||||||
| typedef MobiusFermion<GparityWilsonImplRL> GparityMobiusFermionRL; | //typedef MobiusFermion<GparityWilsonImplRL> GparityMobiusFermionRL; | ||||||
| typedef MobiusFermion<GparityWilsonImplFH> GparityMobiusFermionFH; | //typedef MobiusFermion<GparityWilsonImplFH> GparityMobiusFermionFH; | ||||||
| typedef MobiusFermion<GparityWilsonImplDF> GparityMobiusFermionDF; | //typedef MobiusFermion<GparityWilsonImplDF> GparityMobiusFermionDF; | ||||||
|  |  | ||||||
| typedef MobiusEOFAFermion<GparityWilsonImplR> GparityMobiusEOFAFermionR; | typedef MobiusEOFAFermion<GparityWilsonImplR> GparityMobiusEOFAFermionR; | ||||||
| typedef MobiusEOFAFermion<GparityWilsonImplF> GparityMobiusEOFAFermionF; | typedef MobiusEOFAFermion<GparityWilsonImplF> GparityMobiusEOFAFermionF; | ||||||
| typedef MobiusEOFAFermion<GparityWilsonImplD> GparityMobiusEOFAFermionD; | typedef MobiusEOFAFermion<GparityWilsonImplD> GparityMobiusEOFAFermionD; | ||||||
|  |  | ||||||
| typedef MobiusEOFAFermion<GparityWilsonImplRL> GparityMobiusEOFAFermionRL; | //typedef MobiusEOFAFermion<GparityWilsonImplRL> GparityMobiusEOFAFermionRL; | ||||||
| typedef MobiusEOFAFermion<GparityWilsonImplFH> GparityMobiusEOFAFermionFH; | //typedef MobiusEOFAFermion<GparityWilsonImplFH> GparityMobiusEOFAFermionFH; | ||||||
| typedef MobiusEOFAFermion<GparityWilsonImplDF> GparityMobiusEOFAFermionDF; | //typedef MobiusEOFAFermion<GparityWilsonImplDF> GparityMobiusEOFAFermionDF; | ||||||
|  |  | ||||||
| typedef ImprovedStaggeredFermion<StaggeredImplR> ImprovedStaggeredFermionR; | typedef ImprovedStaggeredFermion<StaggeredImplR> ImprovedStaggeredFermionR; | ||||||
| typedef ImprovedStaggeredFermion<StaggeredImplF> ImprovedStaggeredFermionF; | typedef ImprovedStaggeredFermion<StaggeredImplF> ImprovedStaggeredFermionF; | ||||||
| @@ -291,12 +297,6 @@ typedef ImprovedStaggeredFermion5D<StaggeredImplR> ImprovedStaggeredFermion5DR; | |||||||
| typedef ImprovedStaggeredFermion5D<StaggeredImplF> ImprovedStaggeredFermion5DF; | typedef ImprovedStaggeredFermion5D<StaggeredImplF> ImprovedStaggeredFermion5DF; | ||||||
| typedef ImprovedStaggeredFermion5D<StaggeredImplD> ImprovedStaggeredFermion5DD; | typedef ImprovedStaggeredFermion5D<StaggeredImplD> ImprovedStaggeredFermion5DD; | ||||||
|  |  | ||||||
| #ifndef GRID_CUDA |  | ||||||
| typedef ImprovedStaggeredFermion5D<StaggeredVec5dImplR> ImprovedStaggeredFermionVec5dR; |  | ||||||
| typedef ImprovedStaggeredFermion5D<StaggeredVec5dImplF> ImprovedStaggeredFermionVec5dF; |  | ||||||
| typedef ImprovedStaggeredFermion5D<StaggeredVec5dImplD> ImprovedStaggeredFermionVec5dD; |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| NAMESPACE_END(Grid); | NAMESPACE_END(Grid); | ||||||
|  |  | ||||||
| //////////////////// | //////////////////// | ||||||
|   | |||||||
| @@ -25,8 +25,7 @@ Author: Peter Boyle <pabobyle@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 */ | ||||||
| #ifndef  GRID_QCD_FERMION_CORE_H | #pragma once | ||||||
| #define  GRID_QCD_FERMION_CORE_H |  | ||||||
|  |  | ||||||
| #include <Grid/GridCore.h> | #include <Grid/GridCore.h> | ||||||
| #include <Grid/GridQCDcore.h> | #include <Grid/GridQCDcore.h> | ||||||
| @@ -45,4 +44,3 @@ NAMESPACE_CHECK(FermionOperator); | |||||||
| #include <Grid/qcd/action/fermion/StaggeredKernels.h>        //used by all wilson type fermions | #include <Grid/qcd/action/fermion/StaggeredKernels.h>        //used by all wilson type fermions | ||||||
| NAMESPACE_CHECK(Kernels); | NAMESPACE_CHECK(Kernels); | ||||||
|  |  | ||||||
| #endif |  | ||||||
|   | |||||||
| @@ -140,6 +140,9 @@ public: | |||||||
|   // Updates gauge field during HMC |   // Updates gauge field during HMC | ||||||
|   /////////////////////////////////////////////// |   /////////////////////////////////////////////// | ||||||
|   virtual void ImportGauge(const GaugeField & _U)=0; |   virtual void ImportGauge(const GaugeField & _U)=0; | ||||||
|  |   virtual DoubledGaugeField &GetDoubledGaugeField(void)  =0; | ||||||
|  |   virtual DoubledGaugeField &GetDoubledGaugeFieldE(void)  =0; | ||||||
|  |   virtual DoubledGaugeField &GetDoubledGaugeFieldO(void)  =0; | ||||||
|  |  | ||||||
|   ////////////////////////////////////////////////////////////////////// |   ////////////////////////////////////////////////////////////////////// | ||||||
|   // Conserved currents, either contract at sink or insert sequentially. |   // Conserved currents, either contract at sink or insert sequentially. | ||||||
| @@ -171,6 +174,16 @@ public: | |||||||
|       /////////////////////////////////////////////// |       /////////////////////////////////////////////// | ||||||
|       virtual void Dminus(const FermionField &psi, FermionField &chi)    { chi=psi; } |       virtual void Dminus(const FermionField &psi, FermionField &chi)    { chi=psi; } | ||||||
|       virtual void DminusDag(const FermionField &psi, FermionField &chi) { chi=psi; } |       virtual void DminusDag(const FermionField &psi, FermionField &chi) { chi=psi; } | ||||||
|  |  | ||||||
|  |       virtual void ImportFourDimPseudoFermion(const FermionField &input,FermionField &imported) | ||||||
|  |       { | ||||||
|  | 	imported = input; | ||||||
|  |       }; | ||||||
|  |       virtual void ExportFourDimPseudoFermion(const FermionField &solution,FermionField &exported) | ||||||
|  |       { | ||||||
|  | 	exported=solution; | ||||||
|  |       }; | ||||||
|  |  | ||||||
|       virtual void ImportPhysicalFermionSource(const FermionField &input,FermionField &imported) |       virtual void ImportPhysicalFermionSource(const FermionField &input,FermionField &imported) | ||||||
|       { |       { | ||||||
| 	imported = input; | 	imported = input; | ||||||
|   | |||||||
| @@ -153,8 +153,8 @@ public: | |||||||
|   typedef typename Impl::StencilImpl             StencilImpl;		\ |   typedef typename Impl::StencilImpl             StencilImpl;		\ | ||||||
|   typedef typename Impl::ImplParams               ImplParams;	        \ |   typedef typename Impl::ImplParams               ImplParams;	        \ | ||||||
|   typedef typename Impl::StencilImpl::View_type  StencilView;		\ |   typedef typename Impl::StencilImpl::View_type  StencilView;		\ | ||||||
|   typedef typename ViewMap<FermionField>::Type      FermionFieldView;	\ |   typedef const typename ViewMap<FermionField>::Type      FermionFieldView;	\ | ||||||
|   typedef typename ViewMap<DoubledGaugeField>::Type DoubledGaugeFieldView; |   typedef const typename ViewMap<DoubledGaugeField>::Type DoubledGaugeFieldView; | ||||||
|  |  | ||||||
| #define INHERIT_IMPL_TYPES(Base)		\ | #define INHERIT_IMPL_TYPES(Base)		\ | ||||||
|   INHERIT_GIMPL_TYPES(Base)			\ |   INHERIT_GIMPL_TYPES(Base)			\ | ||||||
| @@ -183,7 +183,8 @@ NAMESPACE_CHECK(ImplStaggered); | |||||||
| ///////////////////////////////////////////////////////////////////////////// | ///////////////////////////////////////////////////////////////////////////// | ||||||
| // Single flavour one component spinors with colour index. 5d vec | // Single flavour one component spinors with colour index. 5d vec | ||||||
| ///////////////////////////////////////////////////////////////////////////// | ///////////////////////////////////////////////////////////////////////////// | ||||||
| #include <Grid/qcd/action/fermion/StaggeredVec5dImpl.h>  | // Deprecate Vec5d | ||||||
| NAMESPACE_CHECK(ImplStaggered5dVec);   | //#include <Grid/qcd/action/fermion/StaggeredVec5dImpl.h>  | ||||||
|  | //NAMESPACE_CHECK(ImplStaggered5dVec);   | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -30,6 +30,18 @@ directory | |||||||
|  |  | ||||||
| NAMESPACE_BEGIN(Grid); | NAMESPACE_BEGIN(Grid); | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |   Policy implementation for G-parity boundary conditions | ||||||
|  |  | ||||||
|  |   Rather than treating the gauge field as a flavored field, the Grid implementation of G-parity treats the gauge field as a regular | ||||||
|  |   field with complex conjugate boundary conditions. In order to ensure the second flavor interacts with the conjugate links and the first | ||||||
|  |   with the regular links we overload the functionality of doubleStore, whose purpose is to store the gauge field and the barrel-shifted gauge field | ||||||
|  |   to avoid communicating links when applying the Dirac operator, such that the double-stored field contains also a flavor index which maps to | ||||||
|  |   either the link or the conjugate link. This flavored field is then used by multLink to apply the correct link to a spinor. | ||||||
|  |  | ||||||
|  |   Here the first Nd-1 directions are treated as "spatial", and a twist value of 1 indicates G-parity BCs in that direction.  | ||||||
|  |   mu=Nd-1 is assumed to be the time direction and a twist value of 1 indicates antiperiodic BCs | ||||||
|  |  */ | ||||||
| template <class S, class Representation = FundamentalRepresentation, class Options=CoeffReal> | template <class S, class Representation = FundamentalRepresentation, class Options=CoeffReal> | ||||||
| class GparityWilsonImpl : public ConjugateGaugeImpl<GaugeImplTypes<S, Representation::Dimension> > { | class GparityWilsonImpl : public ConjugateGaugeImpl<GaugeImplTypes<S, Representation::Dimension> > { | ||||||
| public: | public: | ||||||
| @@ -97,42 +109,30 @@ public: | |||||||
|     Coordinate icoor; |     Coordinate icoor; | ||||||
|  |  | ||||||
| #ifdef GRID_SIMT | #ifdef GRID_SIMT | ||||||
|     _Spinor tmp; |  | ||||||
|  |  | ||||||
|     const int Nsimd =SiteDoubledGaugeField::Nsimd(); |     const int Nsimd =SiteDoubledGaugeField::Nsimd(); | ||||||
|     int s = acceleratorSIMTlane(Nsimd); |     int s = acceleratorSIMTlane(Nsimd); | ||||||
|     St.iCoorFromIindex(icoor,s); |     St.iCoorFromIindex(icoor,s); | ||||||
|  |  | ||||||
|     int mmu = mu % Nd; |     int mmu = mu % Nd; | ||||||
|     if ( SE->_around_the_world && St.parameters.twists[mmu] ) { |  | ||||||
|        |  | ||||||
|       int permute_lane = (sl==1)  |  | ||||||
|     	|| ((distance== 1)&&(icoor[direction]==1)) |  | ||||||
| 	|| ((distance==-1)&&(icoor[direction]==0)); |  | ||||||
|  |  | ||||||
|       if ( permute_lane ) {  |     auto UU0=coalescedRead(U(0)(mu)); | ||||||
| 	tmp(0) = chi(1); |     auto UU1=coalescedRead(U(1)(mu)); | ||||||
| 	tmp(1) = chi(0); |      | ||||||
|       } else { |     //Decide whether we do a G-parity flavor twist | ||||||
| 	tmp(0) = chi(0); |     //Note: this assumes (but does not check) that sl==1 || sl==2 i.e. max 2 SIMD lanes in G-parity dir | ||||||
| 	tmp(1) = chi(1); |     //It also assumes (but does not check) that abs(distance) == 1 | ||||||
|       } |     int permute_lane = (sl==1)  | ||||||
|  |     || ((distance== 1)&&(icoor[direction]==1)) | ||||||
|  |     || ((distance==-1)&&(icoor[direction]==0)); | ||||||
|  |  | ||||||
|       auto UU0=coalescedRead(U(0)(mu)); |     permute_lane = permute_lane && SE->_around_the_world && St.parameters.twists[mmu] && mmu < Nd-1; //only if we are going around the world in a spatial direction | ||||||
|       auto UU1=coalescedRead(U(1)(mu)); |  | ||||||
|  |  | ||||||
|       mult(&phi(0),&UU0,&tmp(0)); |     //Apply the links | ||||||
|       mult(&phi(1),&UU1,&tmp(1)); |     int f_upper = permute_lane ? 1 : 0; | ||||||
|  |     int f_lower = !f_upper; | ||||||
|  |  | ||||||
|     } else { |     mult(&phi(0),&UU0,&chi(f_upper)); | ||||||
|  |     mult(&phi(1),&UU1,&chi(f_lower)); | ||||||
|       auto UU0=coalescedRead(U(0)(mu)); |  | ||||||
|       auto UU1=coalescedRead(U(1)(mu)); |  | ||||||
|  |  | ||||||
|       mult(&phi(0),&UU0,&chi(0)); |  | ||||||
|       mult(&phi(1),&UU1,&chi(1)); |  | ||||||
|  |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| #else | #else | ||||||
|     typedef _Spinor vobj; |     typedef _Spinor vobj; | ||||||
| @@ -151,10 +151,10 @@ public: | |||||||
|     assert((distance == 1) || (distance == -1));  // nearest neighbour stencil hard code |     assert((distance == 1) || (distance == -1));  // nearest neighbour stencil hard code | ||||||
|     assert((sl == 1) || (sl == 2)); |     assert((sl == 1) || (sl == 2)); | ||||||
|  |  | ||||||
|     if ( SE->_around_the_world && St.parameters.twists[mmu] ) { |     //If this site is an global boundary site, perform the G-parity flavor twist | ||||||
|  |     if ( mmu < Nd-1 && SE->_around_the_world && St.parameters.twists[mmu] ) { | ||||||
|       if ( sl == 2 ) { |       if ( sl == 2 ) { | ||||||
|         | 	//Only do the twist for lanes on the edge of the physical node | ||||||
| 	ExtractBuffer<sobj> vals(Nsimd); | 	ExtractBuffer<sobj> vals(Nsimd); | ||||||
|  |  | ||||||
| 	extract(chi,vals); | 	extract(chi,vals); | ||||||
| @@ -209,6 +209,19 @@ public: | |||||||
|     reg = memory; |     reg = memory; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   //Poke 'poke_f0' onto flavor 0 and 'poke_f1' onto flavor 1 in direction mu of the doubled gauge field Uds | ||||||
|  |   inline void pokeGparityDoubledGaugeField(DoubledGaugeField &Uds, const GaugeLinkField &poke_f0, const GaugeLinkField &poke_f1, const int mu){ | ||||||
|  |     autoView(poke_f0_v, poke_f0, CpuRead); | ||||||
|  |     autoView(poke_f1_v, poke_f1, CpuRead); | ||||||
|  |     autoView(Uds_v, Uds, CpuWrite); | ||||||
|  |     thread_foreach(ss,poke_f0_v,{ | ||||||
|  | 	Uds_v[ss](0)(mu) = poke_f0_v[ss](); | ||||||
|  | 	Uds_v[ss](1)(mu) = poke_f1_v[ss](); | ||||||
|  |       }); | ||||||
|  |   } | ||||||
|  |      | ||||||
|  |  | ||||||
|   inline void DoubleStore(GridBase *GaugeGrid,DoubledGaugeField &Uds,const GaugeField &Umu) |   inline void DoubleStore(GridBase *GaugeGrid,DoubledGaugeField &Uds,const GaugeField &Umu) | ||||||
|   { |   { | ||||||
|     conformable(Uds.Grid(),GaugeGrid); |     conformable(Uds.Grid(),GaugeGrid); | ||||||
| @@ -219,14 +232,19 @@ public: | |||||||
|     GaugeLinkField Uconj(GaugeGrid); |     GaugeLinkField Uconj(GaugeGrid); | ||||||
|     |     | ||||||
|     Lattice<iScalar<vInteger> > coor(GaugeGrid); |     Lattice<iScalar<vInteger> > coor(GaugeGrid); | ||||||
|          |  | ||||||
|     for(int mu=0;mu<Nd;mu++){ |     //Here the first Nd-1 directions are treated as "spatial", and a twist value of 1 indicates G-parity BCs in that direction.  | ||||||
|            |     //mu=Nd-1 is assumed to be the time direction and a twist value of 1 indicates antiperiodic BCs         | ||||||
|       LatticeCoordinate(coor,mu); |     for(int mu=0;mu<Nd-1;mu++){ | ||||||
|  |  | ||||||
|  |       if( Params.twists[mu] ){ | ||||||
|  | 	LatticeCoordinate(coor,mu); | ||||||
|  |       } | ||||||
|            |            | ||||||
|       U     = PeekIndex<LorentzIndex>(Umu,mu); |       U     = PeekIndex<LorentzIndex>(Umu,mu); | ||||||
|       Uconj = conjugate(U); |       Uconj = conjugate(U); | ||||||
|       |       | ||||||
|  |       // Implement the isospin rotation sign on the boundary between f=1 and f=0 | ||||||
|       // This phase could come from a simple bc 1,1,-1,1 .. |       // This phase could come from a simple bc 1,1,-1,1 .. | ||||||
|       int neglink = GaugeGrid->GlobalDimensions()[mu]-1; |       int neglink = GaugeGrid->GlobalDimensions()[mu]-1; | ||||||
|       if ( Params.twists[mu] ) {  |       if ( Params.twists[mu] ) {  | ||||||
| @@ -241,7 +259,7 @@ public: | |||||||
| 	thread_foreach(ss,U_v,{ | 	thread_foreach(ss,U_v,{ | ||||||
| 	    Uds_v[ss](0)(mu) = U_v[ss](); | 	    Uds_v[ss](0)(mu) = U_v[ss](); | ||||||
| 	    Uds_v[ss](1)(mu) = Uconj_v[ss](); | 	    Uds_v[ss](1)(mu) = Uconj_v[ss](); | ||||||
| 	  }); | 	}); | ||||||
|       } |       } | ||||||
|            |            | ||||||
|       U     = adj(Cshift(U    ,mu,-1));      // correct except for spanning the boundary |       U     = adj(Cshift(U    ,mu,-1));      // correct except for spanning the boundary | ||||||
| @@ -272,6 +290,38 @@ public: | |||||||
|         }); |         }); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     { //periodic / antiperiodic temporal BCs | ||||||
|  |       int mu = Nd-1; | ||||||
|  |       int L   = GaugeGrid->GlobalDimensions()[mu]; | ||||||
|  |       int Lmu = L - 1; | ||||||
|  |  | ||||||
|  |       LatticeCoordinate(coor, mu); | ||||||
|  |  | ||||||
|  |       U = PeekIndex<LorentzIndex>(Umu, mu); //Get t-directed links | ||||||
|  |        | ||||||
|  |       GaugeLinkField *Upoke = &U; | ||||||
|  |  | ||||||
|  |       if(Params.twists[mu]){ //antiperiodic | ||||||
|  | 	Utmp =  where(coor == Lmu, -U, U); | ||||||
|  | 	Upoke = &Utmp; | ||||||
|  |       } | ||||||
|  |      | ||||||
|  |       Uconj = conjugate(*Upoke); //second flavor interacts with conjugate links       | ||||||
|  |       pokeGparityDoubledGaugeField(Uds, *Upoke, Uconj, mu); | ||||||
|  |  | ||||||
|  |       //Get the barrel-shifted field | ||||||
|  |       Utmp = adj(Cshift(U, mu, -1)); //is a forward shift! | ||||||
|  |       Upoke = &Utmp; | ||||||
|  |  | ||||||
|  |       if(Params.twists[mu]){ | ||||||
|  | 	U = where(coor == 0, -Utmp, Utmp);  //boundary phase | ||||||
|  | 	Upoke = &U; | ||||||
|  |       } | ||||||
|  |        | ||||||
|  |       Uconj = conjugate(*Upoke); | ||||||
|  |       pokeGparityDoubledGaugeField(Uds, *Upoke, Uconj, mu + 4); | ||||||
|  |     } | ||||||
|   } |   } | ||||||
|        |        | ||||||
|   inline void InsertForce4D(GaugeField &mat, FermionField &Btilde, FermionField &A, int mu) { |   inline void InsertForce4D(GaugeField &mat, FermionField &Btilde, FermionField &A, int mu) { | ||||||
| @@ -310,28 +360,48 @@ public: | |||||||
|   inline void extractLinkField(std::vector<GaugeLinkField> &mat, DoubledGaugeField &Uds){ |   inline void extractLinkField(std::vector<GaugeLinkField> &mat, DoubledGaugeField &Uds){ | ||||||
|     assert(0); |     assert(0); | ||||||
|   } |   } | ||||||
|    |   | ||||||
|   inline void InsertForce5D(GaugeField &mat, FermionField &Btilde, FermionField Ã, int mu) { |   inline void InsertForce5D(GaugeField &mat, FermionField &Btilde, FermionField Ã, int mu) { | ||||||
|  |     int Ls=Btilde.Grid()->_fdimensions[0]; | ||||||
|     int Ls = Btilde.Grid()->_fdimensions[0]; |      | ||||||
|          |  | ||||||
|     GaugeLinkField tmp(mat.Grid()); |  | ||||||
|     tmp = Zero(); |  | ||||||
|     { |     { | ||||||
|       autoView( tmp_v , tmp, CpuWrite); |       GridBase *GaugeGrid = mat.Grid(); | ||||||
|       autoView( Atilde_v , Atilde, CpuRead); |       Lattice<iScalar<vInteger> > coor(GaugeGrid); | ||||||
|       autoView( Btilde_v , Btilde, CpuRead); |  | ||||||
|       thread_for(ss,tmp.Grid()->oSites(),{ |       if( Params.twists[mu] ){ | ||||||
| 	  for (int s = 0; s < Ls; s++) { | 	LatticeCoordinate(coor,mu); | ||||||
| 	    int sF = s + Ls * ss; |       } | ||||||
| 	    auto ttmp = traceIndex<SpinIndex>(outerProduct(Btilde_v[sF], Atilde_v[sF])); |  | ||||||
| 	    tmp_v[ss]() = tmp_v[ss]() + ttmp(0, 0) + conjugate(ttmp(1, 1)); |       autoView( mat_v , mat, AcceleratorWrite); | ||||||
| 	  } |       autoView( Btilde_v , Btilde, AcceleratorRead); | ||||||
| 	}); |       autoView( Atilde_v , Atilde, AcceleratorRead); | ||||||
|  |       accelerator_for(sss,mat.Grid()->oSites(), FermionField::vector_type::Nsimd(),{	   | ||||||
|  |   	  int sU=sss; | ||||||
|  |   	  typedef decltype(coalescedRead(mat_v[sU](mu)() )) ColorMatrixType; | ||||||
|  |   	  ColorMatrixType sum; | ||||||
|  |   	  zeroit(sum); | ||||||
|  |   	  for(int s=0;s<Ls;s++){ | ||||||
|  |   	    int sF = s+Ls*sU; | ||||||
|  |   	    for(int spn=0;spn<Ns;spn++){ //sum over spin | ||||||
|  | 	      //Flavor 0 | ||||||
|  |   	      auto bb = coalescedRead(Btilde_v[sF](0)(spn) ); //color vector | ||||||
|  |   	      auto aa = coalescedRead(Atilde_v[sF](0)(spn) ); | ||||||
|  |   	      sum = sum + outerProduct(bb,aa); | ||||||
|  |  | ||||||
|  |   	      //Flavor 1 | ||||||
|  |   	      bb = coalescedRead(Btilde_v[sF](1)(spn) ); | ||||||
|  |   	      aa = coalescedRead(Atilde_v[sF](1)(spn) ); | ||||||
|  |   	      sum = sum + conjugate(outerProduct(bb,aa)); | ||||||
|  |   	    } | ||||||
|  |   	  }	     | ||||||
|  |   	  coalescedWrite(mat_v[sU](mu)(), sum); | ||||||
|  |   	}); | ||||||
|     } |     } | ||||||
|     PokeIndex<LorentzIndex>(mat, tmp, mu); |  | ||||||
|     return; |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |    | ||||||
|  |  | ||||||
|    |    | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @@ -339,8 +409,8 @@ typedef GparityWilsonImpl<vComplex , FundamentalRepresentation,CoeffReal> Gparit | |||||||
| typedef GparityWilsonImpl<vComplexF, FundamentalRepresentation,CoeffReal> GparityWilsonImplF;  // Float | typedef GparityWilsonImpl<vComplexF, FundamentalRepresentation,CoeffReal> GparityWilsonImplF;  // Float | ||||||
| typedef GparityWilsonImpl<vComplexD, FundamentalRepresentation,CoeffReal> GparityWilsonImplD;  // Double | typedef GparityWilsonImpl<vComplexD, FundamentalRepresentation,CoeffReal> GparityWilsonImplD;  // Double | ||||||
|   |   | ||||||
| typedef GparityWilsonImpl<vComplex , FundamentalRepresentation,CoeffRealHalfComms> GparityWilsonImplRL;  // Real.. whichever prec | //typedef GparityWilsonImpl<vComplex , FundamentalRepresentation,CoeffRealHalfComms> GparityWilsonImplRL;  // Real.. whichever prec | ||||||
| typedef GparityWilsonImpl<vComplexF, FundamentalRepresentation,CoeffRealHalfComms> GparityWilsonImplFH;  // Float | //typedef GparityWilsonImpl<vComplexF, FundamentalRepresentation,CoeffRealHalfComms> GparityWilsonImplFH;  // Float | ||||||
| typedef GparityWilsonImpl<vComplexD, FundamentalRepresentation,CoeffRealHalfComms> GparityWilsonImplDF;  // Double | //typedef GparityWilsonImpl<vComplexD, FundamentalRepresentation,CoeffRealHalfComms> GparityWilsonImplDF;  // Double | ||||||
|  |  | ||||||
| NAMESPACE_END(Grid); | NAMESPACE_END(Grid); | ||||||
|   | |||||||
| @@ -141,8 +141,11 @@ public: | |||||||
|   void ImportGauge(const GaugeField &_Uthin, const GaugeField &_Ufat); |   void ImportGauge(const GaugeField &_Uthin, const GaugeField &_Ufat); | ||||||
|   void ImportGaugeSimple(const GaugeField &_UUU    ,const GaugeField &_U); |   void ImportGaugeSimple(const GaugeField &_UUU    ,const GaugeField &_U); | ||||||
|   void ImportGaugeSimple(const DoubledGaugeField &_UUU,const DoubledGaugeField &_U); |   void ImportGaugeSimple(const DoubledGaugeField &_UUU,const DoubledGaugeField &_U); | ||||||
|   DoubledGaugeField &GetU(void)   { return Umu ; } ; |   virtual DoubledGaugeField &GetDoubledGaugeField(void)  override { return Umu; }; | ||||||
|   DoubledGaugeField &GetUUU(void) { return UUUmu; }; |   virtual DoubledGaugeField &GetDoubledGaugeFieldE(void) override { return UmuEven; }; | ||||||
|  |   virtual DoubledGaugeField &GetDoubledGaugeFieldO(void) override { return UmuOdd; }; | ||||||
|  |   virtual DoubledGaugeField &GetU(void)   { return Umu ; } ; | ||||||
|  |   virtual DoubledGaugeField &GetUUU(void) { return UUUmu; }; | ||||||
|   void CopyGaugeCheckerboards(void); |   void CopyGaugeCheckerboards(void); | ||||||
|  |  | ||||||
|   /////////////////////////////////////////////////////////////// |   /////////////////////////////////////////////////////////////// | ||||||
|   | |||||||
| @@ -160,17 +160,20 @@ public: | |||||||
| 			       RealD _c1=1.0, RealD _c2=1.0,RealD _u0=1.0, | 			       RealD _c1=1.0, RealD _c2=1.0,RealD _u0=1.0, | ||||||
| 			     const ImplParams &p= ImplParams()); | 			     const ImplParams &p= ImplParams()); | ||||||
|      |      | ||||||
|     // DoubleStore gauge field in operator |   // DoubleStore gauge field in operator | ||||||
|     void ImportGauge      (const GaugeField &_Uthin ) { assert(0); } |   void ImportGauge      (const GaugeField &_Uthin ) { assert(0); } | ||||||
|   void ImportGauge(const GaugeField &_Uthin,const GaugeField &_Ufat); |   void ImportGauge(const GaugeField &_Uthin,const GaugeField &_Ufat); | ||||||
|     void ImportGaugeSimple(const GaugeField &_UUU,const GaugeField &_U); |   void ImportGaugeSimple(const GaugeField &_UUU,const GaugeField &_U); | ||||||
|     void ImportGaugeSimple(const DoubledGaugeField &_UUU,const DoubledGaugeField &_U); |   void ImportGaugeSimple(const DoubledGaugeField &_UUU,const DoubledGaugeField &_U); | ||||||
|     // Give a reference; can be used to do an assignment or copy back out after import |   // Give a reference; can be used to do an assignment or copy back out after import | ||||||
|     // if Carleton wants to cache them and not use the ImportSimple |   // if Carleton wants to cache them and not use the ImportSimple | ||||||
|     DoubledGaugeField &GetU(void)   { return Umu ; } ; |   virtual DoubledGaugeField &GetDoubledGaugeField(void)  override { return Umu; }; | ||||||
|     DoubledGaugeField &GetUUU(void) { return UUUmu; }; |   virtual DoubledGaugeField &GetDoubledGaugeFieldE(void) override { return UmuEven; }; | ||||||
|     void CopyGaugeCheckerboards(void); |   virtual DoubledGaugeField &GetDoubledGaugeFieldO(void) override { return UmuOdd; }; | ||||||
|      |   DoubledGaugeField &GetU(void)   { return Umu ; } ; | ||||||
|  |   DoubledGaugeField &GetUUU(void) { return UUUmu; }; | ||||||
|  |   void CopyGaugeCheckerboards(void); | ||||||
|  |    | ||||||
|   /////////////////////////////////////////////////////////////// |   /////////////////////////////////////////////////////////////// | ||||||
|   // Data members require to support the functionality |   // Data members require to support the functionality | ||||||
|   /////////////////////////////////////////////////////////////// |   /////////////////////////////////////////////////////////////// | ||||||
|   | |||||||
| @@ -85,7 +85,7 @@ class MADWF | |||||||
|       maxiter     =_maxiter; |       maxiter     =_maxiter; | ||||||
|     }; |     }; | ||||||
|     |     | ||||||
|   void operator() (const FermionFieldo &src4,FermionFieldo &sol5) |   void operator() (const FermionFieldo &src,FermionFieldo &sol5) | ||||||
|   { |   { | ||||||
|     std::cout << GridLogMessage<< " ************************************************" << std::endl; |     std::cout << GridLogMessage<< " ************************************************" << std::endl; | ||||||
|     std::cout << GridLogMessage<< "  MADWF-like algorithm                           " << std::endl; |     std::cout << GridLogMessage<< "  MADWF-like algorithm                           " << std::endl; | ||||||
| @@ -114,8 +114,16 @@ class MADWF | |||||||
|     /////////////////////////////////////// |     /////////////////////////////////////// | ||||||
|     //Import source, include Dminus factors |     //Import source, include Dminus factors | ||||||
|     /////////////////////////////////////// |     /////////////////////////////////////// | ||||||
|     Mato.ImportPhysicalFermionSource(src4,b);  |     GridBase *src_grid = src.Grid(); | ||||||
|     std::cout << GridLogMessage << " src4 " <<norm2(src4)<<std::endl; |  | ||||||
|  |     assert( (src_grid == Mato.GaugeGrid()) || (src_grid == Mato.FermionGrid())); | ||||||
|  |  | ||||||
|  |     if ( src_grid == Mato.GaugeGrid() ) { | ||||||
|  |       Mato.ImportPhysicalFermionSource(src,b); | ||||||
|  |     } else { | ||||||
|  |       b=src; | ||||||
|  |     } | ||||||
|  |     std::cout << GridLogMessage << " src " <<norm2(src)<<std::endl; | ||||||
|     std::cout << GridLogMessage << " b    " <<norm2(b)<<std::endl; |     std::cout << GridLogMessage << " b    " <<norm2(b)<<std::endl; | ||||||
|  |  | ||||||
|     defect = b; |     defect = b; | ||||||
|   | |||||||
| @@ -135,6 +135,9 @@ public: | |||||||
|  |  | ||||||
|   // DoubleStore impl dependent |   // DoubleStore impl dependent | ||||||
|   void ImportGauge      (const GaugeField &_U ); |   void ImportGauge      (const GaugeField &_U ); | ||||||
|  |   DoubledGaugeField &GetDoubledGaugeField(void){ return Umu; }; | ||||||
|  |   DoubledGaugeField &GetDoubledGaugeFieldE(void){ return UmuEven; }; | ||||||
|  |   DoubledGaugeField &GetDoubledGaugeFieldO(void){ return UmuOdd; }; | ||||||
|   DoubledGaugeField &GetU(void)   { return Umu ; } ; |   DoubledGaugeField &GetU(void)   { return Umu ; } ; | ||||||
|   void CopyGaugeCheckerboards(void); |   void CopyGaugeCheckerboards(void); | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										534
									
								
								Grid/qcd/action/fermion/SchurFactoredFermionOperator.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										534
									
								
								Grid/qcd/action/fermion/SchurFactoredFermionOperator.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,534 @@ | |||||||
|  | /************************************************************************************* | ||||||
|  |  | ||||||
|  |     Grid physics library, www.github.com/paboyle/Grid  | ||||||
|  |  | ||||||
|  |     Source file: ./lib/qcd/action/fermion/SchurFactoredFermionOperator.h | ||||||
|  |  | ||||||
|  |     Copyright (C) 2021 | ||||||
|  |  | ||||||
|  | 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 */ | ||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include <Grid/qcd/utils/MixedPrecisionOperatorFunction.h> | ||||||
|  | #include <Grid/qcd/action/domains/Domains.h> | ||||||
|  |  | ||||||
|  | NAMESPACE_BEGIN(Grid); | ||||||
|  |  | ||||||
|  |   //////////////////////////////////////////////////////// | ||||||
|  |   // Some explanation of class structure for domain decomposition: | ||||||
|  |   // | ||||||
|  |   // Need a dirichlet operator for two flavour determinant - acts on both Omega and OmegaBar. | ||||||
|  |   // | ||||||
|  |   // Possible gain if the global sums and CG are run independently?? Could measure this. | ||||||
|  |   // | ||||||
|  |   // Types of operations | ||||||
|  |   // | ||||||
|  |   // 1) assemble local det dOmega det dOmegaBar pseudofermion | ||||||
|  |   // | ||||||
|  |   // - DirichletFermionOperator - can either do a global solve, or independent/per cell coefficients. | ||||||
|  |   // | ||||||
|  |   // 2) assemble dOmegaInverse and dOmegaBarInverse in R | ||||||
|  |   // | ||||||
|  |   // - DirichletFermionOperator - can also be used to  | ||||||
|  |   //                                       - need two or more cells per node. Options | ||||||
|  |   //                                       - a) solve one cell at a time, no new code, CopyRegion and reduced /split Grids | ||||||
|  |   //                                       - b) solve multiple cells in parallel. predicated dslash implementation | ||||||
|  |   // | ||||||
|  |   //                                       - b) has more parallelism, experience with block solver suggest might not be aalgorithmically inefficient | ||||||
|  |   //                                         a) has more cache friendly and easier code. | ||||||
|  |   //                                         b) is easy to implement in a "trial" or inefficient code with projection. | ||||||
|  |   // | ||||||
|  |   // 3)  Additional functionality for domain operations | ||||||
|  |   // | ||||||
|  |   // - SchurFactoredFermionOperator  - Need a DDHMC utility - whether used in two flavour or one flavour  | ||||||
|  |   // | ||||||
|  |   // - dBoundary - needs non-dirichlet operator | ||||||
|  |   // - Contains one Dirichlet Op, and one non-Dirichlet op. Implements dBoundary etc... | ||||||
|  |   // - The Dirichlet ops can be passed to dOmega(Bar) solvers etc... | ||||||
|  |   // | ||||||
|  |   //////////////////////////////////////////////////////// | ||||||
|  |  | ||||||
|  |  | ||||||
|  | template<class ImplD,class ImplF> | ||||||
|  | class SchurFactoredFermionOperator : public ImplD | ||||||
|  | { | ||||||
|  |   INHERIT_IMPL_TYPES(ImplD); | ||||||
|  |    | ||||||
|  |   typedef typename ImplF::FermionField FermionFieldF; | ||||||
|  |   typedef typename ImplD::FermionField FermionFieldD; | ||||||
|  |  | ||||||
|  |   typedef SchurDiagMooeeOperator<FermionOperator<ImplD>,FermionFieldD> LinearOperatorD; | ||||||
|  |   typedef SchurDiagMooeeOperator<FermionOperator<ImplF>,FermionFieldF> LinearOperatorF; | ||||||
|  |   typedef SchurDiagMooeeDagOperator<FermionOperator<ImplD>,FermionFieldD> LinearOperatorDagD; | ||||||
|  |   typedef SchurDiagMooeeDagOperator<FermionOperator<ImplF>,FermionFieldF> LinearOperatorDagF; | ||||||
|  |  | ||||||
|  |   typedef MixedPrecisionConjugateGradientOperatorFunction<FermionOperator<ImplD>, | ||||||
|  | 							  FermionOperator<ImplF>, | ||||||
|  | 							  LinearOperatorD, | ||||||
|  | 							  LinearOperatorF> MxPCG; | ||||||
|  |  | ||||||
|  |   typedef MixedPrecisionConjugateGradientOperatorFunction<FermionOperator<ImplD>, | ||||||
|  | 							  FermionOperator<ImplF>, | ||||||
|  | 							  LinearOperatorDagD, | ||||||
|  | 							  LinearOperatorDagF> MxDagPCG; | ||||||
|  | public: | ||||||
|  |  | ||||||
|  |   GridBase *FermionGrid(void) { return PeriodicFermOpD.FermionGrid(); }; | ||||||
|  |   GridBase *GaugeGrid(void)   { return PeriodicFermOpD.GaugeGrid(); }; | ||||||
|  |    | ||||||
|  |   FermionOperator<ImplD> & DirichletFermOpD; | ||||||
|  |   FermionOperator<ImplF> & DirichletFermOpF; | ||||||
|  |   FermionOperator<ImplD> & PeriodicFermOpD;  | ||||||
|  |   FermionOperator<ImplF> & PeriodicFermOpF;  | ||||||
|  |  | ||||||
|  |   LinearOperatorD DirichletLinOpD; | ||||||
|  |   LinearOperatorF DirichletLinOpF; | ||||||
|  |   LinearOperatorD PeriodicLinOpD; | ||||||
|  |   LinearOperatorF PeriodicLinOpF; | ||||||
|  |  | ||||||
|  |   LinearOperatorDagD DirichletLinOpDagD; | ||||||
|  |   LinearOperatorDagF DirichletLinOpDagF; | ||||||
|  |   LinearOperatorDagD PeriodicLinOpDagD; | ||||||
|  |   LinearOperatorDagF PeriodicLinOpDagF; | ||||||
|  |  | ||||||
|  |   // Can tinker with these in the pseudofermion for force vs. action solves | ||||||
|  |   Integer maxinnerit; | ||||||
|  |   Integer maxouterit; | ||||||
|  |   RealD tol; | ||||||
|  |   RealD tolinner; | ||||||
|  |    | ||||||
|  |   Coordinate Block; | ||||||
|  |  | ||||||
|  |   DomainDecomposition Domains; | ||||||
|  |  | ||||||
|  |   SchurFactoredFermionOperator(FermionOperator<ImplD>  & _PeriodicFermOpD, | ||||||
|  | 			       FermionOperator<ImplF>  & _PeriodicFermOpF, | ||||||
|  | 			       FermionOperator<ImplD>  & _DirichletFermOpD, | ||||||
|  | 			       FermionOperator<ImplF>  & _DirichletFermOpF, | ||||||
|  | 			       Coordinate &_Block) | ||||||
|  |     : Block(_Block), Domains(Block), | ||||||
|  |  | ||||||
|  |       PeriodicFermOpD(_PeriodicFermOpD), | ||||||
|  |       PeriodicFermOpF(_PeriodicFermOpF), | ||||||
|  |       DirichletFermOpD(_DirichletFermOpD), | ||||||
|  |       DirichletFermOpF(_DirichletFermOpF), | ||||||
|  |       DirichletLinOpD(DirichletFermOpD), | ||||||
|  |       DirichletLinOpF(DirichletFermOpF), | ||||||
|  |       PeriodicLinOpD(PeriodicFermOpD), | ||||||
|  |       PeriodicLinOpF(PeriodicFermOpF), | ||||||
|  |       DirichletLinOpDagD(DirichletFermOpD), | ||||||
|  |       DirichletLinOpDagF(DirichletFermOpF), | ||||||
|  |       PeriodicLinOpDagD(PeriodicFermOpD), | ||||||
|  |       PeriodicLinOpDagF(PeriodicFermOpF) | ||||||
|  |   { | ||||||
|  |     tol=1.0e-10; | ||||||
|  |     tolinner=1.0e-6; | ||||||
|  |     maxinnerit=1000; | ||||||
|  |     maxouterit=10; | ||||||
|  |     assert(PeriodicFermOpD.FermionGrid() == DirichletFermOpD.FermionGrid()); | ||||||
|  |     assert(PeriodicFermOpF.FermionGrid() == DirichletFermOpF.FermionGrid()); | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   enum Domain { Omega=0, OmegaBar=1 }; | ||||||
|  |  | ||||||
|  |   void ImportGauge(const GaugeField &Umu) | ||||||
|  |   { | ||||||
|  |     // Single precision will update in the mixed prec CG | ||||||
|  |     PeriodicFermOpD.ImportGauge(Umu); | ||||||
|  |     GaugeField dUmu(Umu.Grid()); | ||||||
|  |     dUmu=Umu; | ||||||
|  |     //    DirchletBCs(dUmu); | ||||||
|  |     DirichletFilter<GaugeField> Filter(Block); | ||||||
|  |     Filter.applyFilter(dUmu); | ||||||
|  |     DirichletFermOpD.ImportGauge(dUmu); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |   void ProjectBoundaryBothDomains (FermionField &f,int sgn) | ||||||
|  |   { | ||||||
|  |     assert((sgn==1)||(sgn==-1)); | ||||||
|  |     Real rsgn = sgn; | ||||||
|  |  | ||||||
|  |     Gamma::Algebra Gmu [] = { | ||||||
|  |       Gamma::Algebra::GammaX, | ||||||
|  |       Gamma::Algebra::GammaY, | ||||||
|  |       Gamma::Algebra::GammaZ, | ||||||
|  |       Gamma::Algebra::GammaT | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     GridBase *grid = f.Grid(); | ||||||
|  |     LatticeInteger  coor(grid); | ||||||
|  |     LatticeInteger  face(grid); | ||||||
|  |     LatticeInteger  one(grid); one = 1; | ||||||
|  |     LatticeInteger  zero(grid); zero = 0; | ||||||
|  |     LatticeInteger nface(grid); nface=Zero(); | ||||||
|  |      | ||||||
|  |     FermionField projected(grid); projected=Zero(); | ||||||
|  |     FermionField sp_proj  (grid); | ||||||
|  |  | ||||||
|  |     int dims = grid->Nd(); | ||||||
|  |     int isDWF= (dims==Nd+1); | ||||||
|  |     assert((dims==Nd)||(dims==Nd+1)); | ||||||
|  |     Coordinate Global=grid->GlobalDimensions(); | ||||||
|  |  | ||||||
|  |     for(int mu=0;mu<Nd;mu++){ | ||||||
|  |  | ||||||
|  |       if ( Block[mu] <= Global[mu+isDWF] ) { | ||||||
|  | 	// need to worry about DWF 5th dim first | ||||||
|  | 	LatticeCoordinate(coor,mu+isDWF);  | ||||||
|  |        | ||||||
|  | 	face = where(mod(coor,Block[mu]) == Integer(0),one,zero ); | ||||||
|  | 	nface = nface + face; | ||||||
|  |  | ||||||
|  | 	Gamma G(Gmu[mu]); | ||||||
|  | 	// Lower face receives (1-gamma)/2 in normal forward hopping term | ||||||
|  | 	sp_proj  = 0.5*(f-G*f*rsgn); | ||||||
|  | 	projected= where(face,sp_proj,projected); | ||||||
|  | 	//projected= where(face,f,projected); | ||||||
|  |        | ||||||
|  | 	face = where(mod(coor,Block[mu]) == Integer(Block[mu]-1) ,one,zero ); | ||||||
|  | 	nface = nface + face; | ||||||
|  |  | ||||||
|  | 	// Upper face receives (1+gamma)/2 in normal backward hopping term | ||||||
|  | 	sp_proj = 0.5*(f+G*f*rsgn); | ||||||
|  | 	projected= where(face,sp_proj,projected); | ||||||
|  | 	//projected= where(face,f,projected); | ||||||
|  |       } | ||||||
|  |        | ||||||
|  |     } | ||||||
|  |     // Initial Zero() where nface==0. | ||||||
|  |     // Keep the spin projected faces where nface==1 | ||||||
|  |     // Full spinor where nface>=2 | ||||||
|  |     projected = where(nface>Integer(1),f,projected); | ||||||
|  |     f=projected; | ||||||
|  |   } | ||||||
|  | */ | ||||||
|  |   void ProjectBoundaryBothDomains (FermionField &f,int sgn) | ||||||
|  |   { | ||||||
|  |     assert((sgn==1)||(sgn==-1)); | ||||||
|  |     Real rsgn = sgn; | ||||||
|  |  | ||||||
|  |     Gamma::Algebra Gmu [] = { | ||||||
|  |       Gamma::Algebra::GammaX, | ||||||
|  |       Gamma::Algebra::GammaY, | ||||||
|  |       Gamma::Algebra::GammaZ, | ||||||
|  |       Gamma::Algebra::GammaT | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     GridBase *grid = f.Grid(); | ||||||
|  |     LatticeInteger  coor(grid); | ||||||
|  |     LatticeInteger  face(grid); | ||||||
|  |     LatticeInteger  one(grid);   one = 1; | ||||||
|  |     LatticeInteger  zero(grid); zero = 0; | ||||||
|  |     LatticeInteger  omega(grid); | ||||||
|  |     LatticeInteger  omegabar(grid); | ||||||
|  |     LatticeInteger  tmp(grid); | ||||||
|  |  | ||||||
|  |     omega=one;    Domains.ProjectDomain(omega,0); | ||||||
|  |     omegabar=one; Domains.ProjectDomain(omegabar,1); | ||||||
|  |      | ||||||
|  |     LatticeInteger nface(grid); nface=Zero(); | ||||||
|  |      | ||||||
|  |     FermionField projected(grid); projected=Zero(); | ||||||
|  |     FermionField sp_proj  (grid); | ||||||
|  |  | ||||||
|  |     int dims = grid->Nd(); | ||||||
|  |     int isDWF= (dims==Nd+1); | ||||||
|  |     assert((dims==Nd)||(dims==Nd+1)); | ||||||
|  |     Coordinate Global=grid->GlobalDimensions(); | ||||||
|  |  | ||||||
|  |     for(int mmu=0;mmu<Nd;mmu++){ | ||||||
|  |       Gamma G(Gmu[mmu]); | ||||||
|  |  | ||||||
|  |       // need to worry about DWF 5th dim first | ||||||
|  |       int mu = mmu+isDWF; | ||||||
|  |       if ( Block[mmu] && (Block[mmu] <= Global[mu]) ) { | ||||||
|  |  | ||||||
|  | 	// Lower face receives (1-gamma)/2 in normal forward hopping term | ||||||
|  |  	tmp = Cshift(omegabar,mu,-1); | ||||||
|  | 	tmp = tmp + omega; | ||||||
|  | 	face = where(tmp == Integer(2),one,zero ); | ||||||
|  |  | ||||||
|  |  	tmp = Cshift(omega,mu,-1); | ||||||
|  | 	tmp = tmp + omegabar; | ||||||
|  | 	face = where(tmp == Integer(2),one,face ); | ||||||
|  |  | ||||||
|  | 	nface = nface + face; | ||||||
|  |  | ||||||
|  | 	sp_proj  = 0.5*(f-G*f*rsgn); | ||||||
|  | 	projected= where(face,sp_proj,projected); | ||||||
|  |  | ||||||
|  | 	// Upper face receives (1+gamma)/2 in normal backward hopping term | ||||||
|  |  	tmp = Cshift(omegabar,mu,1); | ||||||
|  | 	tmp = tmp + omega; | ||||||
|  | 	face = where(tmp == Integer(2),one,zero ); | ||||||
|  |  | ||||||
|  |  	tmp = Cshift(omega,mu,1); | ||||||
|  | 	tmp = tmp + omegabar; | ||||||
|  | 	face = where(tmp == Integer(2),one,face ); | ||||||
|  |  | ||||||
|  | 	nface = nface + face; | ||||||
|  |  | ||||||
|  | 	sp_proj = 0.5*(f+G*f*rsgn); | ||||||
|  | 	projected= where(face,sp_proj,projected); | ||||||
|  |       } | ||||||
|  |        | ||||||
|  |     } | ||||||
|  |     // Initial Zero() where nface==0. | ||||||
|  |     // Keep the spin projected faces where nface==1 | ||||||
|  |     // Full spinor where nface>=2 | ||||||
|  |     projected = where(nface>Integer(1),f,projected); | ||||||
|  |     f=projected; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void ProjectDomain(FermionField &f,int domain) | ||||||
|  |   { | ||||||
|  | /* | ||||||
|  |     GridBase *grid = f.Grid(); | ||||||
|  |     int dims = grid->Nd(); | ||||||
|  |     int isDWF= (dims==Nd+1); | ||||||
|  |     assert((dims==Nd)||(dims==Nd+1)); | ||||||
|  |  | ||||||
|  |     FermionField zz(grid); zz=Zero(); | ||||||
|  |     LatticeInteger coor(grid); | ||||||
|  |     LatticeInteger domaincb(grid); domaincb=Zero(); | ||||||
|  |     for(int d=0;d<Nd;d++){ | ||||||
|  |       LatticeCoordinate(coor,d+isDWF); | ||||||
|  |       domaincb = domaincb + div(coor,Block[d]); | ||||||
|  |     } | ||||||
|  |     f = where(mod(domaincb,2)==Integer(domain),f,zz); | ||||||
|  | */ | ||||||
|  |     Domains.ProjectDomain(f,domain); | ||||||
|  |  | ||||||
|  |   }; | ||||||
|  |   void ProjectOmegaBar   (FermionField &f) {ProjectDomain(f,OmegaBar);} | ||||||
|  |   void ProjectOmega      (FermionField &f) {ProjectDomain(f,Omega);} | ||||||
|  |   // See my notes(!). | ||||||
|  |   // Notation: Following Luscher, we introduce projectors $\hPdb$ with both spinor and space structure | ||||||
|  |   // projecting all spinor elements in $\Omega$ connected by $\Ddb$ to $\bar{\Omega}$, | ||||||
|  |   void ProjectBoundaryBar(FermionField &f) | ||||||
|  |   { | ||||||
|  |     ProjectBoundaryBothDomains(f,1); | ||||||
|  |     ProjectOmega(f); | ||||||
|  |   } | ||||||
|  |   // and $\hPd$ projecting all spinor elements in $\bar{\Omega}$ connected by $\Dd$ to $\Omega$. | ||||||
|  |   void ProjectBoundary   (FermionField &f) | ||||||
|  |   { | ||||||
|  |     ProjectBoundaryBothDomains(f,1); | ||||||
|  |     ProjectOmegaBar(f); | ||||||
|  |     //    DumpSliceNorm("ProjectBoundary",f,f.Grid()->Nd()-1); | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   void dBoundary    (FermionField &in,FermionField &out) | ||||||
|  |   { | ||||||
|  |     FermionField tmp(in); | ||||||
|  |     ProjectOmegaBar(tmp); | ||||||
|  |     PeriodicFermOpD.M(tmp,out); | ||||||
|  |     ProjectOmega(out); | ||||||
|  |   }; | ||||||
|  |   void dBoundaryDag (FermionField &in,FermionField &out) | ||||||
|  |   { | ||||||
|  |     FermionField tmp(in); | ||||||
|  |     ProjectOmega(tmp); | ||||||
|  |     PeriodicFermOpD.Mdag(tmp,out); | ||||||
|  |     ProjectOmegaBar(out); | ||||||
|  |   }; | ||||||
|  |   void dBoundaryBar (FermionField &in,FermionField &out) | ||||||
|  |   { | ||||||
|  |     FermionField tmp(in); | ||||||
|  |     ProjectOmega(tmp); | ||||||
|  |     PeriodicFermOpD.M(tmp,out); | ||||||
|  |     ProjectOmegaBar(out); | ||||||
|  |   }; | ||||||
|  |   void dBoundaryBarDag (FermionField &in,FermionField &out) | ||||||
|  |   { | ||||||
|  |     FermionField tmp(in); | ||||||
|  |     ProjectOmegaBar(tmp); | ||||||
|  |     PeriodicFermOpD.Mdag(tmp,out); | ||||||
|  |     ProjectOmega(out); | ||||||
|  |   }; | ||||||
|  |   void dOmega       (FermionField &in,FermionField &out) | ||||||
|  |   { | ||||||
|  |     FermionField tmp(in); | ||||||
|  |     ProjectOmega(tmp); | ||||||
|  |     DirichletFermOpD.M(tmp,out); | ||||||
|  |     ProjectOmega(out); | ||||||
|  |   }; | ||||||
|  |   void dOmegaBar    (FermionField &in,FermionField &out) | ||||||
|  |   { | ||||||
|  |     FermionField tmp(in); | ||||||
|  |     ProjectOmegaBar(tmp); | ||||||
|  |     DirichletFermOpD.M(tmp,out); | ||||||
|  |     ProjectOmegaBar(out); | ||||||
|  |   }; | ||||||
|  |   void dOmegaDag       (FermionField &in,FermionField &out) | ||||||
|  |   { | ||||||
|  |     FermionField tmp(in); | ||||||
|  |     ProjectOmega(tmp); | ||||||
|  |     DirichletFermOpD.Mdag(tmp,out); | ||||||
|  |     ProjectOmega(out); | ||||||
|  |   }; | ||||||
|  |   void dOmegaBarDag    (FermionField &in,FermionField &out) | ||||||
|  |   { | ||||||
|  |     FermionField tmp(in); | ||||||
|  |     ProjectOmegaBar(tmp); | ||||||
|  |     DirichletFermOpD.Mdag(tmp,out); | ||||||
|  |     ProjectOmegaBar(out); | ||||||
|  |   }; | ||||||
|  |   void dOmegaInv   (FermionField &in,FermionField &out) | ||||||
|  |   { | ||||||
|  |     FermionField tmp(in); | ||||||
|  |     ProjectOmega(tmp); | ||||||
|  |     dOmegaInvAndOmegaBarInv(tmp,out); // Inefficient warning | ||||||
|  |     ProjectOmega(out); | ||||||
|  |   }; | ||||||
|  |   void dOmegaBarInv(FermionField &in,FermionField &out) | ||||||
|  |   {     | ||||||
|  |     FermionField tmp(in); | ||||||
|  |     ProjectOmegaBar(tmp); | ||||||
|  |     dOmegaInvAndOmegaBarInv(tmp,out); | ||||||
|  |     ProjectOmegaBar(out); | ||||||
|  |   }; | ||||||
|  |   void dOmegaDagInv   (FermionField &in,FermionField &out) | ||||||
|  |   { | ||||||
|  |     FermionField tmp(in); | ||||||
|  |     ProjectOmega(tmp); | ||||||
|  |     dOmegaDagInvAndOmegaBarDagInv(tmp,out); | ||||||
|  |     ProjectOmega(out); | ||||||
|  |   }; | ||||||
|  |   void dOmegaBarDagInv(FermionField &in,FermionField &out) | ||||||
|  |   {     | ||||||
|  |     FermionField tmp(in); | ||||||
|  |     ProjectOmegaBar(tmp); | ||||||
|  |     dOmegaDagInvAndOmegaBarDagInv(tmp,out); | ||||||
|  |     ProjectOmegaBar(out); | ||||||
|  |   }; | ||||||
|  |   void dOmegaInvAndOmegaBarInv(FermionField &in,FermionField &out) | ||||||
|  |   { | ||||||
|  |     MxPCG OmegaSolver(tol, | ||||||
|  | 		      tolinner, | ||||||
|  | 		      maxinnerit, | ||||||
|  | 		      maxouterit, | ||||||
|  | 		      DirichletFermOpF.FermionRedBlackGrid(), | ||||||
|  | 		      DirichletFermOpF, | ||||||
|  | 		      DirichletFermOpD, | ||||||
|  | 		      DirichletLinOpF, | ||||||
|  | 		      DirichletLinOpD); | ||||||
|  |     SchurRedBlackDiagMooeeSolve<FermionField> PrecSolve(OmegaSolver); | ||||||
|  |     PrecSolve(DirichletFermOpD,in,out); | ||||||
|  |   }; | ||||||
|  |   void dOmegaDagInvAndOmegaBarDagInv(FermionField &in,FermionField &out) | ||||||
|  |   { | ||||||
|  |     MxDagPCG OmegaDagSolver(tol, | ||||||
|  | 			    tolinner, | ||||||
|  | 			    maxinnerit, | ||||||
|  | 			    maxouterit, | ||||||
|  | 			    DirichletFermOpF.FermionRedBlackGrid(), | ||||||
|  | 			    DirichletFermOpF, | ||||||
|  | 			    DirichletFermOpD, | ||||||
|  | 			    DirichletLinOpDagF, | ||||||
|  | 			    DirichletLinOpDagD); | ||||||
|  |     SchurRedBlackDiagMooeeDagSolve<FermionField> PrecSolve(OmegaDagSolver); | ||||||
|  |     PrecSolve(DirichletFermOpD,in,out); | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   // Rdag = Pdbar - DdbarDag DomegabarDagInv  DdDag DomegaDagInv Pdbar  | ||||||
|  |   void RDag(FermionField &in,FermionField &out) | ||||||
|  |   { | ||||||
|  |     FermionField tmp1(PeriodicFermOpD.FermionGrid()); | ||||||
|  |     FermionField tmp2(PeriodicFermOpD.FermionGrid()); | ||||||
|  |     out = in; | ||||||
|  |     ProjectBoundaryBar(out); | ||||||
|  |     dOmegaDagInv(out,tmp1);    | ||||||
|  |     dBoundaryDag(tmp1,tmp2);    | ||||||
|  |     dOmegaBarDagInv(tmp2,tmp1); | ||||||
|  |     dBoundaryBarDag(tmp1,tmp2);  | ||||||
|  |     out = out - tmp2; | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   // R = Pdbar - Pdbar DomegaInv Dd DomegabarInv Ddbar | ||||||
|  |   void R(FermionField &in,FermionField &out) | ||||||
|  |   { | ||||||
|  |     FermionField tmp1(PeriodicFermOpD.FermionGrid()); | ||||||
|  |     FermionField tmp2(PeriodicFermOpD.FermionGrid()); | ||||||
|  |     out = in; | ||||||
|  |     ProjectBoundaryBar(out); | ||||||
|  |     dBoundaryBar(out,tmp1);  | ||||||
|  |     dOmegaBarInv(tmp1,tmp2); | ||||||
|  |     dBoundary(tmp2,tmp1);    | ||||||
|  |     dOmegaInv(tmp1,tmp2);    | ||||||
|  |     out = in - tmp2 ;        | ||||||
|  |     ProjectBoundaryBar(out); | ||||||
|  |     //    DumpSliceNorm("R",out,out.Grid()->Nd()-1); | ||||||
|  |   }; | ||||||
|  |    | ||||||
|  |   // R = Pdbar - Pdbar Dinv Ddbar  | ||||||
|  |   void RInv(FermionField &in,FermionField &out) | ||||||
|  |   { | ||||||
|  |     FermionField tmp1(PeriodicFermOpD.FermionGrid()); | ||||||
|  |     dBoundaryBar(in,out); | ||||||
|  |     Dinverse(out,tmp1);   | ||||||
|  |     out =in -tmp1;  | ||||||
|  |     ProjectBoundaryBar(out); | ||||||
|  |   }; | ||||||
|  |   // R = Pdbar - DdbarDag DinvDag Pdbar  | ||||||
|  |   void RDagInv(FermionField &in,FermionField &out) | ||||||
|  |   { | ||||||
|  |     FermionField tmp(PeriodicFermOpD.FermionGrid()); | ||||||
|  |     FermionField Pin(PeriodicFermOpD.FermionGrid()); | ||||||
|  |     Pin = in; ProjectBoundaryBar(Pin); | ||||||
|  |     DinverseDag(Pin,out);   | ||||||
|  |     dBoundaryBarDag(out,tmp); | ||||||
|  |     out =Pin -tmp;  | ||||||
|  |   }; | ||||||
|  |   // Non-dirichlet inverter using red-black preconditioning | ||||||
|  |   void Dinverse(FermionField &in,FermionField &out) | ||||||
|  |   { | ||||||
|  |     MxPCG DSolver(tol, | ||||||
|  | 		  tolinner, | ||||||
|  | 		  maxinnerit, | ||||||
|  | 		  maxouterit, | ||||||
|  | 		  PeriodicFermOpF.FermionRedBlackGrid(), | ||||||
|  | 		  PeriodicFermOpF, | ||||||
|  | 		  PeriodicFermOpD, | ||||||
|  | 		  PeriodicLinOpF, | ||||||
|  | 		  PeriodicLinOpD); | ||||||
|  |     SchurRedBlackDiagMooeeSolve<FermionField> Solve(DSolver); | ||||||
|  |     Solve(PeriodicFermOpD,in,out); | ||||||
|  |   } | ||||||
|  |   void DinverseDag(FermionField &in,FermionField &out) | ||||||
|  |   { | ||||||
|  |     MxDagPCG DdagSolver(tol, | ||||||
|  | 			tolinner, | ||||||
|  | 			maxinnerit, | ||||||
|  | 			maxouterit, | ||||||
|  | 			PeriodicFermOpF.FermionRedBlackGrid(), | ||||||
|  | 			PeriodicFermOpF, | ||||||
|  | 			PeriodicFermOpD, | ||||||
|  | 			PeriodicLinOpDagF, | ||||||
|  | 			PeriodicLinOpDagD); | ||||||
|  |     SchurRedBlackDiagMooeeDagSolve<FermionField> Solve(DdagSolver); | ||||||
|  |     Solve(PeriodicFermOpD,in,out); | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | NAMESPACE_END(Grid); | ||||||
|  |  | ||||||
| @@ -72,19 +72,23 @@ public: | |||||||
|      |      | ||||||
|   StaggeredImpl(const ImplParams &p = ImplParams()) : Params(p){}; |   StaggeredImpl(const ImplParams &p = ImplParams()) : Params(p){}; | ||||||
|        |        | ||||||
|   static accelerator_inline void multLink(SiteSpinor &phi, |   template<class _Spinor> | ||||||
|  |   static accelerator_inline void multLink(_Spinor &phi, | ||||||
| 		       const SiteDoubledGaugeField &U, | 		       const SiteDoubledGaugeField &U, | ||||||
| 		       const SiteSpinor &chi, | 		       const _Spinor &chi, | ||||||
| 		       int mu) | 		       int mu) | ||||||
|   { |   { | ||||||
|     mult(&phi(), &U(mu), &chi()); |     auto UU = coalescedRead(U(mu)); | ||||||
|  |     mult(&phi(), &UU, &chi()); | ||||||
|   } |   } | ||||||
|   static accelerator_inline void multLinkAdd(SiteSpinor &phi, |   template<class _Spinor> | ||||||
|  |   static accelerator_inline void multLinkAdd(_Spinor &phi, | ||||||
| 			  const SiteDoubledGaugeField &U, | 			  const SiteDoubledGaugeField &U, | ||||||
| 			  const SiteSpinor &chi, | 			  const _Spinor &chi, | ||||||
| 			  int mu) | 			  int mu) | ||||||
|   { |   { | ||||||
|     mac(&phi(), &U(mu), &chi()); |     auto UU = coalescedRead(U(mu)); | ||||||
|  |     mac(&phi(), &UU, &chi()); | ||||||
|   } |   } | ||||||
|        |        | ||||||
|   template <class ref> |   template <class ref> | ||||||
|   | |||||||
| @@ -245,7 +245,7 @@ public: | |||||||
|     return out; |     return out; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| private: | protected: | ||||||
|   // here fixing the 4 dimensions, make it more general? |   // here fixing the 4 dimensions, make it more general? | ||||||
|  |  | ||||||
|   RealD csw_r;                                               // Clover coefficient - spatial |   RealD csw_r;                                               // Clover coefficient - spatial | ||||||
|   | |||||||
| @@ -61,18 +61,19 @@ public: | |||||||
|   typedef typename SiteHalfSpinor::vector_type     vComplexHigh; |   typedef typename SiteHalfSpinor::vector_type     vComplexHigh; | ||||||
|   constexpr static int Nw=sizeof(SiteHalfSpinor)/sizeof(vComplexHigh); |   constexpr static int Nw=sizeof(SiteHalfSpinor)/sizeof(vComplexHigh); | ||||||
|  |  | ||||||
|   accelerator_inline int CommDatumSize(void) { |   accelerator_inline int CommDatumSize(void) const { | ||||||
|     return sizeof(SiteHalfCommSpinor); |     return sizeof(SiteHalfCommSpinor); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /*****************************************************/ |   /*****************************************************/ | ||||||
|   /* Compress includes precision change if mpi data is not same */ |   /* Compress includes precision change if mpi data is not same */ | ||||||
|   /*****************************************************/ |   /*****************************************************/ | ||||||
|   template<class _SiteHalfSpinor, class _SiteSpinor> |   accelerator_inline void Compress(SiteHalfSpinor &buf,const SiteSpinor &in) const { | ||||||
|   accelerator_inline void Compress(_SiteHalfSpinor *buf,Integer o,const _SiteSpinor &in) { |     typedef decltype(coalescedRead(buf)) sobj; | ||||||
|     _SiteHalfSpinor tmp; |     sobj sp; | ||||||
|     projector::Proj(tmp,in,mu,dag); |     auto sin = coalescedRead(in); | ||||||
|     vstream(buf[o],tmp); |     projector::Proj(sp,sin,mu,dag); | ||||||
|  |     coalescedWrite(buf,sp); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /*****************************************************/ |   /*****************************************************/ | ||||||
| @@ -81,19 +82,24 @@ public: | |||||||
|   accelerator_inline void Exchange(SiteHalfSpinor *mp, |   accelerator_inline void Exchange(SiteHalfSpinor *mp, | ||||||
| 				   const SiteHalfSpinor * __restrict__ vp0, | 				   const SiteHalfSpinor * __restrict__ vp0, | ||||||
| 				   const SiteHalfSpinor * __restrict__ vp1, | 				   const SiteHalfSpinor * __restrict__ vp1, | ||||||
| 				   Integer type,Integer o){ | 				   Integer type,Integer o) const { | ||||||
|  | #ifdef GRID_SIMT | ||||||
|  |     exchangeSIMT(mp[2*o],mp[2*o+1],vp0[o],vp1[o],type); | ||||||
|  | #else | ||||||
|     SiteHalfSpinor tmp1; |     SiteHalfSpinor tmp1; | ||||||
|     SiteHalfSpinor tmp2; |     SiteHalfSpinor tmp2; | ||||||
|     exchange(tmp1,tmp2,vp0[o],vp1[o],type); |     exchange(tmp1,tmp2,vp0[o],vp1[o],type); | ||||||
|     vstream(mp[2*o  ],tmp1); |     vstream(mp[2*o  ],tmp1); | ||||||
|     vstream(mp[2*o+1],tmp2); |     vstream(mp[2*o+1],tmp2); | ||||||
|  | #endif | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|   /*****************************************************/ |   /*****************************************************/ | ||||||
|   /* Have a decompression step if mpi data is not same */ |   /* Have a decompression step if mpi data is not same */ | ||||||
|   /*****************************************************/ |   /*****************************************************/ | ||||||
|   accelerator_inline void Decompress(SiteHalfSpinor * __restrict__ out, |   accelerator_inline void Decompress(SiteHalfSpinor * __restrict__ out, | ||||||
| 				     SiteHalfSpinor * __restrict__ in, Integer o) {     | 				     SiteHalfSpinor * __restrict__ in, Integer o) const {     | ||||||
|     assert(0); |     assert(0); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -103,8 +109,30 @@ public: | |||||||
|   accelerator_inline void CompressExchange(SiteHalfSpinor * __restrict__ out0, |   accelerator_inline void CompressExchange(SiteHalfSpinor * __restrict__ out0, | ||||||
| 					   SiteHalfSpinor * __restrict__ out1, | 					   SiteHalfSpinor * __restrict__ out1, | ||||||
| 					   const SiteSpinor * __restrict__ in, | 					   const SiteSpinor * __restrict__ in, | ||||||
| 					   Integer j,Integer k, Integer m,Integer type) | 					   Integer j,Integer k, Integer m,Integer type) const | ||||||
|   { |   { | ||||||
|  | #ifdef GRID_SIMT | ||||||
|  |     typedef SiteSpinor vobj; | ||||||
|  |     typedef SiteHalfSpinor hvobj; | ||||||
|  |     typedef decltype(coalescedRead(*in))    sobj; | ||||||
|  |     typedef decltype(coalescedRead(*out0)) hsobj; | ||||||
|  |  | ||||||
|  |     unsigned int Nsimd = vobj::Nsimd(); | ||||||
|  |     unsigned int mask = Nsimd >> (type + 1); | ||||||
|  |     int lane = acceleratorSIMTlane(Nsimd); | ||||||
|  |     int j0 = lane &(~mask); // inner coor zero | ||||||
|  |     int j1 = lane |(mask) ; // inner coor one | ||||||
|  |     const vobj *vp0 = &in[k]; | ||||||
|  |     const vobj *vp1 = &in[m]; | ||||||
|  |     const vobj *vp = (lane&mask) ? vp1:vp0; | ||||||
|  |     auto sa = coalescedRead(*vp,j0); | ||||||
|  |     auto sb = coalescedRead(*vp,j1); | ||||||
|  |     hsobj psa, psb; | ||||||
|  |     projector::Proj(psa,sa,mu,dag); | ||||||
|  |     projector::Proj(psb,sb,mu,dag); | ||||||
|  |     coalescedWrite(out0[j],psa); | ||||||
|  |     coalescedWrite(out1[j],psb); | ||||||
|  | #else | ||||||
|     SiteHalfSpinor temp1, temp2; |     SiteHalfSpinor temp1, temp2; | ||||||
|     SiteHalfSpinor temp3, temp4; |     SiteHalfSpinor temp3, temp4; | ||||||
|     projector::Proj(temp1,in[k],mu,dag); |     projector::Proj(temp1,in[k],mu,dag); | ||||||
| @@ -112,15 +140,17 @@ public: | |||||||
|     exchange(temp3,temp4,temp1,temp2,type); |     exchange(temp3,temp4,temp1,temp2,type); | ||||||
|     vstream(out0[j],temp3); |     vstream(out0[j],temp3); | ||||||
|     vstream(out1[j],temp4); |     vstream(out1[j],temp4); | ||||||
|  | #endif | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /*****************************************************/ |   /*****************************************************/ | ||||||
|   /* Pass the info to the stencil */ |   /* Pass the info to the stencil */ | ||||||
|   /*****************************************************/ |   /*****************************************************/ | ||||||
|   accelerator_inline bool DecompressionStep(void) { return false; } |   accelerator_inline bool DecompressionStep(void) const { return false; } | ||||||
|  |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | #if 0 | ||||||
| template<class _HCspinor,class _Hspinor,class _Spinor, class projector> | template<class _HCspinor,class _Hspinor,class _Spinor, class projector> | ||||||
| class WilsonCompressorTemplate< _HCspinor, _Hspinor, _Spinor, projector, | class WilsonCompressorTemplate< _HCspinor, _Hspinor, _Spinor, projector, | ||||||
| 				typename std::enable_if<!std::is_same<_HCspinor,_Hspinor>::value>::type > | 				typename std::enable_if<!std::is_same<_HCspinor,_Hspinor>::value>::type > | ||||||
| @@ -142,20 +172,30 @@ public: | |||||||
|   typedef typename SiteHalfSpinor::vector_type     vComplexHigh; |   typedef typename SiteHalfSpinor::vector_type     vComplexHigh; | ||||||
|   constexpr static int Nw=sizeof(SiteHalfSpinor)/sizeof(vComplexHigh); |   constexpr static int Nw=sizeof(SiteHalfSpinor)/sizeof(vComplexHigh); | ||||||
|  |  | ||||||
|   accelerator_inline int CommDatumSize(void) { |   accelerator_inline int CommDatumSize(void) const { | ||||||
|     return sizeof(SiteHalfCommSpinor); |     return sizeof(SiteHalfCommSpinor); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /*****************************************************/ |   /*****************************************************/ | ||||||
|   /* Compress includes precision change if mpi data is not same */ |   /* Compress includes precision change if mpi data is not same */ | ||||||
|   /*****************************************************/ |   /*****************************************************/ | ||||||
|   template<class _SiteHalfSpinor, class _SiteSpinor> |   accelerator_inline void Compress(SiteHalfSpinor &buf,const SiteSpinor &in) const { | ||||||
|   accelerator_inline void Compress(_SiteHalfSpinor *buf,Integer o,const _SiteSpinor &in) { |     SiteHalfSpinor hsp; | ||||||
|     _SiteHalfSpinor hsp; |  | ||||||
|     SiteHalfCommSpinor *hbuf = (SiteHalfCommSpinor *)buf; |     SiteHalfCommSpinor *hbuf = (SiteHalfCommSpinor *)buf; | ||||||
|     projector::Proj(hsp,in,mu,dag); |     projector::Proj(hsp,in,mu,dag); | ||||||
|     precisionChange((vComplexLow *)&hbuf[o],(vComplexHigh *)&hsp,Nw); |     precisionChange((vComplexLow *)&hbuf[o],(vComplexHigh *)&hsp,Nw); | ||||||
|   } |   } | ||||||
|  |   accelerator_inline void Compress(SiteHalfSpinor &buf,const SiteSpinor &in) const { | ||||||
|  | #ifdef GRID_SIMT | ||||||
|  |     typedef decltype(coalescedRead(buf)) sobj; | ||||||
|  |     sobj sp; | ||||||
|  |     auto sin = coalescedRead(in); | ||||||
|  |     projector::Proj(sp,sin,mu,dag); | ||||||
|  |     coalescedWrite(buf,sp); | ||||||
|  | #else | ||||||
|  |     projector::Proj(buf,in,mu,dag); | ||||||
|  | #endif | ||||||
|  |   } | ||||||
|  |  | ||||||
|   /*****************************************************/ |   /*****************************************************/ | ||||||
|   /* Exchange includes precision change if mpi data is not same */ |   /* Exchange includes precision change if mpi data is not same */ | ||||||
| @@ -163,7 +203,7 @@ public: | |||||||
|   accelerator_inline void Exchange(SiteHalfSpinor *mp, |   accelerator_inline void Exchange(SiteHalfSpinor *mp, | ||||||
|                        SiteHalfSpinor *vp0, |                        SiteHalfSpinor *vp0, | ||||||
|                        SiteHalfSpinor *vp1, |                        SiteHalfSpinor *vp1, | ||||||
| 		       Integer type,Integer o){ | 		       Integer type,Integer o) const { | ||||||
|     SiteHalfSpinor vt0,vt1; |     SiteHalfSpinor vt0,vt1; | ||||||
|     SiteHalfCommSpinor *vpp0 = (SiteHalfCommSpinor *)vp0; |     SiteHalfCommSpinor *vpp0 = (SiteHalfCommSpinor *)vp0; | ||||||
|     SiteHalfCommSpinor *vpp1 = (SiteHalfCommSpinor *)vp1; |     SiteHalfCommSpinor *vpp1 = (SiteHalfCommSpinor *)vp1; | ||||||
| @@ -175,7 +215,7 @@ public: | |||||||
|   /*****************************************************/ |   /*****************************************************/ | ||||||
|   /* Have a decompression step if mpi data is not same */ |   /* Have a decompression step if mpi data is not same */ | ||||||
|   /*****************************************************/ |   /*****************************************************/ | ||||||
|   accelerator_inline void Decompress(SiteHalfSpinor *out, SiteHalfSpinor *in, Integer o){ |   accelerator_inline void Decompress(SiteHalfSpinor *out, SiteHalfSpinor *in, Integer o) const { | ||||||
|     SiteHalfCommSpinor *hin=(SiteHalfCommSpinor *)in; |     SiteHalfCommSpinor *hin=(SiteHalfCommSpinor *)in; | ||||||
|     precisionChange((vComplexHigh *)&out[o],(vComplexLow *)&hin[o],Nw); |     precisionChange((vComplexHigh *)&out[o],(vComplexLow *)&hin[o],Nw); | ||||||
|   } |   } | ||||||
| @@ -186,7 +226,7 @@ public: | |||||||
|   accelerator_inline void CompressExchange(SiteHalfSpinor *out0, |   accelerator_inline void CompressExchange(SiteHalfSpinor *out0, | ||||||
| 			       SiteHalfSpinor *out1, | 			       SiteHalfSpinor *out1, | ||||||
| 			       const SiteSpinor *in, | 			       const SiteSpinor *in, | ||||||
| 			       Integer j,Integer k, Integer m,Integer type){ | 			       Integer j,Integer k, Integer m,Integer type) const { | ||||||
|     SiteHalfSpinor temp1, temp2,temp3,temp4; |     SiteHalfSpinor temp1, temp2,temp3,temp4; | ||||||
|     SiteHalfCommSpinor *hout0 = (SiteHalfCommSpinor *)out0; |     SiteHalfCommSpinor *hout0 = (SiteHalfCommSpinor *)out0; | ||||||
|     SiteHalfCommSpinor *hout1 = (SiteHalfCommSpinor *)out1; |     SiteHalfCommSpinor *hout1 = (SiteHalfCommSpinor *)out1; | ||||||
| @@ -200,9 +240,10 @@ public: | |||||||
|   /*****************************************************/ |   /*****************************************************/ | ||||||
|   /* Pass the info to the stencil */ |   /* Pass the info to the stencil */ | ||||||
|   /*****************************************************/ |   /*****************************************************/ | ||||||
|   accelerator_inline bool DecompressionStep(void) { return true; } |   accelerator_inline bool DecompressionStep(void) const { return true; } | ||||||
|  |  | ||||||
| }; | }; | ||||||
|  | #endif | ||||||
|  |  | ||||||
| #define DECLARE_PROJ(Projector,Compressor,spProj)			\ | #define DECLARE_PROJ(Projector,Compressor,spProj)			\ | ||||||
|   class Projector {							\ |   class Projector {							\ | ||||||
| @@ -253,33 +294,8 @@ public: | |||||||
|   typedef typename Base::View_type View_type; |   typedef typename Base::View_type View_type; | ||||||
|   typedef typename Base::StencilVector StencilVector; |   typedef typename Base::StencilVector StencilVector; | ||||||
|  |  | ||||||
|   double timer0; |   void ZeroCountersi(void)  {  } | ||||||
|   double timer1; |   void Reporti(int calls)  {  } | ||||||
|   double timer2; |  | ||||||
|   double timer3; |  | ||||||
|   double timer4; |  | ||||||
|   double timer5; |  | ||||||
|   double timer6; |  | ||||||
|   uint64_t callsi; |  | ||||||
|   void ZeroCountersi(void) |  | ||||||
|   { |  | ||||||
|     timer0=0; |  | ||||||
|     timer1=0; |  | ||||||
|     timer2=0; |  | ||||||
|     timer3=0; |  | ||||||
|     timer4=0; |  | ||||||
|     timer5=0; |  | ||||||
|     timer6=0; |  | ||||||
|     callsi=0; |  | ||||||
|   } |  | ||||||
|   void Reporti(int calls) |  | ||||||
|   { |  | ||||||
|     if ( timer0 ) std::cout << GridLogMessage << " timer0 (HaloGatherOpt) " <<timer0/calls <<std::endl; |  | ||||||
|     if ( timer1 ) std::cout << GridLogMessage << " timer1 (Communicate)   " <<timer1/calls <<std::endl; |  | ||||||
|     if ( timer2 ) std::cout << GridLogMessage << " timer2 (CommsMerge )   " <<timer2/calls <<std::endl; |  | ||||||
|     if ( timer3 ) std::cout << GridLogMessage << " timer3 (commsMergeShm) " <<timer3/calls <<std::endl; |  | ||||||
|     if ( timer4 ) std::cout << GridLogMessage << " timer4 " <<timer4 <<std::endl; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   std::vector<int> surface_list; |   std::vector<int> surface_list; | ||||||
|  |  | ||||||
| @@ -287,9 +303,11 @@ public: | |||||||
| 		int npoints, | 		int npoints, | ||||||
| 		int checkerboard, | 		int checkerboard, | ||||||
| 		const std::vector<int> &directions, | 		const std::vector<int> &directions, | ||||||
| 		const std::vector<int> &distances,Parameters p)   | 		const std::vector<int> &distances, | ||||||
|     : CartesianStencil<vobj,cobj,Parameters> (grid,npoints,checkerboard,directions,distances,p)  | 		bool locally_periodic, | ||||||
|   {  | 		Parameters p)   | ||||||
|  |     : CartesianStencil<vobj,cobj,Parameters> (grid,npoints,checkerboard,directions,distances,locally_periodic,p) | ||||||
|  |   { | ||||||
|     ZeroCountersi(); |     ZeroCountersi(); | ||||||
|     surface_list.resize(0); |     surface_list.resize(0); | ||||||
|     this->same_node.resize(npoints); |     this->same_node.resize(npoints); | ||||||
| @@ -321,26 +339,18 @@ public: | |||||||
|   { |   { | ||||||
|     std::vector<std::vector<CommsRequest_t> > reqs; |     std::vector<std::vector<CommsRequest_t> > reqs; | ||||||
|     this->HaloExchangeOptGather(source,compress); |     this->HaloExchangeOptGather(source,compress); | ||||||
|     double t1=usecond(); |  | ||||||
|     // Asynchronous MPI calls multidirectional, Isend etc... |     // Asynchronous MPI calls multidirectional, Isend etc... | ||||||
|     // Non-overlapped directions within a thread. Asynchronous calls except MPI3, threaded up to comm threads ways. |     // Non-overlapped directions within a thread. Asynchronous calls except MPI3, threaded up to comm threads ways. | ||||||
|     this->Communicate(); |     this->Communicate(); | ||||||
|     double t2=usecond(); timer1 += t2-t1; |  | ||||||
|     this->CommsMerge(compress); |     this->CommsMerge(compress); | ||||||
|     double t3=usecond(); timer2 += t3-t2; |  | ||||||
|     this->CommsMergeSHM(compress); |     this->CommsMergeSHM(compress); | ||||||
|     double t4=usecond(); timer3 += t4-t3; |  | ||||||
|   } |   } | ||||||
|    |    | ||||||
|   template <class compressor> |   template <class compressor> | ||||||
|   void HaloExchangeOptGather(const Lattice<vobj> &source,compressor &compress)  |   void HaloExchangeOptGather(const Lattice<vobj> &source,compressor &compress)  | ||||||
|   { |   { | ||||||
|     this->Prepare(); |     this->Prepare(); | ||||||
|     double t0=usecond(); |  | ||||||
|     this->HaloGatherOpt(source,compress); |     this->HaloGatherOpt(source,compress); | ||||||
|     double t1=usecond(); |  | ||||||
|     timer0 += t1-t0; |  | ||||||
|     callsi++; |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   template <class compressor> |   template <class compressor> | ||||||
| @@ -352,12 +362,9 @@ public: | |||||||
|     typedef typename compressor::SiteHalfSpinor     SiteHalfSpinor; |     typedef typename compressor::SiteHalfSpinor     SiteHalfSpinor; | ||||||
|     typedef typename compressor::SiteHalfCommSpinor SiteHalfCommSpinor; |     typedef typename compressor::SiteHalfCommSpinor SiteHalfCommSpinor; | ||||||
|  |  | ||||||
|     this->mpi3synctime_g-=usecond(); |  | ||||||
|     this->_grid->StencilBarrier(); |     this->_grid->StencilBarrier(); | ||||||
|     this->mpi3synctime_g+=usecond(); |  | ||||||
|  |  | ||||||
|     assert(source.Grid()==this->_grid); |     assert(source.Grid()==this->_grid); | ||||||
|     this->halogtime-=usecond(); |  | ||||||
|      |      | ||||||
|     this->u_comm_offset=0; |     this->u_comm_offset=0; | ||||||
|        |        | ||||||
| @@ -393,7 +400,6 @@ public: | |||||||
|     } |     } | ||||||
|     this->face_table_computed=1; |     this->face_table_computed=1; | ||||||
|     assert(this->u_comm_offset==this->_unified_buffer_size); |     assert(this->u_comm_offset==this->_unified_buffer_size); | ||||||
|     this->halogtime+=usecond(); |  | ||||||
|     accelerator_barrier(); |     accelerator_barrier(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -146,8 +146,11 @@ public: | |||||||
|   void DhopInternalSerial(StencilImpl &st, LebesgueOrder &lo, DoubledGaugeField &U, |   void DhopInternalSerial(StencilImpl &st, LebesgueOrder &lo, DoubledGaugeField &U, | ||||||
|                     const FermionField &in, FermionField &out, int dag); |                     const FermionField &in, FermionField &out, int dag); | ||||||
|  |  | ||||||
|  |   void DhopInternalDirichletComms(StencilImpl &st, LebesgueOrder &lo, DoubledGaugeField &U, | ||||||
|  | 				  const FermionField &in, FermionField &out, int dag); | ||||||
|  |    | ||||||
|   void DhopInternalOverlappedComms(StencilImpl &st, LebesgueOrder &lo, DoubledGaugeField &U, |   void DhopInternalOverlappedComms(StencilImpl &st, LebesgueOrder &lo, DoubledGaugeField &U, | ||||||
|                     const FermionField &in, FermionField &out, int dag); | 				   const FermionField &in, FermionField &out, int dag); | ||||||
|  |  | ||||||
|   // Constructor |   // Constructor | ||||||
|   WilsonFermion(GaugeField &_Umu, GridCartesian &Fgrid, |   WilsonFermion(GaugeField &_Umu, GridCartesian &Fgrid, | ||||||
| @@ -157,7 +160,10 @@ public: | |||||||
|  |  | ||||||
|   // DoubleStore impl dependent |   // DoubleStore impl dependent | ||||||
|   void ImportGauge(const GaugeField &_Umu); |   void ImportGauge(const GaugeField &_Umu); | ||||||
|  |   DoubledGaugeField &GetDoubledGaugeField(void){ return Umu; }; | ||||||
|  |   DoubledGaugeField &GetDoubledGaugeFieldE(void){ return UmuEven; }; | ||||||
|  |   DoubledGaugeField &GetDoubledGaugeFieldO(void){ return UmuOdd; }; | ||||||
|  |    | ||||||
|   /////////////////////////////////////////////////////////////// |   /////////////////////////////////////////////////////////////// | ||||||
|   // Data members require to support the functionality |   // Data members require to support the functionality | ||||||
|   /////////////////////////////////////////////////////////////// |   /////////////////////////////////////////////////////////////// | ||||||
|   | |||||||
| @@ -165,7 +165,14 @@ public: | |||||||
| 			       const FermionField &in,  | 			       const FermionField &in,  | ||||||
| 			       FermionField &out, | 			       FermionField &out, | ||||||
| 			       int dag); | 			       int dag); | ||||||
|      |  | ||||||
|  |   void DhopInternalDirichletComms(StencilImpl & st, | ||||||
|  | 				  LebesgueOrder &lo, | ||||||
|  | 				  DoubledGaugeField &U, | ||||||
|  | 				  const FermionField &in,  | ||||||
|  | 				  FermionField &out, | ||||||
|  | 				  int dag); | ||||||
|  |    | ||||||
|   // Constructors |   // Constructors | ||||||
|   WilsonFermion5D(GaugeField &_Umu, |   WilsonFermion5D(GaugeField &_Umu, | ||||||
| 		  GridCartesian         &FiveDimGrid, | 		  GridCartesian         &FiveDimGrid, | ||||||
| @@ -174,19 +181,11 @@ public: | |||||||
| 		  GridRedBlackCartesian &FourDimRedBlackGrid, | 		  GridRedBlackCartesian &FourDimRedBlackGrid, | ||||||
| 		  double _M5,const ImplParams &p= ImplParams()); | 		  double _M5,const ImplParams &p= ImplParams()); | ||||||
|      |      | ||||||
|   // Constructors |  | ||||||
|   /* |  | ||||||
|     WilsonFermion5D(int simd,  |  | ||||||
|     GaugeField &_Umu, |  | ||||||
|     GridCartesian         &FiveDimGrid, |  | ||||||
|     GridRedBlackCartesian &FiveDimRedBlackGrid, |  | ||||||
|     GridCartesian         &FourDimGrid, |  | ||||||
|     double _M5,const ImplParams &p= ImplParams()); |  | ||||||
|   */ |  | ||||||
|      |  | ||||||
|   // DoubleStore |   // DoubleStore | ||||||
|   void ImportGauge(const GaugeField &_Umu); |   void ImportGauge(const GaugeField &_Umu); | ||||||
|      |   DoubledGaugeField &GetDoubledGaugeField(void){ return Umu; }; | ||||||
|  |   DoubledGaugeField &GetDoubledGaugeFieldE(void){ return UmuEven; }; | ||||||
|  |   DoubledGaugeField &GetDoubledGaugeFieldO(void){ return UmuOdd; }; | ||||||
|   /////////////////////////////////////////////////////////////// |   /////////////////////////////////////////////////////////////// | ||||||
|   // Data members require to support the functionality |   // Data members require to support the functionality | ||||||
|   /////////////////////////////////////////////////////////////// |   /////////////////////////////////////////////////////////////// | ||||||
|   | |||||||
| @@ -72,7 +72,7 @@ public: | |||||||
|   typedef WilsonCompressor<SiteHalfCommSpinor,SiteHalfSpinor, SiteSpinor> Compressor; |   typedef WilsonCompressor<SiteHalfCommSpinor,SiteHalfSpinor, SiteSpinor> Compressor; | ||||||
|   typedef WilsonImplParams ImplParams; |   typedef WilsonImplParams ImplParams; | ||||||
|   typedef WilsonStencil<SiteSpinor, SiteHalfSpinor,ImplParams> StencilImpl; |   typedef WilsonStencil<SiteSpinor, SiteHalfSpinor,ImplParams> StencilImpl; | ||||||
|   typedef typename StencilImpl::View_type StencilView; |   typedef const typename StencilImpl::View_type StencilView; | ||||||
|      |      | ||||||
|   ImplParams Params; |   ImplParams Params; | ||||||
|  |  | ||||||
| @@ -106,11 +106,15 @@ public: | |||||||
| 			    const _SpinorField & phi, | 			    const _SpinorField & phi, | ||||||
| 			    int mu) | 			    int mu) | ||||||
|   { |   { | ||||||
|  |     const int Nsimd = SiteHalfSpinor::Nsimd(); | ||||||
|     autoView( out_v, out, AcceleratorWrite); |     autoView( out_v, out, AcceleratorWrite); | ||||||
|     autoView( phi_v, phi, AcceleratorRead); |     autoView( phi_v, phi, AcceleratorRead); | ||||||
|     autoView( Umu_v, Umu, AcceleratorRead); |     autoView( Umu_v, Umu, AcceleratorRead); | ||||||
|     accelerator_for(sss,out.Grid()->oSites(),1,{ |     typedef decltype(coalescedRead(out_v[0]))   calcSpinor; | ||||||
| 	multLink(out_v[sss],Umu_v[sss],phi_v[sss],mu); |     accelerator_for(sss,out.Grid()->oSites(),Nsimd,{ | ||||||
|  | 	calcSpinor tmp; | ||||||
|  | 	multLink(tmp,Umu_v[sss],phi_v(sss),mu); | ||||||
|  | 	coalescedWrite(out_v[sss],tmp); | ||||||
|     }); |     }); | ||||||
|   } |   } | ||||||
| 					    | 					    | ||||||
| @@ -180,18 +184,22 @@ public: | |||||||
|       mat = TraceIndex<SpinIndex>(P);  |       mat = TraceIndex<SpinIndex>(P);  | ||||||
|     } |     } | ||||||
|        |        | ||||||
|     inline void extractLinkField(std::vector<GaugeLinkField> &mat, DoubledGaugeField &Uds){ |     inline void extractLinkField(std::vector<GaugeLinkField> &mat, DoubledGaugeField &Uds) | ||||||
|  |     { | ||||||
|       for (int mu = 0; mu < Nd; mu++) |       for (int mu = 0; mu < Nd; mu++) | ||||||
|       mat[mu] = PeekIndex<LorentzIndex>(Uds, mu); |       mat[mu] = PeekIndex<LorentzIndex>(Uds, mu); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |   inline void InsertForce5D(GaugeField &mat, FermionField &Btilde, FermionField Ã,int mu) | ||||||
|   inline void InsertForce5D(GaugeField &mat, FermionField &Btilde, FermionField Ã,int mu){ |   { | ||||||
|        | #undef USE_OLD_INSERT_FORCE     | ||||||
|     int Ls=Btilde.Grid()->_fdimensions[0]; |     int Ls=Btilde.Grid()->_fdimensions[0]; | ||||||
|  |     autoView( mat_v , mat, AcceleratorWrite); | ||||||
|  | #ifdef USE_OLD_INSERT_FORCE     | ||||||
|     GaugeLinkField tmp(mat.Grid()); |     GaugeLinkField tmp(mat.Grid()); | ||||||
|     tmp = Zero(); |     tmp = Zero(); | ||||||
|     { |     { | ||||||
|  |       const int Nsimd = SiteSpinor::Nsimd(); | ||||||
|       autoView( tmp_v , tmp, AcceleratorWrite); |       autoView( tmp_v , tmp, AcceleratorWrite); | ||||||
|       autoView( Btilde_v , Btilde, AcceleratorRead); |       autoView( Btilde_v , Btilde, AcceleratorRead); | ||||||
|       autoView( Atilde_v , Atilde, AcceleratorRead); |       autoView( Atilde_v , Atilde, AcceleratorRead); | ||||||
| @@ -204,6 +212,29 @@ public: | |||||||
| 	}); | 	}); | ||||||
|     } |     } | ||||||
|     PokeIndex<LorentzIndex>(mat,tmp,mu); |     PokeIndex<LorentzIndex>(mat,tmp,mu); | ||||||
|  | #else | ||||||
|  |     { | ||||||
|  |       const int Nsimd = SiteSpinor::Nsimd(); | ||||||
|  |       autoView( Btilde_v , Btilde, AcceleratorRead); | ||||||
|  |       autoView( Atilde_v , Atilde, AcceleratorRead); | ||||||
|  |       accelerator_for(sss,mat.Grid()->oSites(),Nsimd,{ | ||||||
|  | 	  int sU=sss; | ||||||
|  |   	  typedef decltype(coalescedRead(mat_v[sU](mu)() )) ColorMatrixType; | ||||||
|  |   	  ColorMatrixType sum; | ||||||
|  | 	  zeroit(sum);   | ||||||
|  | 	  for(int s=0;s<Ls;s++){ | ||||||
|  | 	    int sF = s+Ls*sU; | ||||||
|  |   	    for(int spn=0;spn<Ns;spn++){ //sum over spin | ||||||
|  |   	      auto bb = coalescedRead(Btilde_v[sF]()(spn) ); //color vector | ||||||
|  |   	      auto aa = coalescedRead(Atilde_v[sF]()(spn) ); | ||||||
|  | 	      auto op = outerProduct(bb,aa); | ||||||
|  |   	      sum = sum + op; | ||||||
|  | 	    } | ||||||
|  | 	  } | ||||||
|  |   	  coalescedWrite(mat_v[sU](mu)(), sum); | ||||||
|  |       }); | ||||||
|  |     } | ||||||
|  | #endif     | ||||||
|   } |   } | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @@ -212,17 +243,17 @@ typedef WilsonImpl<vComplex,  FundamentalRepresentation, CoeffReal > WilsonImplR | |||||||
| typedef WilsonImpl<vComplexF, FundamentalRepresentation, CoeffReal > WilsonImplF;  // Float | typedef WilsonImpl<vComplexF, FundamentalRepresentation, CoeffReal > WilsonImplF;  // Float | ||||||
| typedef WilsonImpl<vComplexD, FundamentalRepresentation, CoeffReal > WilsonImplD;  // Double | typedef WilsonImpl<vComplexD, FundamentalRepresentation, CoeffReal > WilsonImplD;  // Double | ||||||
|  |  | ||||||
| typedef WilsonImpl<vComplex,  FundamentalRepresentation, CoeffRealHalfComms > WilsonImplRL;  // Real.. whichever prec | //typedef WilsonImpl<vComplex,  FundamentalRepresentation, CoeffRealHalfComms > WilsonImplRL;  // Real.. whichever prec | ||||||
| typedef WilsonImpl<vComplexF, FundamentalRepresentation, CoeffRealHalfComms > WilsonImplFH;  // Float | //typedef WilsonImpl<vComplexF, FundamentalRepresentation, CoeffRealHalfComms > WilsonImplFH;  // Float | ||||||
| typedef WilsonImpl<vComplexD, FundamentalRepresentation, CoeffRealHalfComms > WilsonImplDF;  // Double | //typedef WilsonImpl<vComplexD, FundamentalRepresentation, CoeffRealHalfComms > WilsonImplDF;  // Double | ||||||
|  |  | ||||||
| typedef WilsonImpl<vComplex,  FundamentalRepresentation, CoeffComplex > ZWilsonImplR; // Real.. whichever prec | typedef WilsonImpl<vComplex,  FundamentalRepresentation, CoeffComplex > ZWilsonImplR; // Real.. whichever prec | ||||||
| typedef WilsonImpl<vComplexF, FundamentalRepresentation, CoeffComplex > ZWilsonImplF; // Float | typedef WilsonImpl<vComplexF, FundamentalRepresentation, CoeffComplex > ZWilsonImplF; // Float | ||||||
| typedef WilsonImpl<vComplexD, FundamentalRepresentation, CoeffComplex > ZWilsonImplD; // Double | typedef WilsonImpl<vComplexD, FundamentalRepresentation, CoeffComplex > ZWilsonImplD; // Double | ||||||
|  |  | ||||||
| typedef WilsonImpl<vComplex,  FundamentalRepresentation, CoeffComplexHalfComms > ZWilsonImplRL; // Real.. whichever prec | //typedef WilsonImpl<vComplex,  FundamentalRepresentation, CoeffComplexHalfComms > ZWilsonImplRL; // Real.. whichever prec | ||||||
| typedef WilsonImpl<vComplexF, FundamentalRepresentation, CoeffComplexHalfComms > ZWilsonImplFH; // Float | //typedef WilsonImpl<vComplexF, FundamentalRepresentation, CoeffComplexHalfComms > ZWilsonImplFH; // Float | ||||||
| typedef WilsonImpl<vComplexD, FundamentalRepresentation, CoeffComplexHalfComms > ZWilsonImplDF; // Double | //typedef WilsonImpl<vComplexD, FundamentalRepresentation, CoeffComplexHalfComms > ZWilsonImplDF; // Double | ||||||
|   |   | ||||||
| typedef WilsonImpl<vComplex,  AdjointRepresentation, CoeffReal > WilsonAdjImplR;   // Real.. whichever prec | typedef WilsonImpl<vComplex,  AdjointRepresentation, CoeffReal > WilsonAdjImplR;   // Real.. whichever prec | ||||||
| typedef WilsonImpl<vComplexF, AdjointRepresentation, CoeffReal > WilsonAdjImplF;  // Float | typedef WilsonImpl<vComplexF, AdjointRepresentation, CoeffReal > WilsonAdjImplF;  // Float | ||||||
|   | |||||||
| @@ -39,7 +39,7 @@ NAMESPACE_BEGIN(Grid); | |||||||
| class WilsonKernelsStatic {  | class WilsonKernelsStatic {  | ||||||
| public: | public: | ||||||
|   enum { OptGeneric, OptHandUnroll, OptInlineAsm }; |   enum { OptGeneric, OptHandUnroll, OptInlineAsm }; | ||||||
|   enum { CommsAndCompute, CommsThenCompute }; |   enum { CommsAndCompute, CommsThenCompute, CommsDirichlet }; | ||||||
|   static int Opt;   |   static int Opt;   | ||||||
|   static int Comms; |   static int Comms; | ||||||
| }; | }; | ||||||
| @@ -49,9 +49,17 @@ public: | |||||||
|  |  | ||||||
|   INHERIT_IMPL_TYPES(Impl); |   INHERIT_IMPL_TYPES(Impl); | ||||||
|   typedef FermionOperator<Impl> Base; |   typedef FermionOperator<Impl> Base; | ||||||
|     |   typedef AcceleratorVector<int,STENCIL_MAX> StencilVector;    | ||||||
| public: | public: | ||||||
|  |  | ||||||
|  | #ifdef GRID_SYCL | ||||||
|  | #define SYCL_HACK | ||||||
|  | #endif   | ||||||
|  | #ifdef SYCL_HACK | ||||||
|  |   static void HandDhopSiteSycl(StencilVector st_perm,StencilEntry *st_p, SiteDoubledGaugeField *U,SiteHalfSpinor  *buf, | ||||||
|  | 			       int ss,int sU,const SiteSpinor *in, SiteSpinor *out); | ||||||
|  | #endif | ||||||
|  |    | ||||||
|   static void DhopKernel(int Opt,StencilImpl &st,  DoubledGaugeField &U, SiteHalfSpinor * buf, |   static void DhopKernel(int Opt,StencilImpl &st,  DoubledGaugeField &U, SiteHalfSpinor * buf, | ||||||
| 			 int Ls, int Nsite, const FermionField &in, FermionField &out, | 			 int Ls, int Nsite, const FermionField &in, FermionField &out, | ||||||
| 			 int interior=1,int exterior=1) ; | 			 int interior=1,int exterior=1) ; | ||||||
|   | |||||||
| @@ -112,7 +112,6 @@ void CayleyFermion5D<Impl>::ImportUnphysicalFermion(const FermionField &input4d, | |||||||
|   axpby_ssp_pminus(tmp, 0., tmp, 1., tmp, Ls-1, Ls-1); |   axpby_ssp_pminus(tmp, 0., tmp, 1., tmp, Ls-1, Ls-1); | ||||||
|   imported5d=tmp; |   imported5d=tmp; | ||||||
| } | } | ||||||
|  |  | ||||||
| template<class Impl>   | template<class Impl>   | ||||||
| void CayleyFermion5D<Impl>::ImportPhysicalFermionSource(const FermionField &input4d,FermionField &imported5d) | void CayleyFermion5D<Impl>::ImportPhysicalFermionSource(const FermionField &input4d,FermionField &imported5d) | ||||||
| { | { | ||||||
| @@ -127,6 +126,37 @@ void CayleyFermion5D<Impl>::ImportPhysicalFermionSource(const FermionField &inpu | |||||||
|   axpby_ssp_pminus(tmp, 0., tmp, 1., tmp, Ls-1, Ls-1); |   axpby_ssp_pminus(tmp, 0., tmp, 1., tmp, Ls-1, Ls-1); | ||||||
|   Dminus(tmp,imported5d); |   Dminus(tmp,imported5d); | ||||||
| } | } | ||||||
|  | //////////////////////////////////////////////////// | ||||||
|  | // Added for fourD pseudofermion det estimation | ||||||
|  | //////////////////////////////////////////////////// | ||||||
|  | template<class Impl>   | ||||||
|  | void CayleyFermion5D<Impl>::ImportFourDimPseudoFermion(const FermionField &input4d,FermionField &imported5d) | ||||||
|  | { | ||||||
|  |   int Ls = this->Ls; | ||||||
|  |   FermionField tmp(this->FermionGrid()); | ||||||
|  |   conformable(imported5d.Grid(),this->FermionGrid()); | ||||||
|  |   conformable(input4d.Grid()   ,this->GaugeGrid()); | ||||||
|  |   tmp = Zero(); | ||||||
|  |   InsertSlice(input4d, tmp, 0   , 0); | ||||||
|  |   InsertSlice(input4d, tmp, Ls-1, 0); | ||||||
|  |   axpby_ssp_pminus(tmp, 0., tmp, 1., tmp, 0, 0); | ||||||
|  |   axpby_ssp_pplus (tmp, 0., tmp, 1., tmp, Ls-1, Ls-1); | ||||||
|  |   imported5d=tmp; | ||||||
|  | } | ||||||
|  | template<class Impl>   | ||||||
|  | void CayleyFermion5D<Impl>::ExportFourDimPseudoFermion(const FermionField &solution5d,FermionField &exported4d) | ||||||
|  | { | ||||||
|  |   int Ls = this->Ls; | ||||||
|  |   FermionField tmp(this->FermionGrid()); | ||||||
|  |   tmp = solution5d; | ||||||
|  |   conformable(solution5d.Grid(),this->FermionGrid()); | ||||||
|  |   conformable(exported4d.Grid(),this->GaugeGrid()); | ||||||
|  |   axpby_ssp_pminus(tmp, 0., solution5d, 1., solution5d, 0, 0); | ||||||
|  |   axpby_ssp_pplus (tmp, 1., tmp       , 1., solution5d, 0, Ls-1); | ||||||
|  |   ExtractSlice(exported4d, tmp, 0, 0); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Dminus | ||||||
| template<class Impl>   | template<class Impl>   | ||||||
| void CayleyFermion5D<Impl>::Dminus(const FermionField &psi, FermionField &chi) | void CayleyFermion5D<Impl>::Dminus(const FermionField &psi, FermionField &chi) | ||||||
| { | { | ||||||
| @@ -642,7 +672,7 @@ void CayleyFermion5D<Impl>::ContractConservedCurrent( PropagatorField &q_in_1, | |||||||
| 						      Current curr_type, | 						      Current curr_type, | ||||||
| 						      unsigned int mu) | 						      unsigned int mu) | ||||||
| { | { | ||||||
| #if (!defined(GRID_CUDA)) && (!defined(GRID_HIP)) | #if (!defined(GRID_HIP)) | ||||||
|   Gamma::Algebra Gmu [] = { |   Gamma::Algebra Gmu [] = { | ||||||
|     Gamma::Algebra::GammaX, |     Gamma::Algebra::GammaX, | ||||||
|     Gamma::Algebra::GammaY, |     Gamma::Algebra::GammaY, | ||||||
| @@ -826,7 +856,7 @@ void CayleyFermion5D<Impl>::SeqConservedCurrent(PropagatorField &q_in, | |||||||
|   } |   } | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #if (!defined(GRID_CUDA)) && (!defined(GRID_HIP)) | #if (!defined(GRID_HIP)) | ||||||
|   int tshift = (mu == Nd-1) ? 1 : 0; |   int tshift = (mu == Nd-1) ? 1 : 0; | ||||||
|   //////////////////////////////////////////////// |   //////////////////////////////////////////////// | ||||||
|   // GENERAL CAYLEY CASE |   // GENERAL CAYLEY CASE | ||||||
| @@ -880,17 +910,29 @@ void CayleyFermion5D<Impl>::SeqConservedCurrent(PropagatorField &q_in, | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   std::vector<RealD> G_s(Ls,1.0); |   std::vector<RealD> G_s(Ls,1.0); | ||||||
|  |   RealD sign = 1; // sign flip for vector/tadpole | ||||||
|   if ( curr_type == Current::Axial ) { |   if ( curr_type == Current::Axial ) { | ||||||
|     for(int s=0;s<Ls/2;s++){ |     for(int s=0;s<Ls/2;s++){ | ||||||
|       G_s[s] = -1.0; |       G_s[s] = -1.0; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |   else if ( curr_type == Current::Tadpole ) { | ||||||
|  |     auto b=this->_b; | ||||||
|  |     auto c=this->_c; | ||||||
|  |     if ( b == 1 && c == 0 ) { | ||||||
|  |       sign = -1;     | ||||||
|  |     } | ||||||
|  |     else { | ||||||
|  |       std::cerr << "Error: Tadpole implementation currently unavailable for non-Shamir actions." << std::endl; | ||||||
|  |       assert(b==1 && c==0); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|   for(int s=0;s<Ls;s++){ |   for(int s=0;s<Ls;s++){ | ||||||
|  |  | ||||||
|     int sp = (s+1)%Ls; |     int sp = (s+1)%Ls; | ||||||
|     int sr = Ls-1-s; |     //    int sr = Ls-1-s; | ||||||
|     int srp= (sr+1)%Ls; |     //    int srp= (sr+1)%Ls; | ||||||
|  |  | ||||||
|     // Mobius parameters |     // Mobius parameters | ||||||
|     auto b=this->bs[s]; |     auto b=this->bs[s]; | ||||||
| @@ -907,7 +949,7 @@ void CayleyFermion5D<Impl>::SeqConservedCurrent(PropagatorField &q_in, | |||||||
|  |  | ||||||
|     tmp    = Cshift(tmp,mu,1); |     tmp    = Cshift(tmp,mu,1); | ||||||
|     Impl::multLinkField(Utmp,this->Umu,tmp,mu); |     Impl::multLinkField(Utmp,this->Umu,tmp,mu); | ||||||
|     tmp    = G_s[s]*( Utmp*ph - gmu*Utmp*ph ); // Forward hop |     tmp    = sign*G_s[s]*( Utmp*ph - gmu*Utmp*ph ); // Forward hop | ||||||
|     tmp    = where((lcoor>=tmin),tmp,zz); // Mask the time  |     tmp    = where((lcoor>=tmin),tmp,zz); // Mask the time  | ||||||
|     L_Q    = where((lcoor<=tmax),tmp,zz); // Position of current complicated |     L_Q    = where((lcoor<=tmax),tmp,zz); // Position of current complicated | ||||||
|  |  | ||||||
|   | |||||||
| @@ -680,7 +680,8 @@ void StaggeredKernels<Impl>::DhopSiteAsm(StencilView &st, | |||||||
|   gauge2 =(uint64_t)&UU[sU]( Z );				\ |   gauge2 =(uint64_t)&UU[sU]( Z );				\ | ||||||
|   gauge3 =(uint64_t)&UU[sU]( T );  |   gauge3 =(uint64_t)&UU[sU]( T );  | ||||||
|    |    | ||||||
|  | #undef STAG_VEC5D | ||||||
|  | #ifdef STAG_VEC5D | ||||||
|   // This is the single precision 5th direction vectorised kernel |   // This is the single precision 5th direction vectorised kernel | ||||||
| #include <Grid/simd/Intel512single.h> | #include <Grid/simd/Intel512single.h> | ||||||
| template <> void StaggeredKernels<StaggeredVec5dImplF>::DhopSiteAsm(StencilView &st, | template <> void StaggeredKernels<StaggeredVec5dImplF>::DhopSiteAsm(StencilView &st, | ||||||
| @@ -790,7 +791,7 @@ template <> void StaggeredKernels<StaggeredVec5dImplD>::DhopSiteAsm(StencilView | |||||||
| #endif | #endif | ||||||
| } | } | ||||||
|     |     | ||||||
|     | #endif    | ||||||
|  |  | ||||||
|  |  | ||||||
| #define PERMUTE_DIR3 __asm__ (	\ | #define PERMUTE_DIR3 __asm__ (	\ | ||||||
|   | |||||||
| @@ -32,25 +32,50 @@ Author: paboyle <paboyle@ph.ed.ac.uk> | |||||||
|  |  | ||||||
| NAMESPACE_BEGIN(Grid); | NAMESPACE_BEGIN(Grid); | ||||||
|  |  | ||||||
| #define LOAD_CHI(b)		\ | #ifdef GRID_SIMT | ||||||
|  |  | ||||||
|  | #define LOAD_CHI(ptype,b)			\ | ||||||
|  |   const SiteSpinor & ref (b[offset]);				\ | ||||||
|  |   Chi_0=coalescedReadPermute<ptype>(ref()()(0),perm,lane);	\ | ||||||
|  |   Chi_1=coalescedReadPermute<ptype>(ref()()(1),perm,lane);	\ | ||||||
|  |   Chi_2=coalescedReadPermute<ptype>(ref()()(2),perm,lane); | ||||||
|  |  | ||||||
|  | #define LOAD_CHI_COMMS(b)		\ | ||||||
|   const SiteSpinor & ref (b[offset]);	\ |   const SiteSpinor & ref (b[offset]);	\ | ||||||
|     Chi_0=ref()()(0);\ |   Chi_0=coalescedRead(ref()()(0),lane);	\ | ||||||
|     Chi_1=ref()()(1);\ |   Chi_1=coalescedRead(ref()()(1),lane);	\ | ||||||
|     Chi_2=ref()()(2); |   Chi_2=coalescedRead(ref()()(2),lane); | ||||||
|  |  | ||||||
|  | #define PERMUTE_DIR(dir)	; | ||||||
|  | #else | ||||||
|  | #define LOAD_CHI(ptype,b)      LOAD_CHI_COMMS(b) | ||||||
|  |  | ||||||
|  | #define LOAD_CHI_COMMS(b)		\ | ||||||
|  |   const SiteSpinor & ref (b[offset]);	\ | ||||||
|  |   Chi_0=ref()()(0);			\ | ||||||
|  |   Chi_1=ref()()(1);			\ | ||||||
|  |   Chi_2=ref()()(2); | ||||||
|  |  | ||||||
|  | #define PERMUTE_DIR(dir)			\ | ||||||
|  |   permute##dir(Chi_0,Chi_0);			\ | ||||||
|  |   permute##dir(Chi_1,Chi_1);			\ | ||||||
|  |   permute##dir(Chi_2,Chi_2); | ||||||
|  |  | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  |  | ||||||
| // To splat or not to splat depends on the implementation | // To splat or not to splat depends on the implementation | ||||||
| #define MULT(A,UChi)				\ | #define MULT(A,UChi)				\ | ||||||
|   auto & ref(U[sU](A));			\ |   auto & ref(U[sU](A));			\ | ||||||
|    Impl::loadLinkElement(U_00,ref()(0,0));      \ |     U_00=coalescedRead(ref()(0,0),lane);				\ | ||||||
|    Impl::loadLinkElement(U_10,ref()(1,0));      \ |     U_10=coalescedRead(ref()(1,0),lane);				\ | ||||||
|    Impl::loadLinkElement(U_20,ref()(2,0));      \ |     U_20=coalescedRead(ref()(2,0),lane);				\ | ||||||
|    Impl::loadLinkElement(U_01,ref()(0,1));      \ |     U_01=coalescedRead(ref()(0,1),lane);				\ | ||||||
|    Impl::loadLinkElement(U_11,ref()(1,1));      \ |     U_11=coalescedRead(ref()(1,1),lane);				\ | ||||||
|    Impl::loadLinkElement(U_21,ref()(2,1));      \ |     U_21=coalescedRead(ref()(2,1),lane);				\ | ||||||
|    Impl::loadLinkElement(U_02,ref()(0,2));     \ |     U_02=coalescedRead(ref()(0,2),lane);				\ | ||||||
|    Impl::loadLinkElement(U_12,ref()(1,2));     \ |     U_12=coalescedRead(ref()(1,2),lane);				\ | ||||||
|    Impl::loadLinkElement(U_22,ref()(2,2));     \ |     U_22=coalescedRead(ref()(2,2),lane);				\ | ||||||
|     UChi ## _0  = U_00*Chi_0;	       \ |     UChi ## _0  = U_00*Chi_0;	       \ | ||||||
|     UChi ## _1  = U_10*Chi_0;\ |     UChi ## _1  = U_10*Chi_0;\ | ||||||
|     UChi ## _2  = U_20*Chi_0;\ |     UChi ## _2  = U_20*Chi_0;\ | ||||||
| @@ -63,15 +88,15 @@ NAMESPACE_BEGIN(Grid); | |||||||
|  |  | ||||||
| #define MULT_ADD(U,A,UChi)			\ | #define MULT_ADD(U,A,UChi)			\ | ||||||
|   auto & ref(U[sU](A));			\ |   auto & ref(U[sU](A));			\ | ||||||
|    Impl::loadLinkElement(U_00,ref()(0,0));      \ |     U_00=coalescedRead(ref()(0,0),lane);				\ | ||||||
|    Impl::loadLinkElement(U_10,ref()(1,0));      \ |     U_10=coalescedRead(ref()(1,0),lane);				\ | ||||||
|    Impl::loadLinkElement(U_20,ref()(2,0));      \ |     U_20=coalescedRead(ref()(2,0),lane);				\ | ||||||
|    Impl::loadLinkElement(U_01,ref()(0,1));      \ |     U_01=coalescedRead(ref()(0,1),lane);				\ | ||||||
|    Impl::loadLinkElement(U_11,ref()(1,1));      \ |     U_11=coalescedRead(ref()(1,1),lane);				\ | ||||||
|    Impl::loadLinkElement(U_21,ref()(2,1));      \ |     U_21=coalescedRead(ref()(2,1),lane);				\ | ||||||
|    Impl::loadLinkElement(U_02,ref()(0,2));     \ |     U_02=coalescedRead(ref()(0,2),lane);				\ | ||||||
|    Impl::loadLinkElement(U_12,ref()(1,2));     \ |     U_12=coalescedRead(ref()(1,2),lane);				\ | ||||||
|    Impl::loadLinkElement(U_22,ref()(2,2));     \ |     U_22=coalescedRead(ref()(2,2),lane);				\ | ||||||
|     UChi ## _0 += U_00*Chi_0;	       \ |     UChi ## _0 += U_00*Chi_0;	       \ | ||||||
|     UChi ## _1 += U_10*Chi_0;\ |     UChi ## _1 += U_10*Chi_0;\ | ||||||
|     UChi ## _2 += U_20*Chi_0;\ |     UChi ## _2 += U_20*Chi_0;\ | ||||||
| @@ -83,24 +108,18 @@ NAMESPACE_BEGIN(Grid); | |||||||
|     UChi ## _2 += U_22*Chi_2; |     UChi ## _2 += U_22*Chi_2; | ||||||
|  |  | ||||||
|  |  | ||||||
| #define PERMUTE_DIR(dir)			\ |  | ||||||
|   permute##dir(Chi_0,Chi_0);			\ |  | ||||||
|   permute##dir(Chi_1,Chi_1);			\ |  | ||||||
|   permute##dir(Chi_2,Chi_2); |  | ||||||
|  |  | ||||||
|  |  | ||||||
| #define HAND_STENCIL_LEG_BASE(Dir,Perm,skew)	\ | #define HAND_STENCIL_LEG_BASE(Dir,Perm,skew)	\ | ||||||
|   SE=st.GetEntry(ptype,Dir+skew,sF);	\ |   SE=st.GetEntry(ptype,Dir+skew,sF);	\ | ||||||
|   offset = SE->_offset;			\ |   offset = SE->_offset;			\ | ||||||
|   local  = SE->_is_local;		\ |   local  = SE->_is_local;		\ | ||||||
|   perm   = SE->_permute;		\ |   perm   = SE->_permute;		\ | ||||||
|   if ( local ) {						\ |   if ( local ) {						\ | ||||||
|     LOAD_CHI(in);					\ |     LOAD_CHI(Perm,in);						\ | ||||||
|     if ( perm) {						\ |     if ( perm) {						\ | ||||||
|       PERMUTE_DIR(Perm);					\ |       PERMUTE_DIR(Perm);					\ | ||||||
|     }								\ |     }								\ | ||||||
|   } else {							\ |   } else {							\ | ||||||
|     LOAD_CHI(buf);						\ |     LOAD_CHI_COMMS(buf);					\ | ||||||
|   }								 |   }								 | ||||||
|  |  | ||||||
| #define HAND_STENCIL_LEG_BEGIN(Dir,Perm,skew,even)		\ | #define HAND_STENCIL_LEG_BEGIN(Dir,Perm,skew,even)		\ | ||||||
| @@ -116,19 +135,18 @@ NAMESPACE_BEGIN(Grid); | |||||||
|   } |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| #define HAND_STENCIL_LEG_INT(U,Dir,Perm,skew,even)	\ | #define HAND_STENCIL_LEG_INT(U,Dir,Perm,skew,even)	\ | ||||||
|   SE=st.GetEntry(ptype,Dir+skew,sF);			\ |   SE=st.GetEntry(ptype,Dir+skew,sF);			\ | ||||||
|   offset = SE->_offset;					\ |   offset = SE->_offset;					\ | ||||||
|   local  = SE->_is_local;				\ |   local  = SE->_is_local;				\ | ||||||
|   perm   = SE->_permute;				\ |   perm   = SE->_permute;				\ | ||||||
|   if ( local ) {					\ |   if ( local ) {					\ | ||||||
|     LOAD_CHI(in);				\ |     LOAD_CHI(Perm,in);					\ | ||||||
|     if ( perm) {					\ |     if ( perm) {					\ | ||||||
|       PERMUTE_DIR(Perm);				\ |       PERMUTE_DIR(Perm);				\ | ||||||
|     }							\ |     }							\ | ||||||
|   } else if ( st.same_node[Dir] ) {			\ |   } else if ( st.same_node[Dir] ) {			\ | ||||||
|     LOAD_CHI(buf);					\ |     LOAD_CHI_COMMS(buf);				\ | ||||||
|   }							\ |   }							\ | ||||||
|   if (local || st.same_node[Dir] ) {		\ |   if (local || st.same_node[Dir] ) {		\ | ||||||
|     MULT_ADD(U,Dir,even);				\ |     MULT_ADD(U,Dir,even);				\ | ||||||
| @@ -140,10 +158,32 @@ NAMESPACE_BEGIN(Grid); | |||||||
|   local  = SE->_is_local;				\ |   local  = SE->_is_local;				\ | ||||||
|   if ((!local) && (!st.same_node[Dir]) ) {		\ |   if ((!local) && (!st.same_node[Dir]) ) {		\ | ||||||
|     nmu++;							\ |     nmu++;							\ | ||||||
|     { LOAD_CHI(buf);	  }					\ |     { LOAD_CHI_COMMS(buf);	  }				\ | ||||||
|     { MULT_ADD(U,Dir,even); }					\ |     { MULT_ADD(U,Dir,even); }					\ | ||||||
|   }								 |   }								 | ||||||
|  |  | ||||||
|  | #define HAND_DECLARATIONS(Simd) \ | ||||||
|  |   Simd even_0;			\ | ||||||
|  |   Simd even_1;			\ | ||||||
|  |   Simd even_2;			\ | ||||||
|  |   Simd odd_0;			\ | ||||||
|  |   Simd odd_1;			\ | ||||||
|  |   Simd odd_2;		        \ | ||||||
|  | 		      		\ | ||||||
|  |   Simd Chi_0;			\ | ||||||
|  |   Simd Chi_1;			\ | ||||||
|  |   Simd Chi_2;			\ | ||||||
|  | 				\ | ||||||
|  |   Simd U_00;			\ | ||||||
|  |   Simd U_10;			\ | ||||||
|  |   Simd U_20;			\ | ||||||
|  |   Simd U_01;			\ | ||||||
|  |   Simd U_11;			\ | ||||||
|  |   Simd U_21;			\ | ||||||
|  |   Simd U_02;			\ | ||||||
|  |   Simd U_12;			\ | ||||||
|  |   Simd U_22;			 | ||||||
|  |    | ||||||
|  |  | ||||||
| template <class Impl> | template <class Impl> | ||||||
| template <int Naik> accelerator_inline | template <int Naik> accelerator_inline | ||||||
| @@ -155,28 +195,14 @@ void StaggeredKernels<Impl>::DhopSiteHand(StencilView &st, | |||||||
|   typedef typename Simd::scalar_type S; |   typedef typename Simd::scalar_type S; | ||||||
|   typedef typename Simd::vector_type V; |   typedef typename Simd::vector_type V; | ||||||
|  |  | ||||||
|   Simd even_0; // 12 regs on knc |  | ||||||
|   Simd even_1; |  | ||||||
|   Simd even_2; |  | ||||||
|   Simd odd_0; // 12 regs on knc |  | ||||||
|   Simd odd_1; |  | ||||||
|   Simd odd_2; |  | ||||||
|  |  | ||||||
|   Simd Chi_0;    // two spinor; 6 regs |   const int Nsimd = SiteHalfSpinor::Nsimd(); | ||||||
|   Simd Chi_1; |   const int lane=acceleratorSIMTlane(Nsimd); | ||||||
|   Simd Chi_2; |   typedef decltype( coalescedRead( in[0]()()(0) )) Simt; | ||||||
|    |   HAND_DECLARATIONS(Simt); | ||||||
|   Simd U_00;  // two rows of U matrix |  | ||||||
|   Simd U_10; |  | ||||||
|   Simd U_20;   |  | ||||||
|   Simd U_01; |  | ||||||
|   Simd U_11; |  | ||||||
|   Simd U_21;  // 2 reg left. |  | ||||||
|   Simd U_02; |  | ||||||
|   Simd U_12; |  | ||||||
|   Simd U_22;  |  | ||||||
|  |  | ||||||
|   SiteSpinor result; |   typedef decltype( coalescedRead( in[0] )) calcSiteSpinor; | ||||||
|  |   calcSiteSpinor result; | ||||||
|   int offset,local,perm, ptype; |   int offset,local,perm, ptype; | ||||||
|  |  | ||||||
|   StencilEntry *SE; |   StencilEntry *SE; | ||||||
| @@ -215,7 +241,7 @@ void StaggeredKernels<Impl>::DhopSiteHand(StencilView &st, | |||||||
|       result()()(1) = even_1 + odd_1; |       result()()(1) = even_1 + odd_1; | ||||||
|       result()()(2) = even_2 + odd_2; |       result()()(2) = even_2 + odd_2; | ||||||
|     } |     } | ||||||
|     vstream(out[sF],result); |     coalescedWrite(out[sF],result); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -230,28 +256,13 @@ void StaggeredKernels<Impl>::DhopSiteHandInt(StencilView &st, | |||||||
|   typedef typename Simd::scalar_type S; |   typedef typename Simd::scalar_type S; | ||||||
|   typedef typename Simd::vector_type V; |   typedef typename Simd::vector_type V; | ||||||
|  |  | ||||||
|   Simd even_0; // 12 regs on knc |   const int Nsimd = SiteHalfSpinor::Nsimd(); | ||||||
|   Simd even_1; |   const int lane=acceleratorSIMTlane(Nsimd); | ||||||
|   Simd even_2; |   typedef decltype( coalescedRead( in[0]()()(0) )) Simt; | ||||||
|   Simd odd_0; // 12 regs on knc |   HAND_DECLARATIONS(Simt); | ||||||
|   Simd odd_1; |  | ||||||
|   Simd odd_2; |  | ||||||
|  |  | ||||||
|   Simd Chi_0;    // two spinor; 6 regs |   typedef decltype( coalescedRead( in[0] )) calcSiteSpinor; | ||||||
|   Simd Chi_1; |   calcSiteSpinor result; | ||||||
|   Simd Chi_2; |  | ||||||
|    |  | ||||||
|   Simd U_00;  // two rows of U matrix |  | ||||||
|   Simd U_10; |  | ||||||
|   Simd U_20;   |  | ||||||
|   Simd U_01; |  | ||||||
|   Simd U_11; |  | ||||||
|   Simd U_21;  // 2 reg left. |  | ||||||
|   Simd U_02; |  | ||||||
|   Simd U_12; |  | ||||||
|   Simd U_22;  |  | ||||||
|  |  | ||||||
|   SiteSpinor result; |  | ||||||
|   int offset, ptype, local, perm; |   int offset, ptype, local, perm; | ||||||
|  |  | ||||||
|   StencilEntry *SE; |   StencilEntry *SE; | ||||||
| @@ -261,8 +272,8 @@ void StaggeredKernels<Impl>::DhopSiteHandInt(StencilView &st, | |||||||
|   //    int sF=s+LLs*sU; |   //    int sF=s+LLs*sU; | ||||||
|   { |   { | ||||||
|  |  | ||||||
|     even_0 = Zero();    even_1 = Zero();    even_2 = Zero(); |     zeroit(even_0);    zeroit(even_1);    zeroit(even_2); | ||||||
|      odd_0 = Zero();     odd_1 = Zero();     odd_2 = Zero(); |     zeroit(odd_0);    zeroit(odd_1);    zeroit(odd_2); | ||||||
|  |  | ||||||
|     skew = 0; |     skew = 0; | ||||||
|     HAND_STENCIL_LEG_INT(U,Xp,3,skew,even);   |     HAND_STENCIL_LEG_INT(U,Xp,3,skew,even);   | ||||||
| @@ -294,7 +305,7 @@ void StaggeredKernels<Impl>::DhopSiteHandInt(StencilView &st, | |||||||
|       result()()(1) = even_1 + odd_1; |       result()()(1) = even_1 + odd_1; | ||||||
|       result()()(2) = even_2 + odd_2; |       result()()(2) = even_2 + odd_2; | ||||||
|     } |     } | ||||||
|     vstream(out[sF],result); |     coalescedWrite(out[sF],result); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -309,28 +320,13 @@ void StaggeredKernels<Impl>::DhopSiteHandExt(StencilView &st, | |||||||
|   typedef typename Simd::scalar_type S; |   typedef typename Simd::scalar_type S; | ||||||
|   typedef typename Simd::vector_type V; |   typedef typename Simd::vector_type V; | ||||||
|  |  | ||||||
|   Simd even_0; // 12 regs on knc |   const int Nsimd = SiteHalfSpinor::Nsimd(); | ||||||
|   Simd even_1; |   const int lane=acceleratorSIMTlane(Nsimd); | ||||||
|   Simd even_2; |   typedef decltype( coalescedRead( in[0]()()(0) )) Simt; | ||||||
|   Simd odd_0; // 12 regs on knc |   HAND_DECLARATIONS(Simt); | ||||||
|   Simd odd_1; |  | ||||||
|   Simd odd_2; |  | ||||||
|  |  | ||||||
|   Simd Chi_0;    // two spinor; 6 regs |   typedef decltype( coalescedRead( in[0] )) calcSiteSpinor; | ||||||
|   Simd Chi_1; |   calcSiteSpinor result; | ||||||
|   Simd Chi_2; |  | ||||||
|    |  | ||||||
|   Simd U_00;  // two rows of U matrix |  | ||||||
|   Simd U_10; |  | ||||||
|   Simd U_20;   |  | ||||||
|   Simd U_01; |  | ||||||
|   Simd U_11; |  | ||||||
|   Simd U_21;  // 2 reg left. |  | ||||||
|   Simd U_02; |  | ||||||
|   Simd U_12; |  | ||||||
|   Simd U_22;  |  | ||||||
|  |  | ||||||
|   SiteSpinor result; |  | ||||||
|   int offset, ptype, local; |   int offset, ptype, local; | ||||||
|  |  | ||||||
|   StencilEntry *SE; |   StencilEntry *SE; | ||||||
| @@ -340,8 +336,8 @@ void StaggeredKernels<Impl>::DhopSiteHandExt(StencilView &st, | |||||||
|   //    int sF=s+LLs*sU; |   //    int sF=s+LLs*sU; | ||||||
|   { |   { | ||||||
|  |  | ||||||
|     even_0 = Zero();    even_1 = Zero();    even_2 = Zero(); |     zeroit(even_0);    zeroit(even_1);    zeroit(even_2); | ||||||
|      odd_0 = Zero();     odd_1 = Zero();     odd_2 = Zero(); |     zeroit(odd_0);    zeroit(odd_1);    zeroit(odd_2); | ||||||
|     int nmu=0; |     int nmu=0; | ||||||
|     skew = 0; |     skew = 0; | ||||||
|     HAND_STENCIL_LEG_EXT(U,Xp,3,skew,even);   |     HAND_STENCIL_LEG_EXT(U,Xp,3,skew,even);   | ||||||
| @@ -374,7 +370,7 @@ void StaggeredKernels<Impl>::DhopSiteHandExt(StencilView &st, | |||||||
| 	result()()(1) = even_1 + odd_1; | 	result()()(1) = even_1 + odd_1; | ||||||
| 	result()()(2) = even_2 + odd_2; | 	result()()(2) = even_2 + odd_2; | ||||||
|       } |       } | ||||||
|       out[sF] = out[sF] + result; |       coalescedWrite(out[sF] , out(sF)+ result); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
| @@ -397,6 +393,7 @@ void StaggeredKernels<Impl>::DhopSiteHandExt(StencilView &st, | |||||||
| 						     const FermionFieldView &in, FermionFieldView &out, int dag); \ | 						     const FermionFieldView &in, FermionFieldView &out, int dag); \ | ||||||
| */ | */ | ||||||
| #undef LOAD_CHI | #undef LOAD_CHI | ||||||
|  | #undef HAND_DECLARATIONS | ||||||
|  |  | ||||||
| NAMESPACE_END(Grid); | NAMESPACE_END(Grid); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -35,39 +35,32 @@ NAMESPACE_BEGIN(Grid); | |||||||
| #define GENERIC_STENCIL_LEG(U,Dir,skew,multLink)		\ | #define GENERIC_STENCIL_LEG(U,Dir,skew,multLink)		\ | ||||||
|   SE = st.GetEntry(ptype, Dir+skew, sF);			\ |   SE = st.GetEntry(ptype, Dir+skew, sF);			\ | ||||||
|   if (SE->_is_local ) {						\ |   if (SE->_is_local ) {						\ | ||||||
|     if (SE->_permute) {						\ |     int perm= SE->_permute;						\ | ||||||
|       chi_p = χ						\ |     chi = coalescedReadPermute(in[SE->_offset],ptype,perm,lane);\ | ||||||
|       permute(chi,  in[SE->_offset], ptype);			\ |  | ||||||
|     } else {							\ |  | ||||||
|       chi_p = &in[SE->_offset];					\ |  | ||||||
|     }								\ |  | ||||||
|   } else {							\ |   } else {							\ | ||||||
|     chi_p = &buf[SE->_offset];					\ |     chi = coalescedRead(buf[SE->_offset],lane);			\ | ||||||
|   }								\ |   }								\ | ||||||
|   multLink(Uchi, U[sU], *chi_p, Dir);			 |   acceleratorSynchronise();					\ | ||||||
|  |   multLink(Uchi, U[sU], chi, Dir);			 | ||||||
|  |  | ||||||
| #define GENERIC_STENCIL_LEG_INT(U,Dir,skew,multLink)		\ | #define GENERIC_STENCIL_LEG_INT(U,Dir,skew,multLink)		\ | ||||||
|   SE = st.GetEntry(ptype, Dir+skew, sF);			\ |   SE = st.GetEntry(ptype, Dir+skew, sF);			\ | ||||||
|   if (SE->_is_local ) {						\ |   if (SE->_is_local ) {						\ | ||||||
|     if (SE->_permute) {						\ |     int perm= SE->_permute;						\ | ||||||
|       chi_p = χ						\ |     chi = coalescedReadPermute(in[SE->_offset],ptype,perm,lane);\ | ||||||
|       permute(chi,  in[SE->_offset], ptype);			\ |  | ||||||
|     } else {							\ |  | ||||||
|       chi_p = &in[SE->_offset];					\ |  | ||||||
|     }								\ |  | ||||||
|   } else if ( st.same_node[Dir] ) {				\ |   } else if ( st.same_node[Dir] ) {				\ | ||||||
|     chi_p = &buf[SE->_offset];					\ |     chi = coalescedRead(buf[SE->_offset],lane);                 \ | ||||||
|   }								\ |   }								\ | ||||||
|   if (SE->_is_local || st.same_node[Dir] ) {			\ |   if (SE->_is_local || st.same_node[Dir] ) {			\ | ||||||
|     multLink(Uchi, U[sU], *chi_p, Dir);				\ |     multLink(Uchi, U[sU], chi, Dir);				\ | ||||||
|   } |   } | ||||||
|  |  | ||||||
| #define GENERIC_STENCIL_LEG_EXT(U,Dir,skew,multLink)		\ | #define GENERIC_STENCIL_LEG_EXT(U,Dir,skew,multLink)		\ | ||||||
|   SE = st.GetEntry(ptype, Dir+skew, sF);			\ |   SE = st.GetEntry(ptype, Dir+skew, sF);			\ | ||||||
|   if ((!SE->_is_local) && (!st.same_node[Dir]) ) {		\ |   if ((!SE->_is_local) && (!st.same_node[Dir]) ) {		\ | ||||||
|     nmu++;							\ |     nmu++;							\ | ||||||
|     chi_p = &buf[SE->_offset];					\ |     chi = coalescedRead(buf[SE->_offset],lane);			\ | ||||||
|     multLink(Uchi, U[sU], *chi_p, Dir);				\ |     multLink(Uchi, U[sU], chi, Dir);				\ | ||||||
|   } |   } | ||||||
|  |  | ||||||
| template <class Impl> | template <class Impl> | ||||||
| @@ -84,12 +77,14 @@ void StaggeredKernels<Impl>::DhopSiteGeneric(StencilView &st, | |||||||
| 					     SiteSpinor *buf, int sF, int sU,  | 					     SiteSpinor *buf, int sF, int sU,  | ||||||
| 					     const FermionFieldView &in, FermionFieldView &out, int dag)  | 					     const FermionFieldView &in, FermionFieldView &out, int dag)  | ||||||
| { | { | ||||||
|   const SiteSpinor *chi_p; |   typedef decltype(coalescedRead(in[0])) calcSpinor; | ||||||
|   SiteSpinor chi; |   calcSpinor chi; | ||||||
|   SiteSpinor Uchi; |   calcSpinor Uchi; | ||||||
|   StencilEntry *SE; |   StencilEntry *SE; | ||||||
|   int ptype; |   int ptype; | ||||||
|   int skew; |   int skew; | ||||||
|  |   const int Nsimd = SiteHalfSpinor::Nsimd(); | ||||||
|  |   const int lane=acceleratorSIMTlane(Nsimd); | ||||||
|  |  | ||||||
|   //  for(int s=0;s<LLs;s++){ |   //  for(int s=0;s<LLs;s++){ | ||||||
|   // |   // | ||||||
| @@ -118,7 +113,7 @@ void StaggeredKernels<Impl>::DhopSiteGeneric(StencilView &st, | |||||||
|     if ( dag ) {  |     if ( dag ) {  | ||||||
|       Uchi = - Uchi; |       Uchi = - Uchi; | ||||||
|     }  |     }  | ||||||
|     vstream(out[sF], Uchi); |     coalescedWrite(out[sF], Uchi,lane); | ||||||
|   } |   } | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @@ -130,13 +125,16 @@ template <int Naik> accelerator_inline | |||||||
| void StaggeredKernels<Impl>::DhopSiteGenericInt(StencilView &st,  | void StaggeredKernels<Impl>::DhopSiteGenericInt(StencilView &st,  | ||||||
| 						DoubledGaugeFieldView &U, DoubledGaugeFieldView &UUU, | 						DoubledGaugeFieldView &U, DoubledGaugeFieldView &UUU, | ||||||
| 						SiteSpinor *buf, int sF, int sU,  | 						SiteSpinor *buf, int sF, int sU,  | ||||||
| 						const FermionFieldView &in, FermionFieldView &out,int dag) { | 						const FermionFieldView &in, FermionFieldView &out,int dag) | ||||||
|   const SiteSpinor *chi_p; | { | ||||||
|   SiteSpinor chi; |   typedef decltype(coalescedRead(in[0])) calcSpinor; | ||||||
|   SiteSpinor Uchi; |   calcSpinor chi; | ||||||
|  |   calcSpinor Uchi; | ||||||
|   StencilEntry *SE; |   StencilEntry *SE; | ||||||
|   int ptype; |   int ptype; | ||||||
|   int skew ; |   int skew ; | ||||||
|  |   const int Nsimd = SiteHalfSpinor::Nsimd(); | ||||||
|  |   const int lane=acceleratorSIMTlane(Nsimd); | ||||||
|  |  | ||||||
|   //  for(int s=0;s<LLs;s++){ |   //  for(int s=0;s<LLs;s++){ | ||||||
|   //    int sF=LLs*sU+s; |   //    int sF=LLs*sU+s; | ||||||
| @@ -165,7 +163,7 @@ void StaggeredKernels<Impl>::DhopSiteGenericInt(StencilView &st, | |||||||
|     if ( dag ) { |     if ( dag ) { | ||||||
|       Uchi = - Uchi; |       Uchi = - Uchi; | ||||||
|     } |     } | ||||||
|     vstream(out[sF], Uchi); |     coalescedWrite(out[sF], Uchi,lane); | ||||||
|   } |   } | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @@ -178,14 +176,17 @@ template <int Naik> accelerator_inline | |||||||
| void StaggeredKernels<Impl>::DhopSiteGenericExt(StencilView &st,  | void StaggeredKernels<Impl>::DhopSiteGenericExt(StencilView &st,  | ||||||
| 						DoubledGaugeFieldView &U, DoubledGaugeFieldView &UUU, | 						DoubledGaugeFieldView &U, DoubledGaugeFieldView &UUU, | ||||||
| 						SiteSpinor *buf, int sF, int sU, | 						SiteSpinor *buf, int sF, int sU, | ||||||
| 						const FermionFieldView &in, FermionFieldView &out,int dag) { | 						const FermionFieldView &in, FermionFieldView &out,int dag) | ||||||
|   const SiteSpinor *chi_p; | { | ||||||
|   //  SiteSpinor chi; |   typedef decltype(coalescedRead(in[0])) calcSpinor; | ||||||
|   SiteSpinor Uchi; |   calcSpinor chi; | ||||||
|  |   calcSpinor Uchi; | ||||||
|   StencilEntry *SE; |   StencilEntry *SE; | ||||||
|   int ptype; |   int ptype; | ||||||
|   int nmu=0; |   int nmu=0; | ||||||
|   int skew ; |   int skew ; | ||||||
|  |   const int Nsimd = SiteHalfSpinor::Nsimd(); | ||||||
|  |   const int lane=acceleratorSIMTlane(Nsimd); | ||||||
|  |  | ||||||
|   //  for(int s=0;s<LLs;s++){ |   //  for(int s=0;s<LLs;s++){ | ||||||
|   //    int sF=LLs*sU+s; |   //    int sF=LLs*sU+s; | ||||||
| @@ -211,11 +212,12 @@ void StaggeredKernels<Impl>::DhopSiteGenericExt(StencilView &st, | |||||||
|     GENERIC_STENCIL_LEG_EXT(UUU,Zm,skew,Impl::multLinkAdd); |     GENERIC_STENCIL_LEG_EXT(UUU,Zm,skew,Impl::multLinkAdd); | ||||||
|     GENERIC_STENCIL_LEG_EXT(UUU,Tm,skew,Impl::multLinkAdd); |     GENERIC_STENCIL_LEG_EXT(UUU,Tm,skew,Impl::multLinkAdd); | ||||||
|     } |     } | ||||||
|     if ( nmu ) {  |     if ( nmu ) { | ||||||
|       if ( dag ) {  |       auto _out = coalescedRead(out[sF],lane); | ||||||
| 	out[sF] = out[sF] - Uchi; |       if ( dag ) { | ||||||
|  | 	coalescedWrite(out[sF], _out-Uchi,lane); | ||||||
|       } else {  |       } else {  | ||||||
| 	out[sF] = out[sF] + Uchi; | 	coalescedWrite(out[sF], _out+Uchi,lane); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| @@ -261,6 +263,8 @@ void StaggeredKernels<Impl>::DhopImproved(StencilImpl &st, LebesgueOrder &lo, | |||||||
|   GridBase *FGrid=in.Grid();   |   GridBase *FGrid=in.Grid();   | ||||||
|   GridBase *UGrid=U.Grid();   |   GridBase *UGrid=U.Grid();   | ||||||
|   typedef StaggeredKernels<Impl> ThisKernel; |   typedef StaggeredKernels<Impl> ThisKernel; | ||||||
|  |   const int Nsimd = SiteHalfSpinor::Nsimd(); | ||||||
|  |   const int lane=acceleratorSIMTlane(Nsimd); | ||||||
|   autoView( UUU_v , UUU, AcceleratorRead); |   autoView( UUU_v , UUU, AcceleratorRead); | ||||||
|   autoView( U_v   ,   U, AcceleratorRead); |   autoView( U_v   ,   U, AcceleratorRead); | ||||||
|   autoView( in_v  ,  in, AcceleratorRead); |   autoView( in_v  ,  in, AcceleratorRead); | ||||||
| @@ -301,6 +305,8 @@ void StaggeredKernels<Impl>::DhopNaive(StencilImpl &st, LebesgueOrder &lo, | |||||||
|   GridBase *FGrid=in.Grid();   |   GridBase *FGrid=in.Grid();   | ||||||
|   GridBase *UGrid=U.Grid();   |   GridBase *UGrid=U.Grid();   | ||||||
|   typedef StaggeredKernels<Impl> ThisKernel; |   typedef StaggeredKernels<Impl> ThisKernel; | ||||||
|  |   const int Nsimd = SiteHalfSpinor::Nsimd(); | ||||||
|  |   const int lane=acceleratorSIMTlane(Nsimd); | ||||||
|   autoView( UUU_v ,   U, AcceleratorRead); |   autoView( UUU_v ,   U, AcceleratorRead); | ||||||
|   autoView( U_v   ,   U, AcceleratorRead); |   autoView( U_v   ,   U, AcceleratorRead); | ||||||
|   autoView( in_v  ,  in, AcceleratorRead); |   autoView( in_v  ,  in, AcceleratorRead); | ||||||
|   | |||||||
| @@ -92,20 +92,16 @@ void WilsonCloverFermion<Impl>::ImportGauge(const GaugeField &_Umu) | |||||||
|   int lvol = _Umu.Grid()->lSites(); |   int lvol = _Umu.Grid()->lSites(); | ||||||
|   int DimRep = Impl::Dimension; |   int DimRep = Impl::Dimension; | ||||||
|  |  | ||||||
|   Eigen::MatrixXcd EigenCloverOp = Eigen::MatrixXcd::Zero(Ns * DimRep, Ns * DimRep); |  | ||||||
|   Eigen::MatrixXcd EigenInvCloverOp = Eigen::MatrixXcd::Zero(Ns * DimRep, Ns * DimRep); |  | ||||||
|  |  | ||||||
|   Coordinate lcoor; |  | ||||||
|   typename SiteCloverType::scalar_object Qx = Zero(), Qxinv = Zero(); |  | ||||||
|  |  | ||||||
|   { |   { | ||||||
|     autoView(CTv,CloverTerm,CpuRead); |     autoView(CTv,CloverTerm,CpuRead); | ||||||
|     autoView(CTIv,CloverTermInv,CpuWrite); |     autoView(CTIv,CloverTermInv,CpuWrite); | ||||||
|     for (int site = 0; site < lvol; site++) { |     thread_for(site, lvol, { | ||||||
|  |       Coordinate lcoor; | ||||||
|       grid->LocalIndexToLocalCoor(site, lcoor); |       grid->LocalIndexToLocalCoor(site, lcoor); | ||||||
|       EigenCloverOp = Eigen::MatrixXcd::Zero(Ns * DimRep, Ns * DimRep); |       Eigen::MatrixXcd EigenCloverOp = Eigen::MatrixXcd::Zero(Ns * DimRep, Ns * DimRep); | ||||||
|  |       Eigen::MatrixXcd EigenInvCloverOp = Eigen::MatrixXcd::Zero(Ns * DimRep, Ns * DimRep); | ||||||
|  |       typename SiteCloverType::scalar_object Qx = Zero(), Qxinv = Zero(); | ||||||
|       peekLocalSite(Qx, CTv, lcoor); |       peekLocalSite(Qx, CTv, lcoor); | ||||||
|       Qxinv = Zero(); |  | ||||||
|       //if (csw!=0){ |       //if (csw!=0){ | ||||||
|       for (int j = 0; j < Ns; j++) |       for (int j = 0; j < Ns; j++) | ||||||
| 	for (int k = 0; k < Ns; k++) | 	for (int k = 0; k < Ns; k++) | ||||||
| @@ -126,7 +122,7 @@ void WilsonCloverFermion<Impl>::ImportGauge(const GaugeField &_Umu) | |||||||
|       //    if (site==0) std::cout << "site =" << site << "\n" << EigenInvCloverOp << std::endl; |       //    if (site==0) std::cout << "site =" << site << "\n" << EigenInvCloverOp << std::endl; | ||||||
|       //  } |       //  } | ||||||
|       pokeLocalSite(Qxinv, CTIv, lcoor); |       pokeLocalSite(Qxinv, CTIv, lcoor); | ||||||
|     } |     }); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   // Separate the even and odd parts |   // Separate the even and odd parts | ||||||
|   | |||||||
| @@ -51,9 +51,9 @@ WilsonFermion5D<Impl>::WilsonFermion5D(GaugeField &_Umu, | |||||||
|   _FiveDimRedBlackGrid(&FiveDimRedBlackGrid), |   _FiveDimRedBlackGrid(&FiveDimRedBlackGrid), | ||||||
|   _FourDimGrid        (&FourDimGrid), |   _FourDimGrid        (&FourDimGrid), | ||||||
|   _FourDimRedBlackGrid(&FourDimRedBlackGrid), |   _FourDimRedBlackGrid(&FourDimRedBlackGrid), | ||||||
|   Stencil    (_FiveDimGrid,npoint,Even,directions,displacements,p), |   Stencil    (_FiveDimGrid,npoint,Even,directions,displacements,p.locally_periodic,p), | ||||||
|   StencilEven(_FiveDimRedBlackGrid,npoint,Even,directions,displacements,p), // source is Even |   StencilEven(_FiveDimRedBlackGrid,npoint,Even,directions,displacements,p.locally_periodic,p), // source is Even | ||||||
|   StencilOdd (_FiveDimRedBlackGrid,npoint,Odd ,directions,displacements,p), // source is Odd |   StencilOdd (_FiveDimRedBlackGrid,npoint,Odd ,directions,displacements,p.locally_periodic,p), // source is Odd | ||||||
|   M5(_M5), |   M5(_M5), | ||||||
|   Umu(_FourDimGrid), |   Umu(_FourDimGrid), | ||||||
|   UmuEven(_FourDimRedBlackGrid), |   UmuEven(_FourDimRedBlackGrid), | ||||||
| @@ -361,10 +361,21 @@ void WilsonFermion5D<Impl>::DhopInternal(StencilImpl & st, LebesgueOrder &lo, | |||||||
|                                          const FermionField &in, FermionField &out,int dag) |                                          const FermionField &in, FermionField &out,int dag) | ||||||
| { | { | ||||||
|   DhopTotalTime-=usecond(); |   DhopTotalTime-=usecond(); | ||||||
|   if ( WilsonKernelsStatic::Comms == WilsonKernelsStatic::CommsAndCompute ) |  | ||||||
|  |   assert(  (WilsonKernelsStatic::Comms == WilsonKernelsStatic::CommsAndCompute) | ||||||
|  | 	 ||(WilsonKernelsStatic::Comms == WilsonKernelsStatic::CommsThenCompute) | ||||||
|  |          ||(WilsonKernelsStatic::Comms == WilsonKernelsStatic::CommsDirichlet) ); | ||||||
|  |  | ||||||
|  |   if ( WilsonKernelsStatic::Comms == WilsonKernelsStatic::CommsAndCompute ) { | ||||||
|     DhopInternalOverlappedComms(st,lo,U,in,out,dag); |     DhopInternalOverlappedComms(st,lo,U,in,out,dag); | ||||||
|   else  |   } | ||||||
|  |   if ( WilsonKernelsStatic::Comms == WilsonKernelsStatic::CommsThenCompute ) { | ||||||
|     DhopInternalSerialComms(st,lo,U,in,out,dag); |     DhopInternalSerialComms(st,lo,U,in,out,dag); | ||||||
|  |   } | ||||||
|  |   if ( WilsonKernelsStatic::Comms == WilsonKernelsStatic::CommsDirichlet ) { | ||||||
|  |     DhopInternalDirichletComms(st,lo,U,in,out,dag); | ||||||
|  |   } | ||||||
|  |    | ||||||
|   DhopTotalTime+=usecond(); |   DhopTotalTime+=usecond(); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -431,6 +442,30 @@ void WilsonFermion5D<Impl>::DhopInternalOverlappedComms(StencilImpl & st, Lebesg | |||||||
|   DhopComputeTime2+=usecond(); |   DhopComputeTime2+=usecond(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | template<class Impl> | ||||||
|  | void WilsonFermion5D<Impl>::DhopInternalDirichletComms(StencilImpl & st, LebesgueOrder &lo, | ||||||
|  | 						       DoubledGaugeField & U, | ||||||
|  | 						       const FermionField &in, FermionField &out,int dag) | ||||||
|  | { | ||||||
|  |   Compressor compressor(dag); | ||||||
|  |  | ||||||
|  |   int LLs = in.Grid()->_rdimensions[0]; | ||||||
|  |   int len =  U.Grid()->oSites(); | ||||||
|  |        | ||||||
|  |   ///////////////////////////// | ||||||
|  |   // do the compute interior | ||||||
|  |   ///////////////////////////// | ||||||
|  |   int Opt = WilsonKernelsStatic::Opt; // Why pass this. Kernels should know | ||||||
|  |   DhopComputeTime-=usecond(); | ||||||
|  |   if (dag == DaggerYes) { | ||||||
|  |     Kernels::DhopDagKernel(Opt,st,U,st.CommBuf(),LLs,U.oSites(),in,out,1,0); | ||||||
|  |   } else { | ||||||
|  |     Kernels::DhopKernel   (Opt,st,U,st.CommBuf(),LLs,U.oSites(),in,out,1,0); | ||||||
|  |   } | ||||||
|  |   accelerator_barrier(); | ||||||
|  |   DhopComputeTime+=usecond(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
| template<class Impl> | template<class Impl> | ||||||
| void WilsonFermion5D<Impl>::DhopInternalSerialComms(StencilImpl & st, LebesgueOrder &lo, | void WilsonFermion5D<Impl>::DhopInternalSerialComms(StencilImpl & st, LebesgueOrder &lo, | ||||||
|   | |||||||
| @@ -47,9 +47,9 @@ WilsonFermion<Impl>::WilsonFermion(GaugeField &_Umu, GridCartesian &Fgrid, | |||||||
|     Kernels(p), |     Kernels(p), | ||||||
|     _grid(&Fgrid), |     _grid(&Fgrid), | ||||||
|     _cbgrid(&Hgrid), |     _cbgrid(&Hgrid), | ||||||
|     Stencil(&Fgrid, npoint, Even, directions, displacements,p), |     Stencil(&Fgrid, npoint, Even, directions, displacements,p.locally_periodic,p), | ||||||
|     StencilEven(&Hgrid, npoint, Even, directions,displacements,p),  // source is Even |     StencilEven(&Hgrid, npoint, Even, directions,displacements,p.locally_periodic,p),  // source is Even | ||||||
|     StencilOdd(&Hgrid, npoint, Odd, directions,displacements,p),  // source is Odd |     StencilOdd(&Hgrid, npoint, Odd, directions,displacements,p.locally_periodic,p),  // source is Odd | ||||||
|     mass(_mass), |     mass(_mass), | ||||||
|     Lebesgue(_grid), |     Lebesgue(_grid), | ||||||
|     LebesgueEvenOdd(_cbgrid), |     LebesgueEvenOdd(_cbgrid), | ||||||
| @@ -397,6 +397,7 @@ void WilsonFermion<Impl>::DhopDerivEO(GaugeField &mat, const FermionField &U, co | |||||||
| template <class Impl> | template <class Impl> | ||||||
| void WilsonFermion<Impl>::Dhop(const FermionField &in, FermionField &out, int dag) | void WilsonFermion<Impl>::Dhop(const FermionField &in, FermionField &out, int dag) | ||||||
| { | { | ||||||
|  |   DhopCalls+=2; | ||||||
|   conformable(in.Grid(), _grid);  // verifies full grid |   conformable(in.Grid(), _grid);  // verifies full grid | ||||||
|   conformable(in.Grid(), out.Grid()); |   conformable(in.Grid(), out.Grid()); | ||||||
|  |  | ||||||
| @@ -408,6 +409,7 @@ void WilsonFermion<Impl>::Dhop(const FermionField &in, FermionField &out, int da | |||||||
| template <class Impl> | template <class Impl> | ||||||
| void WilsonFermion<Impl>::DhopOE(const FermionField &in, FermionField &out, int dag) | void WilsonFermion<Impl>::DhopOE(const FermionField &in, FermionField &out, int dag) | ||||||
| { | { | ||||||
|  |   DhopCalls++; | ||||||
|   conformable(in.Grid(), _cbgrid);    // verifies half grid |   conformable(in.Grid(), _cbgrid);    // verifies half grid | ||||||
|   conformable(in.Grid(), out.Grid());  // drops the cb check |   conformable(in.Grid(), out.Grid());  // drops the cb check | ||||||
|  |  | ||||||
| @@ -420,6 +422,7 @@ void WilsonFermion<Impl>::DhopOE(const FermionField &in, FermionField &out, int | |||||||
| template <class Impl> | template <class Impl> | ||||||
| void WilsonFermion<Impl>::DhopEO(const FermionField &in, FermionField &out,int dag) | void WilsonFermion<Impl>::DhopEO(const FermionField &in, FermionField &out,int dag) | ||||||
| { | { | ||||||
|  |   DhopCalls++; | ||||||
|   conformable(in.Grid(), _cbgrid);    // verifies half grid |   conformable(in.Grid(), _cbgrid);    // verifies half grid | ||||||
|   conformable(in.Grid(), out.Grid());  // drops the cb check |   conformable(in.Grid(), out.Grid());  // drops the cb check | ||||||
|  |  | ||||||
| @@ -485,12 +488,21 @@ void WilsonFermion<Impl>::DhopInternal(StencilImpl &st, LebesgueOrder &lo, | |||||||
|                                        FermionField &out, int dag) |                                        FermionField &out, int dag) | ||||||
| { | { | ||||||
|   DhopTotalTime-=usecond(); |   DhopTotalTime-=usecond(); | ||||||
| #ifdef GRID_OMP |  | ||||||
|   if ( WilsonKernelsStatic::Comms == WilsonKernelsStatic::CommsAndCompute ) |   assert(  (WilsonKernelsStatic::Comms == WilsonKernelsStatic::CommsAndCompute) | ||||||
|  | 	 ||(WilsonKernelsStatic::Comms == WilsonKernelsStatic::CommsThenCompute) | ||||||
|  |          ||(WilsonKernelsStatic::Comms == WilsonKernelsStatic::CommsDirichlet) ); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   if ( WilsonKernelsStatic::Comms == WilsonKernelsStatic::CommsAndCompute ) { | ||||||
|     DhopInternalOverlappedComms(st,lo,U,in,out,dag); |     DhopInternalOverlappedComms(st,lo,U,in,out,dag); | ||||||
|   else |   } | ||||||
| #endif |   if ( WilsonKernelsStatic::Comms == WilsonKernelsStatic::CommsThenCompute ) { | ||||||
|     DhopInternalSerial(st,lo,U,in,out,dag); |     DhopInternalSerial(st,lo,U,in,out,dag); | ||||||
|  |   } | ||||||
|  |   if ( WilsonKernelsStatic::Comms == WilsonKernelsStatic::CommsDirichlet ) { | ||||||
|  |     DhopInternalDirichletComms(st,lo,U,in,out,dag); | ||||||
|  |   } | ||||||
|   DhopTotalTime+=usecond(); |   DhopTotalTime+=usecond(); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -559,6 +571,29 @@ void WilsonFermion<Impl>::DhopInternalOverlappedComms(StencilImpl &st, LebesgueO | |||||||
|   DhopComputeTime2+=usecond(); |   DhopComputeTime2+=usecond(); | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | template <class Impl> | ||||||
|  | void WilsonFermion<Impl>::DhopInternalDirichletComms(StencilImpl &st, LebesgueOrder &lo, | ||||||
|  | 						     DoubledGaugeField &U, | ||||||
|  | 						     const FermionField &in, | ||||||
|  | 						     FermionField &out, int dag) | ||||||
|  | { | ||||||
|  |   assert((dag == DaggerNo) || (dag == DaggerYes)); | ||||||
|  |  | ||||||
|  |   Compressor compressor(dag); | ||||||
|  |   int len =  U.Grid()->oSites(); | ||||||
|  |  | ||||||
|  |   ///////////////////////////// | ||||||
|  |   // do the compute interior | ||||||
|  |   ///////////////////////////// | ||||||
|  |   int Opt = WilsonKernelsStatic::Opt; | ||||||
|  |   DhopComputeTime-=usecond(); | ||||||
|  |   if (dag == DaggerYes) { | ||||||
|  |     Kernels::DhopDagKernel(Opt,st,U,st.CommBuf(),1,U.oSites(),in,out,1,0); | ||||||
|  |   } else { | ||||||
|  |     Kernels::DhopKernel(Opt,st,U,st.CommBuf(),1,U.oSites(),in,out,1,0); | ||||||
|  |   } | ||||||
|  |   DhopComputeTime+=usecond(); | ||||||
|  | }; | ||||||
|  |  | ||||||
| template <class Impl> | template <class Impl> | ||||||
| void WilsonFermion<Impl>::DhopInternalSerial(StencilImpl &st, LebesgueOrder &lo, | void WilsonFermion<Impl>::DhopInternalSerial(StencilImpl &st, LebesgueOrder &lo, | ||||||
|   | |||||||
| @@ -38,9 +38,6 @@ Author: Nils Meyer  <nils.meyer@ur.de>  Regensburg University | |||||||
| // undefine everything related to kernels | // undefine everything related to kernels | ||||||
| #include <simd/Fujitsu_A64FX_undef.h> | #include <simd/Fujitsu_A64FX_undef.h> | ||||||
|  |  | ||||||
| // enable A64FX body |  | ||||||
| #define WILSONKERNELSASMBODYA64FX |  | ||||||
| //#pragma message("A64FX Dslash: WilsonKernelsAsmBodyA64FX.h") |  | ||||||
|  |  | ||||||
|     /////////////////////////////////////////////////////////// |     /////////////////////////////////////////////////////////// | ||||||
|     // If we are A64FX specialise the single precision routine |     // If we are A64FX specialise the single precision routine | ||||||
| @@ -63,119 +60,89 @@ Author: Nils Meyer  <nils.meyer@ur.de>  Regensburg University | |||||||
| #define INTERIOR_AND_EXTERIOR | #define INTERIOR_AND_EXTERIOR | ||||||
| #undef INTERIOR | #undef INTERIOR | ||||||
| #undef EXTERIOR | #undef EXTERIOR | ||||||
|  |  | ||||||
|  | #pragma GCC optimize ("-O3", "-fno-schedule-insns", "-fno-schedule-insns2") | ||||||
| template<> void | template<> void | ||||||
| WilsonKernels<WilsonImplF>::AsmDhopSite(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | WilsonKernels<WilsonImplF>::AsmDhopSite(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #if defined (WILSONKERNELSASMBODYA64FX) |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | ||||||
| #else |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
|  | #pragma GCC optimize ("-O3", "-fno-schedule-insns", "-fno-schedule-insns2") | ||||||
| template<> void | template<> void | ||||||
| WilsonKernels<ZWilsonImplF>::AsmDhopSite(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | WilsonKernels<ZWilsonImplF>::AsmDhopSite(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #if defined (WILSONKERNELSASMBODYA64FX) |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | ||||||
| #else |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| template<> void | //#pragma GCC optimize ("-O3", "-fno-schedule-insns", "-fno-schedule-insns2") | ||||||
| WilsonKernels<WilsonImplFH>::AsmDhopSite(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | //template<> void | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //WilsonKernels<WilsonImplFH>::AsmDhopSite(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| #if defined (WILSONKERNELSASMBODYA64FX) | //						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | ||||||
| #else |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#pragma GCC optimize ("-O3", "-fno-schedule-insns", "-fno-schedule-insns2") | ||||||
| #endif | //template<> void | ||||||
|  | //WilsonKernels<ZWilsonImplFH>::AsmDhopSite(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
|  | //						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
|  | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | ||||||
|  |  | ||||||
| template<> void |  | ||||||
| WilsonKernels<ZWilsonImplFH>::AsmDhopSite(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, |  | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) |  | ||||||
| #if defined (WILSONKERNELSASMBODYA64FX) |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> |  | ||||||
| #else |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #undef INTERIOR_AND_EXTERIOR | #undef INTERIOR_AND_EXTERIOR | ||||||
| #define INTERIOR | #define INTERIOR | ||||||
| #undef EXTERIOR | #undef EXTERIOR | ||||||
|  |  | ||||||
|  | #pragma GCC optimize ("-O3", "-fno-schedule-insns", "-fno-schedule-insns2") | ||||||
| template<> void | template<> void | ||||||
| WilsonKernels<WilsonImplF>::AsmDhopSiteInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | WilsonKernels<WilsonImplF>::AsmDhopSiteInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #if defined (WILSONKERNELSASMBODYA64FX) |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | ||||||
| #else |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
|  | #pragma GCC optimize ("-O3", "-fno-schedule-insns", "-fno-schedule-insns2") | ||||||
| template<> void | template<> void | ||||||
| WilsonKernels<ZWilsonImplF>::AsmDhopSiteInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | WilsonKernels<ZWilsonImplF>::AsmDhopSiteInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #if defined (WILSONKERNELSASMBODYA64FX) |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | ||||||
| #else |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| template<> void | //#pragma GCC optimize ("-O3", "-fno-schedule-insns", "-fno-schedule-insns2") | ||||||
| WilsonKernels<WilsonImplFH>::AsmDhopSiteInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | //template<> void | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //WilsonKernels<WilsonImplFH>::AsmDhopSiteInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| #if defined (WILSONKERNELSASMBODYA64FX) | //						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | ||||||
| #else |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#pragma GCC optimize ("-O3", "-fno-schedule-insns", "-fno-schedule-insns2") | ||||||
| #endif | //template<> void | ||||||
|  | //WilsonKernels<ZWilsonImplFH>::AsmDhopSiteInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
|  | //						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
|  | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | ||||||
|  |  | ||||||
| template<> void |  | ||||||
| WilsonKernels<ZWilsonImplFH>::AsmDhopSiteInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, |  | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) |  | ||||||
| #if defined (WILSONKERNELSASMBODYA64FX) |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> |  | ||||||
| #else |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #undef INTERIOR_AND_EXTERIOR | #undef INTERIOR_AND_EXTERIOR | ||||||
| #undef INTERIOR | #undef INTERIOR | ||||||
| #define EXTERIOR | #define EXTERIOR | ||||||
|  |  | ||||||
|  | #pragma GCC optimize ("-O3", "-fno-schedule-insns", "-fno-schedule-insns2") | ||||||
| template<> void | template<> void | ||||||
| WilsonKernels<WilsonImplF>::AsmDhopSiteExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | WilsonKernels<WilsonImplF>::AsmDhopSiteExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #if defined (WILSONKERNELSASMBODYA64FX) |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | ||||||
| #else |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
|  | #pragma GCC optimize ("-O3", "-fno-schedule-insns", "-fno-schedule-insns2") | ||||||
| template<> void | template<> void | ||||||
| WilsonKernels<ZWilsonImplF>::AsmDhopSiteExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | WilsonKernels<ZWilsonImplF>::AsmDhopSiteExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #if defined (WILSONKERNELSASMBODYA64FX) |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | ||||||
| #else |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| template<> void | //#pragma GCC optimize ("-O3", "-fno-schedule-insns", "-fno-schedule-insns2") | ||||||
| WilsonKernels<WilsonImplFH>::AsmDhopSiteExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | //template<> void | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //WilsonKernels<WilsonImplFH>::AsmDhopSiteExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| #if defined (WILSONKERNELSASMBODYA64FX) | //						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | ||||||
| #else |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#pragma GCC optimize ("-O3", "-fno-schedule-insns", "-fno-schedule-insns2") | ||||||
| #endif | //template<> void | ||||||
|  | //WilsonKernels<ZWilsonImplFH>::AsmDhopSiteExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
|  | //						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
|  | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | ||||||
|  |  | ||||||
| template<> void |  | ||||||
| WilsonKernels<ZWilsonImplFH>::AsmDhopSiteExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, |  | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) |  | ||||||
| #if defined (WILSONKERNELSASMBODYA64FX) |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> |  | ||||||
| #else |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
|  |  | ||||||
| ///////////////////////////////////////////////////////////////// | ///////////////////////////////////////////////////////////////// | ||||||
| @@ -185,119 +152,89 @@ WilsonKernels<ZWilsonImplFH>::AsmDhopSiteExt(StencilView &st, DoubledGaugeFieldV | |||||||
| #define INTERIOR_AND_EXTERIOR | #define INTERIOR_AND_EXTERIOR | ||||||
| #undef INTERIOR | #undef INTERIOR | ||||||
| #undef EXTERIOR | #undef EXTERIOR | ||||||
|  |  | ||||||
|  | #pragma GCC optimize ("-O3", "-fno-schedule-insns", "-fno-schedule-insns2") | ||||||
| template<> void | template<> void | ||||||
| WilsonKernels<WilsonImplF>::AsmDhopSiteDag(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | WilsonKernels<WilsonImplF>::AsmDhopSiteDag(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #if defined (WILSONKERNELSASMBODYA64FX) |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | ||||||
| #else |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
|  | #pragma GCC optimize ("-O3", "-fno-schedule-insns", "-fno-schedule-insns2") | ||||||
| template<> void | template<> void | ||||||
| WilsonKernels<ZWilsonImplF>::AsmDhopSiteDag(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | WilsonKernels<ZWilsonImplF>::AsmDhopSiteDag(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #if defined (WILSONKERNELSASMBODYA64FX) |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | ||||||
| #else |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| template<> void | //#pragma GCC optimize ("-O3", "-fno-schedule-insns", "-fno-schedule-insns2") | ||||||
| WilsonKernels<WilsonImplFH>::AsmDhopSiteDag(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | //template<> void | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //WilsonKernels<WilsonImplFH>::AsmDhopSiteDag(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| #if defined (WILSONKERNELSASMBODYA64FX) | //						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | ||||||
| #else |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#pragma GCC optimize ("-O3", "-fno-schedule-insns", "-fno-schedule-insns2") | ||||||
| #endif | //template<> void | ||||||
|  | //WilsonKernels<ZWilsonImplFH>::AsmDhopSiteDag(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
|  | //						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
|  | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | ||||||
|  |  | ||||||
| template<> void |  | ||||||
| WilsonKernels<ZWilsonImplFH>::AsmDhopSiteDag(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, |  | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) |  | ||||||
| #if defined (WILSONKERNELSASMBODYA64FX) |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> |  | ||||||
| #else |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #undef INTERIOR_AND_EXTERIOR | #undef INTERIOR_AND_EXTERIOR | ||||||
| #define INTERIOR | #define INTERIOR | ||||||
| #undef EXTERIOR | #undef EXTERIOR | ||||||
|  |  | ||||||
|  | #pragma GCC optimize ("-O3", "-fno-schedule-insns", "-fno-schedule-insns2") | ||||||
| template<> void | template<> void | ||||||
| WilsonKernels<WilsonImplF>::AsmDhopSiteDagInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | WilsonKernels<WilsonImplF>::AsmDhopSiteDagInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #if defined (WILSONKERNELSASMBODYA64FX) |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | ||||||
| #else |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
|  | #pragma GCC optimize ("-O3", "-fno-schedule-insns", "-fno-schedule-insns2") | ||||||
| template<> void | template<> void | ||||||
| WilsonKernels<ZWilsonImplF>::AsmDhopSiteDagInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | WilsonKernels<ZWilsonImplF>::AsmDhopSiteDagInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #if defined (WILSONKERNELSASMBODYA64FX) |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | ||||||
| #else |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| template<> void | //#pragma GCC optimize ("-O3", "-fno-schedule-insns", "-fno-schedule-insns2") | ||||||
| WilsonKernels<WilsonImplFH>::AsmDhopSiteDagInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | //template<> void | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //WilsonKernels<WilsonImplFH>::AsmDhopSiteDagInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| #if defined (WILSONKERNELSASMBODYA64FX) | //						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | ||||||
| #else |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#pragma GCC optimize ("-O3", "-fno-schedule-insns", "-fno-schedule-insns2") | ||||||
| #endif | //template<> void | ||||||
|  | //WilsonKernels<ZWilsonImplFH>::AsmDhopSiteDagInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
|  | //						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
|  | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | ||||||
|  |  | ||||||
| template<> void |  | ||||||
| WilsonKernels<ZWilsonImplFH>::AsmDhopSiteDagInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, |  | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) |  | ||||||
| #if defined (WILSONKERNELSASMBODYA64FX) |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> |  | ||||||
| #else |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #undef INTERIOR_AND_EXTERIOR | #undef INTERIOR_AND_EXTERIOR | ||||||
| #undef INTERIOR | #undef INTERIOR | ||||||
| #define EXTERIOR | #define EXTERIOR | ||||||
|  |  | ||||||
|  | #pragma GCC optimize ("-O3", "-fno-schedule-insns", "-fno-schedule-insns2") | ||||||
| template<> void | template<> void | ||||||
| WilsonKernels<WilsonImplF>::AsmDhopSiteDagExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | WilsonKernels<WilsonImplF>::AsmDhopSiteDagExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #if defined (WILSONKERNELSASMBODYA64FX) |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | ||||||
| #else |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
|  | #pragma GCC optimize ("-O3", "-fno-schedule-insns", "-fno-schedule-insns2") | ||||||
| template<> void | template<> void | ||||||
| WilsonKernels<ZWilsonImplF>::AsmDhopSiteDagExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | WilsonKernels<ZWilsonImplF>::AsmDhopSiteDagExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #if defined (WILSONKERNELSASMBODYA64FX) |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | ||||||
| #else |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| template<> void | //#pragma GCC optimize ("-O3", "-fno-schedule-insns", "-fno-schedule-insns2") | ||||||
| WilsonKernels<WilsonImplFH>::AsmDhopSiteDagExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | //template<> void | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //WilsonKernels<WilsonImplFH>::AsmDhopSiteDagExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| #if defined (WILSONKERNELSASMBODYA64FX) | //						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | ||||||
| #else |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#pragma GCC optimize ("-O3", "-fno-schedule-insns", "-fno-schedule-insns2") | ||||||
| #endif | //template<> void | ||||||
|  | //WilsonKernels<ZWilsonImplFH>::AsmDhopSiteDagExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
|  | //						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
|  | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | ||||||
|  |  | ||||||
| template<> void |  | ||||||
| WilsonKernels<ZWilsonImplFH>::AsmDhopSiteDagExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, |  | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) |  | ||||||
| #if defined (WILSONKERNELSASMBODYA64FX) |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> |  | ||||||
| #else |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
|  |  | ||||||
| // undefine | // undefine | ||||||
| @@ -330,119 +267,89 @@ WilsonKernels<ZWilsonImplFH>::AsmDhopSiteDagExt(StencilView &st, DoubledGaugeFie | |||||||
| #define INTERIOR_AND_EXTERIOR | #define INTERIOR_AND_EXTERIOR | ||||||
| #undef INTERIOR | #undef INTERIOR | ||||||
| #undef EXTERIOR | #undef EXTERIOR | ||||||
|  |  | ||||||
|  | #pragma GCC optimize ("-O3", "-fno-schedule-insns", "-fno-schedule-insns2") | ||||||
| template<> void | template<> void | ||||||
| WilsonKernels<WilsonImplD>::AsmDhopSite(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | WilsonKernels<WilsonImplD>::AsmDhopSite(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #if defined (WILSONKERNELSASMBODYA64FX) |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | ||||||
| #else |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
|  | #pragma GCC optimize ("-O3", "-fno-schedule-insns", "-fno-schedule-insns2") | ||||||
| template<> void | template<> void | ||||||
| WilsonKernels<ZWilsonImplD>::AsmDhopSite(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | WilsonKernels<ZWilsonImplD>::AsmDhopSite(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #if defined (WILSONKERNELSASMBODYA64FX) |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | ||||||
| #else |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| template<> void | // #pragma GCC optimize ("-O3", "-fno-schedule-insns", "-fno-schedule-insns2") | ||||||
| WilsonKernels<WilsonImplDF>::AsmDhopSite(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | // template<> void | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | // WilsonKernels<WilsonImplDF>::AsmDhopSite(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| #if defined (WILSONKERNELSASMBODYA64FX) | // 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | // #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | ||||||
| #else |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | // #pragma GCC optimize ("-O3", "-fno-schedule-insns", "-fno-schedule-insns2") | ||||||
| #endif | // template<> void | ||||||
|  | // WilsonKernels<ZWilsonImplDF>::AsmDhopSite(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
|  | // 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
|  | // #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | ||||||
|  |  | ||||||
| template<> void |  | ||||||
| WilsonKernels<ZWilsonImplDF>::AsmDhopSite(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, |  | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) |  | ||||||
| #if defined (WILSONKERNELSASMBODYA64FX) |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> |  | ||||||
| #else |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #undef INTERIOR_AND_EXTERIOR | #undef INTERIOR_AND_EXTERIOR | ||||||
| #define INTERIOR | #define INTERIOR | ||||||
| #undef EXTERIOR | #undef EXTERIOR | ||||||
|  |  | ||||||
|  | #pragma GCC optimize ("-O3", "-fno-schedule-insns", "-fno-schedule-insns2") | ||||||
| template<> void | template<> void | ||||||
| WilsonKernels<WilsonImplD>::AsmDhopSiteInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | WilsonKernels<WilsonImplD>::AsmDhopSiteInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #if defined (WILSONKERNELSASMBODYA64FX) |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | ||||||
| #else |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
|  | #pragma GCC optimize ("-O3", "-fno-schedule-insns", "-fno-schedule-insns2") | ||||||
| template<> void | template<> void | ||||||
| WilsonKernels<ZWilsonImplD>::AsmDhopSiteInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | WilsonKernels<ZWilsonImplD>::AsmDhopSiteInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #if defined (WILSONKERNELSASMBODYA64FX) |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | ||||||
| #else |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| template<> void | // #pragma GCC optimize ("-O3", "-fno-schedule-insns", "-fno-schedule-insns2") | ||||||
| WilsonKernels<WilsonImplDF>::AsmDhopSiteInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | // template<> void | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | // WilsonKernels<WilsonImplDF>::AsmDhopSiteInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| #if defined (WILSONKERNELSASMBODYA64FX) | // 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | // #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | ||||||
| #else |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | // #pragma GCC optimize ("-O3", "-fno-schedule-insns", "-fno-schedule-insns2") | ||||||
| #endif | // template<> void | ||||||
|  | // WilsonKernels<ZWilsonImplDF>::AsmDhopSiteInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
|  | // 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
|  | // #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | ||||||
|  |  | ||||||
| template<> void |  | ||||||
| WilsonKernels<ZWilsonImplDF>::AsmDhopSiteInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, |  | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) |  | ||||||
| #if defined (WILSONKERNELSASMBODYA64FX) |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> |  | ||||||
| #else |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #undef INTERIOR_AND_EXTERIOR | #undef INTERIOR_AND_EXTERIOR | ||||||
| #undef INTERIOR | #undef INTERIOR | ||||||
| #define EXTERIOR | #define EXTERIOR | ||||||
|  |  | ||||||
|  | #pragma GCC optimize ("-O3", "-fno-schedule-insns", "-fno-schedule-insns2") | ||||||
| template<> void | template<> void | ||||||
| WilsonKernels<WilsonImplD>::AsmDhopSiteExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | WilsonKernels<WilsonImplD>::AsmDhopSiteExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #if defined (WILSONKERNELSASMBODYA64FX) |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | ||||||
| #else |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
|  | #pragma GCC optimize ("-O3", "-fno-schedule-insns", "-fno-schedule-insns2") | ||||||
| template<> void | template<> void | ||||||
| WilsonKernels<ZWilsonImplD>::AsmDhopSiteExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | WilsonKernels<ZWilsonImplD>::AsmDhopSiteExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #if defined (WILSONKERNELSASMBODYA64FX) |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | ||||||
| #else |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| template<> void | // #pragma GCC optimize ("-O3", "-fno-schedule-insns", "-fno-schedule-insns2") | ||||||
| WilsonKernels<WilsonImplDF>::AsmDhopSiteExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | // template<> void | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | // WilsonKernels<WilsonImplDF>::AsmDhopSiteExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| #if defined (WILSONKERNELSASMBODYA64FX) | // 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | // #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | ||||||
| #else |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | // #pragma GCC optimize ("-O3", "-fno-schedule-insns", "-fno-schedule-insns2") | ||||||
| #endif | // template<> void | ||||||
|  | // WilsonKernels<ZWilsonImplDF>::AsmDhopSiteExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
|  | // 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
|  | // #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | ||||||
|  |  | ||||||
| template<> void |  | ||||||
| WilsonKernels<ZWilsonImplDF>::AsmDhopSiteExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, |  | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) |  | ||||||
| #if defined (WILSONKERNELSASMBODYA64FX) |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> |  | ||||||
| #else |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| ///////////////////////////////////////////////////////////////// | ///////////////////////////////////////////////////////////////// | ||||||
| // XYZT vectorised, dag Kernel, double | // XYZT vectorised, dag Kernel, double | ||||||
| @@ -451,124 +358,93 @@ WilsonKernels<ZWilsonImplDF>::AsmDhopSiteExt(StencilView &st, DoubledGaugeFieldV | |||||||
| #define INTERIOR_AND_EXTERIOR | #define INTERIOR_AND_EXTERIOR | ||||||
| #undef INTERIOR | #undef INTERIOR | ||||||
| #undef EXTERIOR | #undef EXTERIOR | ||||||
|  |  | ||||||
|  | #pragma GCC optimize ("-O3", "-fno-schedule-insns", "-fno-schedule-insns2") | ||||||
| template<> void | template<> void | ||||||
| WilsonKernels<WilsonImplD>::AsmDhopSiteDag(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | WilsonKernels<WilsonImplD>::AsmDhopSiteDag(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #if defined (WILSONKERNELSASMBODYA64FX) |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | ||||||
| #else |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
|  | #pragma GCC optimize ("-O3", "-fno-schedule-insns", "-fno-schedule-insns2") | ||||||
| template<> void | template<> void | ||||||
| WilsonKernels<ZWilsonImplD>::AsmDhopSiteDag(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | WilsonKernels<ZWilsonImplD>::AsmDhopSiteDag(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #if defined (WILSONKERNELSASMBODYA64FX) |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | ||||||
| #else |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| template<> void | // #pragma GCC optimize ("-O3", "-fno-schedule-insns", "-fno-schedule-insns2") | ||||||
| WilsonKernels<WilsonImplDF>::AsmDhopSiteDag(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | // template<> void | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | // WilsonKernels<WilsonImplDF>::AsmDhopSiteDag(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| #if defined (WILSONKERNELSASMBODYA64FX) | // 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | // #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | ||||||
| #else |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | // #pragma GCC optimize ("-O3", "-fno-schedule-insns", "-fno-schedule-insns2") | ||||||
| #endif | // template<> void | ||||||
|  | // WilsonKernels<ZWilsonImplDF>::AsmDhopSiteDag(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
|  | // 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
|  | // #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | ||||||
|  |  | ||||||
| template<> void |  | ||||||
| WilsonKernels<ZWilsonImplDF>::AsmDhopSiteDag(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, |  | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) |  | ||||||
| #if defined (WILSONKERNELSASMBODYA64FX) |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> |  | ||||||
| #else |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #undef INTERIOR_AND_EXTERIOR | #undef INTERIOR_AND_EXTERIOR | ||||||
| #define INTERIOR | #define INTERIOR | ||||||
| #undef EXTERIOR | #undef EXTERIOR | ||||||
|  |  | ||||||
|  | #pragma GCC optimize ("-O3", "-fno-schedule-insns", "-fno-schedule-insns2") | ||||||
| template<> void | template<> void | ||||||
| WilsonKernels<WilsonImplD>::AsmDhopSiteDagInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | WilsonKernels<WilsonImplD>::AsmDhopSiteDagInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #if defined (WILSONKERNELSASMBODYA64FX) |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | ||||||
| #else |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
|  | #pragma GCC optimize ("-O3", "-fno-schedule-insns", "-fno-schedule-insns2") | ||||||
| template<> void | template<> void | ||||||
| WilsonKernels<ZWilsonImplD>::AsmDhopSiteDagInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | WilsonKernels<ZWilsonImplD>::AsmDhopSiteDagInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #if defined (WILSONKERNELSASMBODYA64FX) |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | ||||||
| #else |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| template<> void | // #pragma GCC optimize ("-O3", "-fno-schedule-insns", "-fno-schedule-insns2") | ||||||
| WilsonKernels<WilsonImplDF>::AsmDhopSiteDagInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | // template<> void | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | // WilsonKernels<WilsonImplDF>::AsmDhopSiteDagInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| #if defined (WILSONKERNELSASMBODYA64FX) | // 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | // #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | ||||||
| #else |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | // #pragma GCC optimize ("-O3", "-fno-schedule-insns", "-fno-schedule-insns2") | ||||||
| #endif | // template<> void | ||||||
|  | // WilsonKernels<ZWilsonImplDF>::AsmDhopSiteDagInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
|  | // 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
|  | // #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | ||||||
|  |  | ||||||
| template<> void |  | ||||||
| WilsonKernels<ZWilsonImplDF>::AsmDhopSiteDagInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, |  | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) |  | ||||||
| #if defined (WILSONKERNELSASMBODYA64FX) |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> |  | ||||||
| #else |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #undef INTERIOR_AND_EXTERIOR | #undef INTERIOR_AND_EXTERIOR | ||||||
| #undef INTERIOR | #undef INTERIOR | ||||||
| #define EXTERIOR | #define EXTERIOR | ||||||
|  |  | ||||||
|  | #pragma GCC optimize ("-O3", "-fno-schedule-insns", "-fno-schedule-insns2") | ||||||
| template<> void | template<> void | ||||||
| WilsonKernels<WilsonImplD>::AsmDhopSiteDagExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | WilsonKernels<WilsonImplD>::AsmDhopSiteDagExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #if defined (WILSONKERNELSASMBODYA64FX) |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | ||||||
| #else |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
|  | #pragma GCC optimize ("-O3", "-fno-schedule-insns", "-fno-schedule-insns2") | ||||||
| template<> void | template<> void | ||||||
| WilsonKernels<ZWilsonImplD>::AsmDhopSiteDagExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | WilsonKernels<ZWilsonImplD>::AsmDhopSiteDagExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #if defined (WILSONKERNELSASMBODYA64FX) |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | ||||||
| #else |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| template<> void | // #pragma GCC optimize ("-O3", "-fno-schedule-insns", "-fno-schedule-insns2") | ||||||
| WilsonKernels<WilsonImplDF>::AsmDhopSiteDagExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | // template<> void | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | // WilsonKernels<WilsonImplDF>::AsmDhopSiteDagExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| #if defined (WILSONKERNELSASMBODYA64FX) | // 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | // #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | ||||||
| #else |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | // #pragma GCC optimize ("-O3", "-fno-schedule-insns", "-fno-schedule-insns2") | ||||||
| #endif | // template<> void | ||||||
|  | // WilsonKernels<ZWilsonImplDF>::AsmDhopSiteDagExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
|  | // 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
|  | // #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> | ||||||
|  |  | ||||||
| template<> void |  | ||||||
| WilsonKernels<ZWilsonImplDF>::AsmDhopSiteDagExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, |  | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) |  | ||||||
| #if defined (WILSONKERNELSASMBODYA64FX) |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBodyA64FX.h> |  | ||||||
| #else |  | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| // undefs | // undefs | ||||||
| #undef WILSONKERNELSASMBODYA64FX |  | ||||||
| #include <simd/Fujitsu_A64FX_undef.h> | #include <simd/Fujitsu_A64FX_undef.h> | ||||||
|  |  | ||||||
| #endif //A64FXASM | #endif //A64FXASM | ||||||
|   | |||||||
| @@ -74,15 +74,15 @@ WilsonKernels<ZWilsonImplF>::AsmDhopSite(StencilView &st, DoubledGaugeFieldView | |||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
|  |  | ||||||
| template<> void  | //template<> void | ||||||
| WilsonKernels<WilsonImplFH>::AsmDhopSite(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | //WilsonKernels<WilsonImplFH>::AsmDhopSite(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
|  | // | ||||||
| template<> void  | //template<> void | ||||||
| WilsonKernels<ZWilsonImplFH>::AsmDhopSite(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | //WilsonKernels<ZWilsonImplFH>::AsmDhopSite(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
|  |  | ||||||
| #undef INTERIOR_AND_EXTERIOR | #undef INTERIOR_AND_EXTERIOR | ||||||
| #define INTERIOR | #define INTERIOR | ||||||
| @@ -97,15 +97,15 @@ WilsonKernels<ZWilsonImplF>::AsmDhopSiteInt(StencilView &st, DoubledGaugeFieldVi | |||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
|  |  | ||||||
| template<> void  | //template<> void | ||||||
| WilsonKernels<WilsonImplFH>::AsmDhopSiteInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | //WilsonKernels<WilsonImplFH>::AsmDhopSiteInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
|  | // | ||||||
| template<> void  | //template<> void | ||||||
| WilsonKernels<ZWilsonImplFH>::AsmDhopSiteInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | //WilsonKernels<ZWilsonImplFH>::AsmDhopSiteInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
|  |  | ||||||
|  |  | ||||||
| #undef INTERIOR_AND_EXTERIOR | #undef INTERIOR_AND_EXTERIOR | ||||||
| @@ -121,15 +121,15 @@ WilsonKernels<ZWilsonImplF>::AsmDhopSiteExt(StencilView &st, DoubledGaugeFieldVi | |||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
|  |  | ||||||
| template<> void  | //template<> void | ||||||
| WilsonKernels<WilsonImplFH>::AsmDhopSiteExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | //WilsonKernels<WilsonImplFH>::AsmDhopSiteExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
|  | // | ||||||
| template<> void  | //template<> void | ||||||
| WilsonKernels<ZWilsonImplFH>::AsmDhopSiteExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | //WilsonKernels<ZWilsonImplFH>::AsmDhopSiteExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
|        |        | ||||||
| ///////////////////////////////////////////////////////////////// | ///////////////////////////////////////////////////////////////// | ||||||
| // XYZT vectorised, dag Kernel, single | // XYZT vectorised, dag Kernel, single | ||||||
| @@ -148,15 +148,15 @@ WilsonKernels<ZWilsonImplF>::AsmDhopSiteDag(StencilView &st, DoubledGaugeFieldVi | |||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
|  |  | ||||||
| template<> void  | //template<> void | ||||||
| WilsonKernels<WilsonImplFH>::AsmDhopSiteDag(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | //WilsonKernels<WilsonImplFH>::AsmDhopSiteDag(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
|  | // | ||||||
| template<> void  | //template<> void | ||||||
| WilsonKernels<ZWilsonImplFH>::AsmDhopSiteDag(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | //WilsonKernels<ZWilsonImplFH>::AsmDhopSiteDag(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
|  |  | ||||||
| #undef INTERIOR_AND_EXTERIOR | #undef INTERIOR_AND_EXTERIOR | ||||||
| #define INTERIOR | #define INTERIOR | ||||||
| @@ -171,15 +171,15 @@ WilsonKernels<ZWilsonImplF>::AsmDhopSiteDagInt(StencilView &st, DoubledGaugeFiel | |||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
|  |  | ||||||
| template<> void  | //template<> void | ||||||
| WilsonKernels<WilsonImplFH>::AsmDhopSiteDagInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | //WilsonKernels<WilsonImplFH>::AsmDhopSiteDagInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
|  | // | ||||||
| template<> void  | //template<> void | ||||||
| WilsonKernels<ZWilsonImplFH>::AsmDhopSiteDagInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | //WilsonKernels<ZWilsonImplFH>::AsmDhopSiteDagInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
|  |  | ||||||
| #undef INTERIOR_AND_EXTERIOR | #undef INTERIOR_AND_EXTERIOR | ||||||
| #undef INTERIOR | #undef INTERIOR | ||||||
| @@ -194,15 +194,15 @@ WilsonKernels<ZWilsonImplF>::AsmDhopSiteDagExt(StencilView &st, DoubledGaugeFiel | |||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
| 				     | 				     | ||||||
| template<> void  | //template<> void | ||||||
| WilsonKernels<WilsonImplFH>::AsmDhopSiteDagExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | //WilsonKernels<WilsonImplFH>::AsmDhopSiteDagExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
| 				     | // | ||||||
| template<> void  | //template<> void | ||||||
| WilsonKernels<ZWilsonImplFH>::AsmDhopSiteDagExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | //WilsonKernels<ZWilsonImplFH>::AsmDhopSiteDagExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
| 				     | 				     | ||||||
| #undef MAYBEPERM | #undef MAYBEPERM | ||||||
| #undef MULT_2SPIN | #undef MULT_2SPIN | ||||||
| @@ -228,14 +228,14 @@ WilsonKernels<ZDomainWallVec5dImplF>::AsmDhopSite(StencilView &st, DoubledGaugeF | |||||||
| 							 int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | 							 int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
|  |  | ||||||
| template<> void  | //template<> void | ||||||
| WilsonKernels<DomainWallVec5dImplFH>::AsmDhopSite(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | //WilsonKernels<DomainWallVec5dImplFH>::AsmDhopSite(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 							 int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //							 int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
| template<> void  | //template<> void | ||||||
| WilsonKernels<ZDomainWallVec5dImplFH>::AsmDhopSite(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | //WilsonKernels<ZDomainWallVec5dImplFH>::AsmDhopSite(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 							 int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //							 int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
|  |  | ||||||
| #undef INTERIOR_AND_EXTERIOR | #undef INTERIOR_AND_EXTERIOR | ||||||
| #define INTERIOR | #define INTERIOR | ||||||
| @@ -249,14 +249,14 @@ WilsonKernels<ZDomainWallVec5dImplF>::AsmDhopSiteInt(StencilView &st, DoubledGau | |||||||
| 							 int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | 							 int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
|  |  | ||||||
| template<> void  | //template<> void | ||||||
| WilsonKernels<DomainWallVec5dImplFH>::AsmDhopSiteInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | //WilsonKernels<DomainWallVec5dImplFH>::AsmDhopSiteInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 							 int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //							 int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
| template<> void  | //template<> void | ||||||
| WilsonKernels<ZDomainWallVec5dImplFH>::AsmDhopSiteInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | //WilsonKernels<ZDomainWallVec5dImplFH>::AsmDhopSiteInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 							 int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //							 int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
|  |  | ||||||
| #undef INTERIOR_AND_EXTERIOR | #undef INTERIOR_AND_EXTERIOR | ||||||
| #undef INTERIOR | #undef INTERIOR | ||||||
| @@ -273,15 +273,15 @@ WilsonKernels<ZDomainWallVec5dImplF>::AsmDhopSiteExt(StencilView &st, DoubledGau | |||||||
| 							 int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | 							 int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
| 				     | 				     | ||||||
| template<> void  | //template<> void | ||||||
| WilsonKernels<DomainWallVec5dImplFH>::AsmDhopSiteExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | //WilsonKernels<DomainWallVec5dImplFH>::AsmDhopSiteExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 							 int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //							 int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
| 				     | // | ||||||
| template<> void  | //template<> void | ||||||
| WilsonKernels<ZDomainWallVec5dImplFH>::AsmDhopSiteExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | //WilsonKernels<ZDomainWallVec5dImplFH>::AsmDhopSiteExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 							 int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //							 int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
| 				     | 				     | ||||||
| ///////////////////////////////////////////////////////////////// | ///////////////////////////////////////////////////////////////// | ||||||
| // Ls vectorised, dag Kernel, single | // Ls vectorised, dag Kernel, single | ||||||
| @@ -299,14 +299,14 @@ WilsonKernels<ZDomainWallVec5dImplF>::AsmDhopSiteDag(StencilView &st, DoubledGau | |||||||
| 							    int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | 							    int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
|  |  | ||||||
| template<> void  | //template<> void | ||||||
| WilsonKernels<DomainWallVec5dImplFH>::AsmDhopSiteDag(StencilView &st, DoubledGaugeFieldView &U,SiteHalfSpinor *buf, | //WilsonKernels<DomainWallVec5dImplFH>::AsmDhopSiteDag(StencilView &st, DoubledGaugeFieldView &U,SiteHalfSpinor *buf, | ||||||
| 							    int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //							    int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
| template<> void  | //template<> void | ||||||
| WilsonKernels<ZDomainWallVec5dImplFH>::AsmDhopSiteDag(StencilView &st, DoubledGaugeFieldView &U,SiteHalfSpinor *buf, | //WilsonKernels<ZDomainWallVec5dImplFH>::AsmDhopSiteDag(StencilView &st, DoubledGaugeFieldView &U,SiteHalfSpinor *buf, | ||||||
| 							    int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //							    int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
|  |  | ||||||
| #undef INTERIOR_AND_EXTERIOR | #undef INTERIOR_AND_EXTERIOR | ||||||
| #define INTERIOR | #define INTERIOR | ||||||
| @@ -320,14 +320,14 @@ WilsonKernels<ZDomainWallVec5dImplF>::AsmDhopSiteDagInt(StencilView &st, Doubled | |||||||
| 							    int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | 							    int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
|  |  | ||||||
| template<> void  | //template<> void | ||||||
| WilsonKernels<DomainWallVec5dImplFH>::AsmDhopSiteDagInt(StencilView &st, DoubledGaugeFieldView &U,SiteHalfSpinor *buf, | //WilsonKernels<DomainWallVec5dImplFH>::AsmDhopSiteDagInt(StencilView &st, DoubledGaugeFieldView &U,SiteHalfSpinor *buf, | ||||||
| 							    int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //							    int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
| template<> void  | //template<> void | ||||||
| WilsonKernels<ZDomainWallVec5dImplFH>::AsmDhopSiteDagInt(StencilView &st, DoubledGaugeFieldView &U,SiteHalfSpinor *buf, | //WilsonKernels<ZDomainWallVec5dImplFH>::AsmDhopSiteDagInt(StencilView &st, DoubledGaugeFieldView &U,SiteHalfSpinor *buf, | ||||||
| 							    int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //							    int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
|  |  | ||||||
| #undef INTERIOR_AND_EXTERIOR | #undef INTERIOR_AND_EXTERIOR | ||||||
| #undef INTERIOR | #undef INTERIOR | ||||||
| @@ -341,14 +341,14 @@ WilsonKernels<ZDomainWallVec5dImplF>::AsmDhopSiteDagExt(StencilView &st, Doubled | |||||||
| 							    int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | 							    int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
|  |  | ||||||
| template<> void  | //template<> void | ||||||
| WilsonKernels<DomainWallVec5dImplFH>::AsmDhopSiteDagExt(StencilView &st, DoubledGaugeFieldView &U,SiteHalfSpinor *buf, | //WilsonKernels<DomainWallVec5dImplFH>::AsmDhopSiteDagExt(StencilView &st, DoubledGaugeFieldView &U,SiteHalfSpinor *buf, | ||||||
| 							    int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //							    int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
| template<> void  | //template<> void | ||||||
| WilsonKernels<ZDomainWallVec5dImplFH>::AsmDhopSiteDagExt(StencilView &st, DoubledGaugeFieldView &U,SiteHalfSpinor *buf, | //WilsonKernels<ZDomainWallVec5dImplFH>::AsmDhopSiteDagExt(StencilView &st, DoubledGaugeFieldView &U,SiteHalfSpinor *buf, | ||||||
| 							    int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //							    int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
|  |  | ||||||
| #endif  // VEC 5D | #endif  // VEC 5D | ||||||
|  |  | ||||||
| @@ -392,14 +392,14 @@ WilsonKernels<ZWilsonImplD>::AsmDhopSite(StencilView &st, DoubledGaugeFieldView | |||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
|  |  | ||||||
| template<> void  | //template<> void | ||||||
| WilsonKernels<WilsonImplDF>::AsmDhopSite(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | //WilsonKernels<WilsonImplDF>::AsmDhopSite(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
| template<> void  | //template<> void | ||||||
| WilsonKernels<ZWilsonImplDF>::AsmDhopSite(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | //WilsonKernels<ZWilsonImplDF>::AsmDhopSite(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
|  |  | ||||||
| #undef INTERIOR_AND_EXTERIOR | #undef INTERIOR_AND_EXTERIOR | ||||||
| #define INTERIOR | #define INTERIOR | ||||||
| @@ -413,14 +413,14 @@ WilsonKernels<ZWilsonImplD>::AsmDhopSiteInt(StencilView &st, DoubledGaugeFieldVi | |||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
|  |  | ||||||
| template<> void  | //template<> void | ||||||
| WilsonKernels<WilsonImplDF>::AsmDhopSiteInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | //WilsonKernels<WilsonImplDF>::AsmDhopSiteInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
| template<> void  | //template<> void | ||||||
| WilsonKernels<ZWilsonImplDF>::AsmDhopSiteInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | //WilsonKernels<ZWilsonImplDF>::AsmDhopSiteInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
|  |  | ||||||
| #undef INTERIOR_AND_EXTERIOR | #undef INTERIOR_AND_EXTERIOR | ||||||
| #undef INTERIOR | #undef INTERIOR | ||||||
| @@ -434,14 +434,14 @@ WilsonKernels<ZWilsonImplD>::AsmDhopSiteExt(StencilView &st, DoubledGaugeFieldVi | |||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
|        |        | ||||||
| template<> void  | //template<> void | ||||||
| WilsonKernels<WilsonImplDF>::AsmDhopSiteExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | //WilsonKernels<WilsonImplDF>::AsmDhopSiteExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
| template<> void  | //template<> void | ||||||
| WilsonKernels<ZWilsonImplDF>::AsmDhopSiteExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | //WilsonKernels<ZWilsonImplDF>::AsmDhopSiteExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
|        |        | ||||||
| ///////////////////////////////////////////////////////////////// | ///////////////////////////////////////////////////////////////// | ||||||
| // XYZT vectorised, dag Kernel, single | // XYZT vectorised, dag Kernel, single | ||||||
| @@ -459,14 +459,14 @@ WilsonKernels<ZWilsonImplD>::AsmDhopSiteDag(StencilView &st, DoubledGaugeFieldVi | |||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
|  |  | ||||||
| template<> void  | //template<> void | ||||||
| WilsonKernels<WilsonImplDF>::AsmDhopSiteDag(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | //WilsonKernels<WilsonImplDF>::AsmDhopSiteDag(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
| template<> void  | //template<> void | ||||||
| WilsonKernels<ZWilsonImplDF>::AsmDhopSiteDag(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | //WilsonKernels<ZWilsonImplDF>::AsmDhopSiteDag(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
|  |  | ||||||
| #undef INTERIOR_AND_EXTERIOR | #undef INTERIOR_AND_EXTERIOR | ||||||
| #define INTERIOR | #define INTERIOR | ||||||
| @@ -480,14 +480,14 @@ WilsonKernels<ZWilsonImplD>::AsmDhopSiteDagInt(StencilView &st, DoubledGaugeFiel | |||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
|  |  | ||||||
| template<> void  | //template<> void | ||||||
| WilsonKernels<WilsonImplDF>::AsmDhopSiteDagInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | //WilsonKernels<WilsonImplDF>::AsmDhopSiteDagInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
| template<> void  | //template<> void | ||||||
| WilsonKernels<ZWilsonImplDF>::AsmDhopSiteDagInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | //WilsonKernels<ZWilsonImplDF>::AsmDhopSiteDagInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
|  |  | ||||||
| #undef INTERIOR_AND_EXTERIOR | #undef INTERIOR_AND_EXTERIOR | ||||||
| #undef INTERIOR | #undef INTERIOR | ||||||
| @@ -501,14 +501,14 @@ WilsonKernels<ZWilsonImplD>::AsmDhopSiteDagExt(StencilView &st, DoubledGaugeFiel | |||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
| 				     | 				     | ||||||
| template<> void  | //template<> void | ||||||
| WilsonKernels<WilsonImplDF>::AsmDhopSiteDagExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | //WilsonKernels<WilsonImplDF>::AsmDhopSiteDagExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
| template<> void  | //template<> void | ||||||
| WilsonKernels<ZWilsonImplDF>::AsmDhopSiteDagExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | //WilsonKernels<ZWilsonImplDF>::AsmDhopSiteDagExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //						int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
| 				     | 				     | ||||||
| #undef MAYBEPERM | #undef MAYBEPERM | ||||||
| #undef MULT_2SPIN | #undef MULT_2SPIN | ||||||
| @@ -533,14 +533,14 @@ WilsonKernels<ZDomainWallVec5dImplD>::AsmDhopSite(StencilView &st, DoubledGaugeF | |||||||
| 							 int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | 							 int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
|  |  | ||||||
| template<> void  | //template<> void | ||||||
| WilsonKernels<DomainWallVec5dImplDF>::AsmDhopSite(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | //WilsonKernels<DomainWallVec5dImplDF>::AsmDhopSite(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 							 int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //							 int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
| template<> void  | //template<> void | ||||||
| WilsonKernels<ZDomainWallVec5dImplDF>::AsmDhopSite(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | //WilsonKernels<ZDomainWallVec5dImplDF>::AsmDhopSite(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 							 int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //							 int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
|  |  | ||||||
| #undef INTERIOR_AND_EXTERIOR | #undef INTERIOR_AND_EXTERIOR | ||||||
| #define INTERIOR | #define INTERIOR | ||||||
| @@ -554,14 +554,14 @@ WilsonKernels<ZDomainWallVec5dImplD>::AsmDhopSiteInt(StencilView &st, DoubledGau | |||||||
| 							 int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | 							 int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
|  |  | ||||||
| template<> void  | //template<> void | ||||||
| WilsonKernels<DomainWallVec5dImplDF>::AsmDhopSiteInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | //WilsonKernels<DomainWallVec5dImplDF>::AsmDhopSiteInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 							 int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //							 int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
| template<> void  | //template<> void | ||||||
| WilsonKernels<ZDomainWallVec5dImplDF>::AsmDhopSiteInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | //WilsonKernels<ZDomainWallVec5dImplDF>::AsmDhopSiteInt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 							 int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //							 int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
|  |  | ||||||
| #undef INTERIOR_AND_EXTERIOR | #undef INTERIOR_AND_EXTERIOR | ||||||
| #undef INTERIOR | #undef INTERIOR | ||||||
| @@ -577,14 +577,14 @@ WilsonKernels<ZDomainWallVec5dImplD>::AsmDhopSiteExt(StencilView &st, DoubledGau | |||||||
| 							 int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | 							 int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
| 				     | 				     | ||||||
| template<> void  | //template<> void | ||||||
| WilsonKernels<DomainWallVec5dImplDF>::AsmDhopSiteExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | //WilsonKernels<DomainWallVec5dImplDF>::AsmDhopSiteExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 							 int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //							 int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
| template<> void  | //template<> void | ||||||
| WilsonKernels<ZDomainWallVec5dImplDF>::AsmDhopSiteExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | //WilsonKernels<ZDomainWallVec5dImplDF>::AsmDhopSiteExt(StencilView &st, DoubledGaugeFieldView &U, SiteHalfSpinor *buf, | ||||||
| 							 int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //							 int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
| 				     | 				     | ||||||
| ///////////////////////////////////////////////////////////////// | ///////////////////////////////////////////////////////////////// | ||||||
| // Ls vectorised, dag Kernel, single | // Ls vectorised, dag Kernel, single | ||||||
| @@ -602,14 +602,14 @@ WilsonKernels<ZDomainWallVec5dImplD>::AsmDhopSiteDag(StencilView &st, DoubledGau | |||||||
| 							    int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | 							    int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
|  |  | ||||||
| template<> void  | //template<> void | ||||||
| WilsonKernels<DomainWallVec5dImplDF>::AsmDhopSiteDag(StencilView &st, DoubledGaugeFieldView &U,SiteHalfSpinor *buf, | //WilsonKernels<DomainWallVec5dImplDF>::AsmDhopSiteDag(StencilView &st, DoubledGaugeFieldView &U,SiteHalfSpinor *buf, | ||||||
| 							    int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //							    int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
| template<> void  | //template<> void | ||||||
| WilsonKernels<ZDomainWallVec5dImplDF>::AsmDhopSiteDag(StencilView &st, DoubledGaugeFieldView &U,SiteHalfSpinor *buf, | //WilsonKernels<ZDomainWallVec5dImplDF>::AsmDhopSiteDag(StencilView &st, DoubledGaugeFieldView &U,SiteHalfSpinor *buf, | ||||||
| 							    int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //							    int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
|  |  | ||||||
| #undef INTERIOR_AND_EXTERIOR | #undef INTERIOR_AND_EXTERIOR | ||||||
| #define INTERIOR | #define INTERIOR | ||||||
| @@ -623,14 +623,14 @@ WilsonKernels<ZDomainWallVec5dImplD>::AsmDhopSiteDagInt(StencilView &st, Doubled | |||||||
| 							    int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | 							    int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
|  |  | ||||||
| template<> void  | //template<> void | ||||||
| WilsonKernels<DomainWallVec5dImplDF>::AsmDhopSiteDagInt(StencilView &st, DoubledGaugeFieldView &U,SiteHalfSpinor *buf, | //WilsonKernels<DomainWallVec5dImplDF>::AsmDhopSiteDagInt(StencilView &st, DoubledGaugeFieldView &U,SiteHalfSpinor *buf, | ||||||
| 							    int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //							    int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
| template<> void  | //template<> void | ||||||
| WilsonKernels<ZDomainWallVec5dImplDF>::AsmDhopSiteDagInt(StencilView &st, DoubledGaugeFieldView &U,SiteHalfSpinor *buf, | //WilsonKernels<ZDomainWallVec5dImplDF>::AsmDhopSiteDagInt(StencilView &st, DoubledGaugeFieldView &U,SiteHalfSpinor *buf, | ||||||
| 							    int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //							    int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
|  |  | ||||||
| #undef INTERIOR_AND_EXTERIOR | #undef INTERIOR_AND_EXTERIOR | ||||||
| #undef INTERIOR | #undef INTERIOR | ||||||
| @@ -645,14 +645,14 @@ WilsonKernels<ZDomainWallVec5dImplD>::AsmDhopSiteDagExt(StencilView &st, Doubled | |||||||
| 							    int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | 							    int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
|  |  | ||||||
| template<> void  | //template<> void | ||||||
| WilsonKernels<DomainWallVec5dImplDF>::AsmDhopSiteDagExt(StencilView &st, DoubledGaugeFieldView &U,SiteHalfSpinor *buf, | //WilsonKernels<DomainWallVec5dImplDF>::AsmDhopSiteDagExt(StencilView &st, DoubledGaugeFieldView &U,SiteHalfSpinor *buf, | ||||||
| 							    int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //							    int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
| template<> void  | //template<> void | ||||||
| WilsonKernels<ZDomainWallVec5dImplDF>::AsmDhopSiteDagExt(StencilView &st, DoubledGaugeFieldView &U,SiteHalfSpinor *buf, | //WilsonKernels<ZDomainWallVec5dImplDF>::AsmDhopSiteDagExt(StencilView &st, DoubledGaugeFieldView &U,SiteHalfSpinor *buf, | ||||||
| 							    int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | //							    int ss,int ssU,int Ls,int Ns,const FermionFieldView &in, FermionFieldView &out) | ||||||
| #include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | //#include <qcd/action/fermion/implementation/WilsonKernelsAsmBody.h> | ||||||
|  |  | ||||||
| #endif  // VEC 5D | #endif  // VEC 5D | ||||||
|  |  | ||||||
|   | |||||||
| @@ -25,6 +25,11 @@ Author:  Nils Meyer  <nils.meyer@ur.de>  Regensburg University | |||||||
|     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 */ | ||||||
|  |  | ||||||
|  | // GCC 10 messes up SVE instruction scheduling using -O3, but | ||||||
|  | // -O3 -fno-schedule-insns -fno-schedule-insns2 does wonders | ||||||
|  | // performance now is better than armclang 20.2 | ||||||
|  |  | ||||||
| #ifdef KERNEL_DAG | #ifdef KERNEL_DAG | ||||||
| #define DIR0_PROJ    XP_PROJ | #define DIR0_PROJ    XP_PROJ | ||||||
| #define DIR1_PROJ    YP_PROJ | #define DIR1_PROJ    YP_PROJ | ||||||
| @@ -97,7 +102,7 @@ Author:  Nils Meyer  <nils.meyer@ur.de>  Regensburg University | |||||||
|     PROJ;							                        \ |     PROJ;							                        \ | ||||||
|     MAYBEPERM(PERMUTE_DIR,perm);					        \ |     MAYBEPERM(PERMUTE_DIR,perm);					        \ | ||||||
|       } else {								                \ |       } else {								                \ | ||||||
| 	LOAD_CHI(base);							                \ | 	  LOAD_CHI(base);							                \ | ||||||
|       }									                    \ |       }									                    \ | ||||||
|       base = st.GetInfo(ptype,local,perm,NxtDir,ent,plocal); ent++;	\ |       base = st.GetInfo(ptype,local,perm,NxtDir,ent,plocal); ent++;	\ | ||||||
|     MULT_2SPIN_1(Dir);					                    \ |     MULT_2SPIN_1(Dir);					                    \ | ||||||
| @@ -110,6 +115,11 @@ Author:  Nils Meyer  <nils.meyer@ur.de>  Regensburg University | |||||||
|     }                                                       \ |     }                                                       \ | ||||||
|     RECON;								                    \ |     RECON;								                    \ | ||||||
|  |  | ||||||
|  | /* | ||||||
|  | NB: picking PREFETCH_GAUGE_L2(Dir+4); here results in performance penalty | ||||||
|  |     though I expected that it would improve on performance | ||||||
|  | */ | ||||||
|  |  | ||||||
| #define ASM_LEG_XP(Dir,NxtDir,PERMUTE_DIR,PROJ,RECON)	    \ | #define ASM_LEG_XP(Dir,NxtDir,PERMUTE_DIR,PROJ,RECON)	    \ | ||||||
|   base = st.GetInfo(ptype,local,perm,Dir,ent,plocal); ent++; \ |   base = st.GetInfo(ptype,local,perm,Dir,ent,plocal); ent++; \ | ||||||
|   PREFETCH1_CHIMU(base);						            \ |   PREFETCH1_CHIMU(base);						            \ | ||||||
| @@ -126,73 +136,63 @@ Author:  Nils Meyer  <nils.meyer@ur.de>  Regensburg University | |||||||
|  |  | ||||||
| #define ASM_LEG(Dir,NxtDir,PERMUTE_DIR,PROJ,RECON)			\ | #define ASM_LEG(Dir,NxtDir,PERMUTE_DIR,PROJ,RECON)			\ | ||||||
|       basep = st.GetPFInfo(nent,plocal); nent++;			\ |       basep = st.GetPFInfo(nent,plocal); nent++;			\ | ||||||
|       if ( local ) {							            \ |       if ( local ) {							\ | ||||||
|     LOAD_CHIMU(base);                                       \ |   LOAD_CHIMU(base);                                       \ | ||||||
|     LOAD_TABLE(PERMUTE_DIR);                                \ |   LOAD_TABLE(PERMUTE_DIR);                                \ | ||||||
|     PROJ;							                        \ |   PROJ;							                        \ | ||||||
|     MAYBEPERM(PERMUTE_DIR,perm);					        \ |   MAYBEPERM(PERMUTE_DIR,perm);					        \ | ||||||
|       }else if ( st.same_node[Dir] ) {LOAD_CHI(base);}	    \ |       }else if ( st.same_node[Dir] ) {LOAD_CHI(base);}			\ | ||||||
|       base = st.GetInfo(ptype,local,perm,NxtDir,ent,plocal); ent++;	\ |       if ( local || st.same_node[Dir] ) {				\ | ||||||
|       if ( local || st.same_node[Dir] ) {				    \ |   MULT_2SPIN_1(Dir);					                    \ | ||||||
|     MULT_2SPIN_1(Dir);					                    \ |   MULT_2SPIN_2;					                        \ | ||||||
|     PREFETCH_CHIMU(base);                                   \ |   RECON;								\ | ||||||
|     /* PREFETCH_GAUGE_L1(NxtDir); */                        \ |       }									\ | ||||||
|     MULT_2SPIN_2;					                        \ |   base = st.GetInfo(ptype,local,perm,NxtDir,ent,plocal); ent++;	\ | ||||||
|     if (s == 0) {                                           \ |   PREFETCH_CHIMU(base);						\ | ||||||
|        if ((Dir == 0) || (Dir == 4)) { PREFETCH_GAUGE_L2(Dir); } \ |   PREFETCH_CHIMU_L2(basep);                               \ | ||||||
|     }                                                       \ |  | ||||||
|     RECON;								                    \ |  | ||||||
|     PREFETCH_CHIMU_L2(basep);                               \ |  | ||||||
|       } else { PREFETCH_CHIMU(base); }								                    \ |  | ||||||
|  |  | ||||||
| #define ASM_LEG_XP(Dir,NxtDir,PERMUTE_DIR,PROJ,RECON)			\ | #define ASM_LEG_XP(Dir,NxtDir,PERMUTE_DIR,PROJ,RECON)			\ | ||||||
|   base = st.GetInfo(ptype,local,perm,Dir,ent,plocal); ent++;		\ |   base = st.GetInfo(ptype,local,perm,Dir,ent,plocal); ent++;		\ | ||||||
|   PREFETCH1_CHIMU(base);						\ |   PREFETCH1_CHIMU(base);						\ | ||||||
|  |   { ZERO_PSI; }								\ | ||||||
|   ASM_LEG(Dir,NxtDir,PERMUTE_DIR,PROJ,RECON) |   ASM_LEG(Dir,NxtDir,PERMUTE_DIR,PROJ,RECON) | ||||||
|  |  | ||||||
| #define RESULT(base,basep) SAVE_RESULT(base,basep); | #define RESULT(base,basep) SAVE_RESULT(base,basep); | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| //////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// | ||||||
| // Post comms kernel | // Post comms kernel | ||||||
| //////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// | ||||||
| #ifdef EXTERIOR | #ifdef EXTERIOR | ||||||
|  |  | ||||||
|  |  | ||||||
| #define ASM_LEG(Dir,NxtDir,PERMUTE_DIR,PROJ,RECON)			\ | #define ASM_LEG(Dir,NxtDir,PERMUTE_DIR,PROJ,RECON)			\ | ||||||
|   base = st.GetInfo(ptype,local,perm,Dir,ent,plocal); ent++; \ |   base = st.GetInfo(ptype,local,perm,Dir,ent,plocal); ent++;		\ | ||||||
|   if((!local)&&(!st.same_node[Dir]) ) {					    \ |   if((!local)&&(!st.same_node[Dir]) ) {					\ | ||||||
|     LOAD_CHI(base);							                \ |     LOAD_CHI(base);							\ | ||||||
|     MULT_2SPIN_1(Dir);					                    \ |     MULT_2SPIN_1(Dir);					                    \ | ||||||
|     PREFETCH_CHIMU(base);                                   \ |  | ||||||
|     /* PREFETCH_GAUGE_L1(NxtDir); */                        \ |  | ||||||
|     MULT_2SPIN_2;					                        \ |     MULT_2SPIN_2;					                        \ | ||||||
|     if (s == 0) {                                           \ |     RECON;								\ | ||||||
|       if ((Dir == 0) || (Dir == 4)) { PREFETCH_GAUGE_L2(Dir); } \ |     nmu++;								\ | ||||||
|     }                                                       \ |  | ||||||
|     RECON;								                    \ |  | ||||||
|     nmu++;								                    \ |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
| #define ASM_LEG_XP(Dir,NxtDir,PERMUTE_DIR,PROJ,RECON)	    \ | #define ASM_LEG_XP(Dir,NxtDir,PERMUTE_DIR,PROJ,RECON)			\ | ||||||
|   nmu=0;								                    \ |   nmu=0;								\ | ||||||
|   base = st.GetInfo(ptype,local,perm,Dir,ent,plocal); ent++;\ |   { ZERO_PSI;}								\ | ||||||
|   if((!local)&&(!st.same_node[Dir]) ) {					    \ |   base = st.GetInfo(ptype,local,perm,Dir,ent,plocal); ent++;		\ | ||||||
|     LOAD_CHI(base);							                \ |   if((!local)&&(!st.same_node[Dir]) ) {					\ | ||||||
|  |     LOAD_CHI(base);							\ | ||||||
|     MULT_2SPIN_1(Dir);					                    \ |     MULT_2SPIN_1(Dir);					                    \ | ||||||
|     PREFETCH_CHIMU(base);                                   \ |  | ||||||
|     /* PREFETCH_GAUGE_L1(NxtDir); */                        \ |  | ||||||
|     MULT_2SPIN_2;					                        \ |     MULT_2SPIN_2;					                        \ | ||||||
|     if (s == 0) {                                           \ |     RECON;								\ | ||||||
|       if ((Dir == 0) || (Dir == 4)) { PREFETCH_GAUGE_L2(Dir); } \ |     nmu++;								\ | ||||||
|     }                                                       \ |  | ||||||
|     RECON;								                    \ |  | ||||||
|     nmu++;								                    \ |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
| #define RESULT(base,basep) if (nmu){ ADD_RESULT(base,base);} | #define RESULT(base,basep) if (nmu){ ADD_RESULT(base,base);} | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  |  | ||||||
| { | { | ||||||
|   int nmu; |   int nmu; | ||||||
|   int local,perm, ptype; |   int local,perm, ptype; | ||||||
| @@ -209,7 +209,6 @@ Author:  Nils Meyer  <nils.meyer@ur.de>  Regensburg University | |||||||
|     int ssn=ssU+1;     if(ssn>=nmax) ssn=0; |     int ssn=ssU+1;     if(ssn>=nmax) ssn=0; | ||||||
|     //    int sUn=lo.Reorder(ssn); |     //    int sUn=lo.Reorder(ssn); | ||||||
|     int sUn=ssn; |     int sUn=ssn; | ||||||
|     LOCK_GAUGE(0); |  | ||||||
| #else | #else | ||||||
|     int sU =ssU; |     int sU =ssU; | ||||||
|     int ssn=ssU+1;     if(ssn>=nmax) ssn=0; |     int ssn=ssU+1;     if(ssn>=nmax) ssn=0; | ||||||
| @@ -295,6 +294,11 @@ Author:  Nils Meyer  <nils.meyer@ur.de>  Regensburg University | |||||||
|       std::cout << "----------------------------------------------------" << std::endl; |       std::cout << "----------------------------------------------------" << std::endl; | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  |       // DC ZVA test | ||||||
|  |       // { uint64_t basestore = (uint64_t)&out[ss]; | ||||||
|  |       //   PREFETCH_RESULT_L2_STORE(basestore); } | ||||||
|  |  | ||||||
|  |  | ||||||
|       ASM_LEG(Ym,Zm,PERMUTE_DIR2,DIR5_PROJ,DIR5_RECON); |       ASM_LEG(Ym,Zm,PERMUTE_DIR2,DIR5_PROJ,DIR5_RECON); | ||||||
|  |  | ||||||
| #ifdef SHOW | #ifdef SHOW | ||||||
| @@ -308,6 +312,11 @@ Author:  Nils Meyer  <nils.meyer@ur.de>  Regensburg University | |||||||
|       std::cout << "----------------------------------------------------" << std::endl; |       std::cout << "----------------------------------------------------" << std::endl; | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  |       // DC ZVA test | ||||||
|  |       //{ uint64_t basestore = (uint64_t)&out[ss]; | ||||||
|  |       //  PREFETCH_RESULT_L2_STORE(basestore); } | ||||||
|  |  | ||||||
|  |  | ||||||
|       ASM_LEG(Zm,Tm,PERMUTE_DIR1,DIR6_PROJ,DIR6_RECON); |       ASM_LEG(Zm,Tm,PERMUTE_DIR1,DIR6_PROJ,DIR6_RECON); | ||||||
|  |  | ||||||
| #ifdef SHOW | #ifdef SHOW | ||||||
| @@ -321,6 +330,11 @@ Author:  Nils Meyer  <nils.meyer@ur.de>  Regensburg University | |||||||
|       std::cout << "----------------------------------------------------" << std::endl; |       std::cout << "----------------------------------------------------" << std::endl; | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  |       // DC ZVA test | ||||||
|  |       //{ uint64_t basestore = (uint64_t)&out[ss]; | ||||||
|  |       //  PREFETCH_RESULT_L2_STORE(basestore); } | ||||||
|  |  | ||||||
|  |  | ||||||
|       ASM_LEG(Tm,Xp,PERMUTE_DIR0,DIR7_PROJ,DIR7_RECON); |       ASM_LEG(Tm,Xp,PERMUTE_DIR0,DIR7_PROJ,DIR7_RECON); | ||||||
|  |  | ||||||
| #ifdef SHOW | #ifdef SHOW | ||||||
| @@ -341,6 +355,7 @@ Author:  Nils Meyer  <nils.meyer@ur.de>  Regensburg University | |||||||
|       base = (uint64_t) &out[ss]; |       base = (uint64_t) &out[ss]; | ||||||
|       basep= st.GetPFInfo(nent,plocal); ent++; |       basep= st.GetPFInfo(nent,plocal); ent++; | ||||||
|       basep = (uint64_t) &out[ssn]; |       basep = (uint64_t) &out[ssn]; | ||||||
|  |       //PREFETCH_RESULT_L1_STORE(base); | ||||||
|       RESULT(base,basep); |       RESULT(base,basep); | ||||||
|  |  | ||||||
| #ifdef SHOW | #ifdef SHOW | ||||||
|   | |||||||
| @@ -76,7 +76,24 @@ Author: paboyle <paboyle@ph.ed.ac.uk> | |||||||
|  |  | ||||||
| #define REGISTER | #define REGISTER | ||||||
|  |  | ||||||
| #define LOAD_CHIMU \ | #ifdef GRID_SIMT | ||||||
|  | #define LOAD_CHIMU(ptype)		\ | ||||||
|  |   {const SiteSpinor & ref (in[offset]);	\ | ||||||
|  |     Chimu_00=coalescedReadPermute<ptype>(ref()(0)(0),perm,lane);	\ | ||||||
|  |     Chimu_01=coalescedReadPermute<ptype>(ref()(0)(1),perm,lane);		\ | ||||||
|  |     Chimu_02=coalescedReadPermute<ptype>(ref()(0)(2),perm,lane);		\ | ||||||
|  |     Chimu_10=coalescedReadPermute<ptype>(ref()(1)(0),perm,lane);		\ | ||||||
|  |     Chimu_11=coalescedReadPermute<ptype>(ref()(1)(1),perm,lane);		\ | ||||||
|  |     Chimu_12=coalescedReadPermute<ptype>(ref()(1)(2),perm,lane);		\ | ||||||
|  |     Chimu_20=coalescedReadPermute<ptype>(ref()(2)(0),perm,lane);		\ | ||||||
|  |     Chimu_21=coalescedReadPermute<ptype>(ref()(2)(1),perm,lane);		\ | ||||||
|  |     Chimu_22=coalescedReadPermute<ptype>(ref()(2)(2),perm,lane);		\ | ||||||
|  |     Chimu_30=coalescedReadPermute<ptype>(ref()(3)(0),perm,lane);		\ | ||||||
|  |     Chimu_31=coalescedReadPermute<ptype>(ref()(3)(1),perm,lane);		\ | ||||||
|  |     Chimu_32=coalescedReadPermute<ptype>(ref()(3)(2),perm,lane);	} | ||||||
|  | #define PERMUTE_DIR(dir) ; | ||||||
|  | #else | ||||||
|  | #define LOAD_CHIMU(ptype)		\ | ||||||
|   {const SiteSpinor & ref (in[offset]);	\ |   {const SiteSpinor & ref (in[offset]);	\ | ||||||
|     Chimu_00=ref()(0)(0);\ |     Chimu_00=ref()(0)(0);\ | ||||||
|     Chimu_01=ref()(0)(1);\ |     Chimu_01=ref()(0)(1);\ | ||||||
| @@ -91,55 +108,55 @@ Author: paboyle <paboyle@ph.ed.ac.uk> | |||||||
|     Chimu_31=ref()(3)(1);\ |     Chimu_31=ref()(3)(1);\ | ||||||
|     Chimu_32=ref()(3)(2);} |     Chimu_32=ref()(3)(2);} | ||||||
|  |  | ||||||
| #define LOAD_CHI\ |  | ||||||
|   {const SiteHalfSpinor &ref(buf[offset]);	\ |  | ||||||
|     Chi_00 = ref()(0)(0);\ |  | ||||||
|     Chi_01 = ref()(0)(1);\ |  | ||||||
|     Chi_02 = ref()(0)(2);\ |  | ||||||
|     Chi_10 = ref()(1)(0);\ |  | ||||||
|     Chi_11 = ref()(1)(1);\ |  | ||||||
|     Chi_12 = ref()(1)(2);} |  | ||||||
|  |  | ||||||
| // To splat or not to splat depends on the implementation |  | ||||||
| #define MULT_2SPIN(A)\ |  | ||||||
|   {auto & ref(U[sU](A));			\ |  | ||||||
|    Impl::loadLinkElement(U_00,ref()(0,0));	\ |  | ||||||
|    Impl::loadLinkElement(U_10,ref()(1,0));	\ |  | ||||||
|    Impl::loadLinkElement(U_20,ref()(2,0));	\ |  | ||||||
|    Impl::loadLinkElement(U_01,ref()(0,1));	\ |  | ||||||
|    Impl::loadLinkElement(U_11,ref()(1,1));	\ |  | ||||||
|    Impl::loadLinkElement(U_21,ref()(2,1));	\ |  | ||||||
|     UChi_00 = U_00*Chi_00;\ |  | ||||||
|     UChi_10 = U_00*Chi_10;\ |  | ||||||
|     UChi_01 = U_10*Chi_00;\ |  | ||||||
|     UChi_11 = U_10*Chi_10;\ |  | ||||||
|     UChi_02 = U_20*Chi_00;\ |  | ||||||
|     UChi_12 = U_20*Chi_10;\ |  | ||||||
|     UChi_00+= U_01*Chi_01;\ |  | ||||||
|     UChi_10+= U_01*Chi_11;\ |  | ||||||
|     UChi_01+= U_11*Chi_01;\ |  | ||||||
|     UChi_11+= U_11*Chi_11;\ |  | ||||||
|     UChi_02+= U_21*Chi_01;\ |  | ||||||
|     UChi_12+= U_21*Chi_11;\ |  | ||||||
|     Impl::loadLinkElement(U_00,ref()(0,2));	\ |  | ||||||
|     Impl::loadLinkElement(U_10,ref()(1,2));	\ |  | ||||||
|     Impl::loadLinkElement(U_20,ref()(2,2));	\ |  | ||||||
|     UChi_00+= U_00*Chi_02;\ |  | ||||||
|     UChi_10+= U_00*Chi_12;\ |  | ||||||
|     UChi_01+= U_10*Chi_02;\ |  | ||||||
|     UChi_11+= U_10*Chi_12;\ |  | ||||||
|     UChi_02+= U_20*Chi_02;\ |  | ||||||
|     UChi_12+= U_20*Chi_12;} |  | ||||||
|  |  | ||||||
|  |  | ||||||
| #define PERMUTE_DIR(dir)			\ | #define PERMUTE_DIR(dir)			\ | ||||||
|       permute##dir(Chi_00,Chi_00);\ |   permute##dir(Chi_00,Chi_00);	\ | ||||||
|       permute##dir(Chi_01,Chi_01);\ |       permute##dir(Chi_01,Chi_01);\ | ||||||
|       permute##dir(Chi_02,Chi_02);\ |       permute##dir(Chi_02,Chi_02);\ | ||||||
|       permute##dir(Chi_10,Chi_10);\ |       permute##dir(Chi_10,Chi_10);	\ | ||||||
|       permute##dir(Chi_11,Chi_11);\ |       permute##dir(Chi_11,Chi_11);\ | ||||||
|       permute##dir(Chi_12,Chi_12); |       permute##dir(Chi_12,Chi_12); | ||||||
|  |  | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #define MULT_2SPIN(A)\ | ||||||
|  |   {auto & ref(U[sU](A));						\ | ||||||
|  |     U_00=coalescedRead(ref()(0,0),lane);				\ | ||||||
|  |     U_10=coalescedRead(ref()(1,0),lane);				\ | ||||||
|  |     U_20=coalescedRead(ref()(2,0),lane);				\ | ||||||
|  |     U_01=coalescedRead(ref()(0,1),lane);				\ | ||||||
|  |     U_11=coalescedRead(ref()(1,1),lane);				\ | ||||||
|  |     U_21=coalescedRead(ref()(2,1),lane);				\ | ||||||
|  |     UChi_00 = U_00*Chi_00;						\ | ||||||
|  |     UChi_10 = U_00*Chi_10;						\ | ||||||
|  |     UChi_01 = U_10*Chi_00;						\ | ||||||
|  |     UChi_11 = U_10*Chi_10;						\ | ||||||
|  |     UChi_02 = U_20*Chi_00;						\ | ||||||
|  |     UChi_12 = U_20*Chi_10;						\ | ||||||
|  |     UChi_00+= U_01*Chi_01;						\ | ||||||
|  |     UChi_10+= U_01*Chi_11;						\ | ||||||
|  |     UChi_01+= U_11*Chi_01;						\ | ||||||
|  |     UChi_11+= U_11*Chi_11;						\ | ||||||
|  |     UChi_02+= U_21*Chi_01;						\ | ||||||
|  |     UChi_12+= U_21*Chi_11;						\ | ||||||
|  |     U_00=coalescedRead(ref()(0,2),lane);				\ | ||||||
|  |     U_10=coalescedRead(ref()(1,2),lane);				\ | ||||||
|  |     U_20=coalescedRead(ref()(2,2),lane);				\ | ||||||
|  |     UChi_00+= U_00*Chi_02;						\ | ||||||
|  |     UChi_10+= U_00*Chi_12;						\ | ||||||
|  |     UChi_01+= U_10*Chi_02;						\ | ||||||
|  |     UChi_11+= U_10*Chi_12;						\ | ||||||
|  |     UChi_02+= U_20*Chi_02;						\ | ||||||
|  |     UChi_12+= U_20*Chi_12;} | ||||||
|  |  | ||||||
|  | #define LOAD_CHI				\ | ||||||
|  |   {const SiteHalfSpinor &ref(buf[offset]);	\ | ||||||
|  |     Chi_00 = coalescedRead(ref()(0)(0),lane);	\ | ||||||
|  |     Chi_01 = coalescedRead(ref()(0)(1),lane);	\ | ||||||
|  |     Chi_02 = coalescedRead(ref()(0)(2),lane);	\ | ||||||
|  |     Chi_10 = coalescedRead(ref()(1)(0),lane);	\ | ||||||
|  |     Chi_11 = coalescedRead(ref()(1)(1),lane);	\ | ||||||
|  |     Chi_12 = coalescedRead(ref()(1)(2),lane);} | ||||||
|  |  | ||||||
| //      hspin(0)=fspin(0)+timesI(fspin(3)); | //      hspin(0)=fspin(0)+timesI(fspin(3)); | ||||||
| //      hspin(1)=fspin(1)+timesI(fspin(2)); | //      hspin(1)=fspin(1)+timesI(fspin(2)); | ||||||
| #define XP_PROJ \ | #define XP_PROJ \ | ||||||
| @@ -353,13 +370,13 @@ Author: paboyle <paboyle@ph.ed.ac.uk> | |||||||
|   result_31-= UChi_11;	\ |   result_31-= UChi_11;	\ | ||||||
|   result_32-= UChi_12; |   result_32-= UChi_12; | ||||||
|  |  | ||||||
| #define HAND_STENCIL_LEG(PROJ,PERM,DIR,RECON)	\ | #define HAND_STENCIL_LEGB(PROJ,PERM,DIR,RECON)	\ | ||||||
|   SE=st.GetEntry(ptype,DIR,ss);			\ |   SE=st.GetEntry(ptype,DIR,ss);			\ | ||||||
|   offset = SE->_offset;				\ |   offset = SE->_offset;				\ | ||||||
|   local  = SE->_is_local;			\ |   local  = SE->_is_local;			\ | ||||||
|   perm   = SE->_permute;			\ |   perm   = SE->_permute;			\ | ||||||
|   if ( local ) {				\ |   if ( local ) {				\ | ||||||
|     LOAD_CHIMU;					\ |     LOAD_CHIMU(PERM);				\ | ||||||
|     PROJ;					\ |     PROJ;					\ | ||||||
|     if ( perm) {				\ |     if ( perm) {				\ | ||||||
|       PERMUTE_DIR(PERM);			\ |       PERMUTE_DIR(PERM);			\ | ||||||
| @@ -367,6 +384,37 @@ Author: paboyle <paboyle@ph.ed.ac.uk> | |||||||
|   } else {					\ |   } else {					\ | ||||||
|     LOAD_CHI;					\ |     LOAD_CHI;					\ | ||||||
|   }						\ |   }						\ | ||||||
|  |   acceleratorSynchronise();			\ | ||||||
|  |   MULT_2SPIN(DIR);				\ | ||||||
|  |   RECON;					 | ||||||
|  |  | ||||||
|  | #define HAND_STENCIL_LEG(PROJ,PERM,DIR,RECON)	\ | ||||||
|  |   SE=&st_p[DIR+8*ss];				\ | ||||||
|  |   ptype=st_perm[DIR];				\ | ||||||
|  |   offset = SE->_offset;				\ | ||||||
|  |   local  = SE->_is_local;			\ | ||||||
|  |   perm   = SE->_permute;			\ | ||||||
|  |   if ( local ) {				\ | ||||||
|  |     LOAD_CHIMU(PERM);				\ | ||||||
|  |     PROJ;					\ | ||||||
|  |     if ( perm) {				\ | ||||||
|  |       PERMUTE_DIR(PERM);			\ | ||||||
|  |     }						\ | ||||||
|  |   } else {					\ | ||||||
|  |     LOAD_CHI;					\ | ||||||
|  |   }						\ | ||||||
|  |   acceleratorSynchronise();			\ | ||||||
|  |   MULT_2SPIN(DIR);				\ | ||||||
|  |   RECON;					 | ||||||
|  |  | ||||||
|  | #define HAND_STENCIL_LEGA(PROJ,PERM,DIR,RECON)				\ | ||||||
|  |   SE=&st_p[DIR+8*ss];							\ | ||||||
|  |   ptype=st_perm[DIR];							\ | ||||||
|  |  /*SE=st.GetEntry(ptype,DIR,ss);*/					\ | ||||||
|  |   offset = SE->_offset;				\ | ||||||
|  |   perm   = SE->_permute;			\ | ||||||
|  |   LOAD_CHIMU(PERM);				\ | ||||||
|  |   PROJ;						\ | ||||||
|   MULT_2SPIN(DIR);				\ |   MULT_2SPIN(DIR);				\ | ||||||
|   RECON;					 |   RECON;					 | ||||||
|  |  | ||||||
| @@ -376,7 +424,7 @@ Author: paboyle <paboyle@ph.ed.ac.uk> | |||||||
|   local  = SE->_is_local;			\ |   local  = SE->_is_local;			\ | ||||||
|   perm   = SE->_permute;			\ |   perm   = SE->_permute;			\ | ||||||
|   if ( local ) {				\ |   if ( local ) {				\ | ||||||
|     LOAD_CHIMU;					\ |     LOAD_CHIMU(PERM);				\ | ||||||
|     PROJ;					\ |     PROJ;					\ | ||||||
|     if ( perm) {				\ |     if ( perm) {				\ | ||||||
|       PERMUTE_DIR(PERM);			\ |       PERMUTE_DIR(PERM);			\ | ||||||
| @@ -384,10 +432,12 @@ Author: paboyle <paboyle@ph.ed.ac.uk> | |||||||
|   } else if ( st.same_node[DIR] ) {		\ |   } else if ( st.same_node[DIR] ) {		\ | ||||||
|     LOAD_CHI;					\ |     LOAD_CHI;					\ | ||||||
|   }						\ |   }						\ | ||||||
|  |   acceleratorSynchronise();			\ | ||||||
|   if (local || st.same_node[DIR] ) {		\ |   if (local || st.same_node[DIR] ) {		\ | ||||||
|     MULT_2SPIN(DIR);				\ |     MULT_2SPIN(DIR);				\ | ||||||
|     RECON;					\ |     RECON;					\ | ||||||
|   } |   }						\ | ||||||
|  |   acceleratorSynchronise();			 | ||||||
|  |  | ||||||
| #define HAND_STENCIL_LEG_EXT(PROJ,PERM,DIR,RECON)	\ | #define HAND_STENCIL_LEG_EXT(PROJ,PERM,DIR,RECON)	\ | ||||||
|   SE=st.GetEntry(ptype,DIR,ss);			\ |   SE=st.GetEntry(ptype,DIR,ss);			\ | ||||||
| @@ -397,44 +447,44 @@ Author: paboyle <paboyle@ph.ed.ac.uk> | |||||||
|     MULT_2SPIN(DIR);				\ |     MULT_2SPIN(DIR);				\ | ||||||
|     RECON;					\ |     RECON;					\ | ||||||
|     nmu++;					\ |     nmu++;					\ | ||||||
|   } |   }						\ | ||||||
|  |   acceleratorSynchronise();			 | ||||||
|  |  | ||||||
| #define HAND_RESULT(ss)				\ | #define HAND_RESULT(ss)				\ | ||||||
|   {						\ |   {						\ | ||||||
|     SiteSpinor & ref (out[ss]);		\ |     SiteSpinor & ref (out[ss]);			\ | ||||||
|     vstream(ref()(0)(0),result_00);		\ |     coalescedWrite(ref()(0)(0),result_00,lane);		\ | ||||||
|     vstream(ref()(0)(1),result_01);		\ |     coalescedWrite(ref()(0)(1),result_01,lane);		\ | ||||||
|     vstream(ref()(0)(2),result_02);		\ |     coalescedWrite(ref()(0)(2),result_02,lane);		\ | ||||||
|     vstream(ref()(1)(0),result_10);		\ |     coalescedWrite(ref()(1)(0),result_10,lane);		\ | ||||||
|     vstream(ref()(1)(1),result_11);		\ |     coalescedWrite(ref()(1)(1),result_11,lane);		\ | ||||||
|     vstream(ref()(1)(2),result_12);		\ |     coalescedWrite(ref()(1)(2),result_12,lane);		\ | ||||||
|     vstream(ref()(2)(0),result_20);		\ |     coalescedWrite(ref()(2)(0),result_20,lane);		\ | ||||||
|     vstream(ref()(2)(1),result_21);		\ |     coalescedWrite(ref()(2)(1),result_21,lane);		\ | ||||||
|     vstream(ref()(2)(2),result_22);		\ |     coalescedWrite(ref()(2)(2),result_22,lane);		\ | ||||||
|     vstream(ref()(3)(0),result_30);		\ |     coalescedWrite(ref()(3)(0),result_30,lane);		\ | ||||||
|     vstream(ref()(3)(1),result_31);		\ |     coalescedWrite(ref()(3)(1),result_31,lane);		\ | ||||||
|     vstream(ref()(3)(2),result_32);		\ |     coalescedWrite(ref()(3)(2),result_32,lane);		\ | ||||||
|   } |   } | ||||||
|  |  | ||||||
| #define HAND_RESULT_EXT(ss)			\ | #define HAND_RESULT_EXT(ss)				\ | ||||||
|   if (nmu){					\ |   {							\ | ||||||
|     SiteSpinor & ref (out[ss]);		\ |     SiteSpinor & ref (out[ss]);				\ | ||||||
|     ref()(0)(0)+=result_00;		\ |     coalescedWrite(ref()(0)(0),coalescedRead(ref()(0)(0))+result_00,lane);	\ | ||||||
|     ref()(0)(1)+=result_01;		\ |     coalescedWrite(ref()(0)(1),coalescedRead(ref()(0)(1))+result_01,lane);	\ | ||||||
|     ref()(0)(2)+=result_02;		\ |     coalescedWrite(ref()(0)(2),coalescedRead(ref()(0)(2))+result_02,lane);	\ | ||||||
|     ref()(1)(0)+=result_10;		\ |     coalescedWrite(ref()(1)(0),coalescedRead(ref()(1)(0))+result_10,lane);	\ | ||||||
|     ref()(1)(1)+=result_11;		\ |     coalescedWrite(ref()(1)(1),coalescedRead(ref()(1)(1))+result_11,lane);	\ | ||||||
|     ref()(1)(2)+=result_12;		\ |     coalescedWrite(ref()(1)(2),coalescedRead(ref()(1)(2))+result_12,lane);	\ | ||||||
|     ref()(2)(0)+=result_20;		\ |     coalescedWrite(ref()(2)(0),coalescedRead(ref()(2)(0))+result_20,lane);	\ | ||||||
|     ref()(2)(1)+=result_21;		\ |     coalescedWrite(ref()(2)(1),coalescedRead(ref()(2)(1))+result_21,lane);	\ | ||||||
|     ref()(2)(2)+=result_22;		\ |     coalescedWrite(ref()(2)(2),coalescedRead(ref()(2)(2))+result_22,lane);	\ | ||||||
|     ref()(3)(0)+=result_30;		\ |     coalescedWrite(ref()(3)(0),coalescedRead(ref()(3)(0))+result_30,lane);	\ | ||||||
|     ref()(3)(1)+=result_31;		\ |     coalescedWrite(ref()(3)(1),coalescedRead(ref()(3)(1))+result_31,lane);	\ | ||||||
|     ref()(3)(2)+=result_32;		\ |     coalescedWrite(ref()(3)(2),coalescedRead(ref()(3)(2))+result_32,lane);	\ | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | #define HAND_DECLARATIONS(Simd)			\ | ||||||
| #define HAND_DECLARATIONS(a)			\ |  | ||||||
|   Simd result_00;				\ |   Simd result_00;				\ | ||||||
|   Simd result_01;				\ |   Simd result_01;				\ | ||||||
|   Simd result_02;				\ |   Simd result_02;				\ | ||||||
| @@ -466,19 +516,19 @@ Author: paboyle <paboyle@ph.ed.ac.uk> | |||||||
|   Simd U_11;					\ |   Simd U_11;					\ | ||||||
|   Simd U_21; |   Simd U_21; | ||||||
|  |  | ||||||
| #define ZERO_RESULT				\ | #define ZERO_RESULT							\ | ||||||
|   result_00=Zero();				\ |   zeroit(result_00);							\ | ||||||
|   result_01=Zero();				\ |   zeroit(result_01);							\ | ||||||
|   result_02=Zero();				\ |   zeroit(result_02);							\ | ||||||
|   result_10=Zero();				\ |   zeroit(result_10);							\ | ||||||
|   result_11=Zero();				\ |   zeroit(result_11);							\ | ||||||
|   result_12=Zero();				\ |   zeroit(result_12);							\ | ||||||
|   result_20=Zero();				\ |   zeroit(result_20);							\ | ||||||
|   result_21=Zero();				\ |   zeroit(result_21);							\ | ||||||
|   result_22=Zero();				\ |   zeroit(result_22);							\ | ||||||
|   result_30=Zero();				\ |   zeroit(result_30);							\ | ||||||
|   result_31=Zero();				\ |   zeroit(result_31);							\ | ||||||
|   result_32=Zero();			 |   zeroit(result_32);			 | ||||||
|  |  | ||||||
| #define Chimu_00 Chi_00 | #define Chimu_00 Chi_00 | ||||||
| #define Chimu_01 Chi_01 | #define Chimu_01 Chi_01 | ||||||
| @@ -495,15 +545,53 @@ Author: paboyle <paboyle@ph.ed.ac.uk> | |||||||
|  |  | ||||||
| NAMESPACE_BEGIN(Grid); | NAMESPACE_BEGIN(Grid); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #ifdef SYCL_HACK | ||||||
| template<class Impl> accelerator_inline void  | template<class Impl> accelerator_inline void  | ||||||
| WilsonKernels<Impl>::HandDhopSite(StencilView &st, DoubledGaugeFieldView &U,SiteHalfSpinor  *buf, | WilsonKernels<Impl>::HandDhopSiteSycl(StencilVector st_perm,StencilEntry *st_p, SiteDoubledGaugeField *U,SiteHalfSpinor  *buf, | ||||||
| 				  int ss,int sU,const FermionFieldView &in, FermionFieldView &out) | 				      int ss,int sU,const SiteSpinor *in, SiteSpinor *out) | ||||||
| { | { | ||||||
| // T==0, Z==1, Y==2, Z==3 expect 1,2,2,2 simd layout etc... | // T==0, Z==1, Y==2, Z==3 expect 1,2,2,2 simd layout etc... | ||||||
|   typedef typename Simd::scalar_type S; |   typedef typename Simd::scalar_type S; | ||||||
|   typedef typename Simd::vector_type V; |   typedef typename Simd::vector_type V; | ||||||
|  |   typedef iSinglet<Simd> vCplx; | ||||||
|  |   //  typedef decltype( coalescedRead( vCplx()()() )) Simt; | ||||||
|  |   typedef decltype( coalescedRead( in[0]()(0)(0) )) Simt; | ||||||
|  |  | ||||||
|   HAND_DECLARATIONS(ignore); |   const int Nsimd = SiteHalfSpinor::Nsimd(); | ||||||
|  |   const int lane=acceleratorSIMTlane(Nsimd); | ||||||
|  |  | ||||||
|  |   HAND_DECLARATIONS(Simt); | ||||||
|  |  | ||||||
|  |   int offset,local,perm, ptype; | ||||||
|  |   StencilEntry *SE; | ||||||
|  |   HAND_STENCIL_LEG(XM_PROJ,3,Xp,XM_RECON); | ||||||
|  |   HAND_STENCIL_LEG(YM_PROJ,2,Yp,YM_RECON_ACCUM); | ||||||
|  |   HAND_STENCIL_LEG(ZM_PROJ,1,Zp,ZM_RECON_ACCUM); | ||||||
|  |   HAND_STENCIL_LEG(TM_PROJ,0,Tp,TM_RECON_ACCUM); | ||||||
|  |   HAND_STENCIL_LEG(XP_PROJ,3,Xm,XP_RECON_ACCUM); | ||||||
|  |   HAND_STENCIL_LEG(YP_PROJ,2,Ym,YP_RECON_ACCUM); | ||||||
|  |   HAND_STENCIL_LEG(ZP_PROJ,1,Zm,ZP_RECON_ACCUM); | ||||||
|  |   HAND_STENCIL_LEG(TP_PROJ,0,Tm,TP_RECON_ACCUM); | ||||||
|  |   HAND_RESULT(ss); | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | template<class Impl> accelerator_inline void  | ||||||
|  | WilsonKernels<Impl>::HandDhopSite(StencilView &st, DoubledGaugeFieldView &U,SiteHalfSpinor  *buf, | ||||||
|  | 				  int ss,int sU,const FermionFieldView &in, FermionFieldView &out) | ||||||
|  | { | ||||||
|  |   auto st_p = st._entries_p;						 | ||||||
|  |   auto st_perm = st._permute_type;					 | ||||||
|  | // T==0, Z==1, Y==2, Z==3 expect 1,2,2,2 simd layout etc... | ||||||
|  |   typedef typename Simd::scalar_type S; | ||||||
|  |   typedef typename Simd::vector_type V; | ||||||
|  |   typedef decltype( coalescedRead( in[0]()(0)(0) )) Simt; | ||||||
|  |  | ||||||
|  |   const int Nsimd = SiteHalfSpinor::Nsimd(); | ||||||
|  |   const int lane=acceleratorSIMTlane(Nsimd); | ||||||
|  |  | ||||||
|  |   HAND_DECLARATIONS(Simt); | ||||||
|  |  | ||||||
|   int offset,local,perm, ptype; |   int offset,local,perm, ptype; | ||||||
|   StencilEntry *SE; |   StencilEntry *SE; | ||||||
| @@ -523,10 +611,16 @@ template<class Impl>  accelerator_inline | |||||||
| void WilsonKernels<Impl>::HandDhopSiteDag(StencilView &st,DoubledGaugeFieldView &U,SiteHalfSpinor *buf, | void WilsonKernels<Impl>::HandDhopSiteDag(StencilView &st,DoubledGaugeFieldView &U,SiteHalfSpinor *buf, | ||||||
| 					  int ss,int sU,const FermionFieldView &in, FermionFieldView &out) | 					  int ss,int sU,const FermionFieldView &in, FermionFieldView &out) | ||||||
| { | { | ||||||
|  |   auto st_p = st._entries_p;						 | ||||||
|  |   auto st_perm = st._permute_type;					 | ||||||
|   typedef typename Simd::scalar_type S; |   typedef typename Simd::scalar_type S; | ||||||
|   typedef typename Simd::vector_type V; |   typedef typename Simd::vector_type V; | ||||||
|  |   typedef decltype( coalescedRead( in[0]()(0)(0) )) Simt; | ||||||
|  |  | ||||||
|   HAND_DECLARATIONS(ignore); |   const int Nsimd = SiteHalfSpinor::Nsimd(); | ||||||
|  |   const int lane=acceleratorSIMTlane(Nsimd); | ||||||
|  |  | ||||||
|  |   HAND_DECLARATIONS(Simt); | ||||||
|  |  | ||||||
|   StencilEntry *SE; |   StencilEntry *SE; | ||||||
|   int offset,local,perm, ptype; |   int offset,local,perm, ptype; | ||||||
| @@ -546,11 +640,17 @@ template<class Impl>  accelerator_inline void | |||||||
| WilsonKernels<Impl>::HandDhopSiteInt(StencilView &st,DoubledGaugeFieldView &U,SiteHalfSpinor  *buf, | WilsonKernels<Impl>::HandDhopSiteInt(StencilView &st,DoubledGaugeFieldView &U,SiteHalfSpinor  *buf, | ||||||
| 					  int ss,int sU,const FermionFieldView &in, FermionFieldView &out) | 					  int ss,int sU,const FermionFieldView &in, FermionFieldView &out) | ||||||
| { | { | ||||||
|  |   auto st_p = st._entries_p;						 | ||||||
|  |   auto st_perm = st._permute_type;					 | ||||||
| // T==0, Z==1, Y==2, Z==3 expect 1,2,2,2 simd layout etc... | // T==0, Z==1, Y==2, Z==3 expect 1,2,2,2 simd layout etc... | ||||||
|   typedef typename Simd::scalar_type S; |   typedef typename Simd::scalar_type S; | ||||||
|   typedef typename Simd::vector_type V; |   typedef typename Simd::vector_type V; | ||||||
|  |   typedef decltype( coalescedRead( in[0]()(0)(0) )) Simt; | ||||||
|  |  | ||||||
|   HAND_DECLARATIONS(ignore); |   const int Nsimd = SiteHalfSpinor::Nsimd(); | ||||||
|  |   const int lane=acceleratorSIMTlane(Nsimd); | ||||||
|  |  | ||||||
|  |   HAND_DECLARATIONS(Simt); | ||||||
|  |  | ||||||
|   int offset,local,perm, ptype; |   int offset,local,perm, ptype; | ||||||
|   StencilEntry *SE; |   StencilEntry *SE; | ||||||
| @@ -570,10 +670,16 @@ template<class Impl> accelerator_inline | |||||||
| void WilsonKernels<Impl>::HandDhopSiteDagInt(StencilView &st,DoubledGaugeFieldView &U,SiteHalfSpinor *buf, | void WilsonKernels<Impl>::HandDhopSiteDagInt(StencilView &st,DoubledGaugeFieldView &U,SiteHalfSpinor *buf, | ||||||
| 						  int ss,int sU,const FermionFieldView &in, FermionFieldView &out) | 						  int ss,int sU,const FermionFieldView &in, FermionFieldView &out) | ||||||
| { | { | ||||||
|  |   auto st_p = st._entries_p;						 | ||||||
|  |   auto st_perm = st._permute_type;					 | ||||||
|   typedef typename Simd::scalar_type S; |   typedef typename Simd::scalar_type S; | ||||||
|   typedef typename Simd::vector_type V; |   typedef typename Simd::vector_type V; | ||||||
|  |   typedef decltype( coalescedRead( in[0]()(0)(0) )) Simt; | ||||||
|  |  | ||||||
|   HAND_DECLARATIONS(ignore); |   const int Nsimd = SiteHalfSpinor::Nsimd(); | ||||||
|  |   const int lane=acceleratorSIMTlane(Nsimd); | ||||||
|  |  | ||||||
|  |   HAND_DECLARATIONS(Simt); | ||||||
|  |  | ||||||
|   StencilEntry *SE; |   StencilEntry *SE; | ||||||
|   int offset,local,perm, ptype; |   int offset,local,perm, ptype; | ||||||
| @@ -593,11 +699,17 @@ template<class Impl>  accelerator_inline void | |||||||
| WilsonKernels<Impl>::HandDhopSiteExt(StencilView &st,DoubledGaugeFieldView &U,SiteHalfSpinor  *buf, | WilsonKernels<Impl>::HandDhopSiteExt(StencilView &st,DoubledGaugeFieldView &U,SiteHalfSpinor  *buf, | ||||||
| 					  int ss,int sU,const FermionFieldView &in, FermionFieldView &out) | 					  int ss,int sU,const FermionFieldView &in, FermionFieldView &out) | ||||||
| { | { | ||||||
|  |   auto st_p = st._entries_p;						 | ||||||
|  |   auto st_perm = st._permute_type;					 | ||||||
| // T==0, Z==1, Y==2, Z==3 expect 1,2,2,2 simd layout etc... | // T==0, Z==1, Y==2, Z==3 expect 1,2,2,2 simd layout etc... | ||||||
|   typedef typename Simd::scalar_type S; |   typedef typename Simd::scalar_type S; | ||||||
|   typedef typename Simd::vector_type V; |   typedef typename Simd::vector_type V; | ||||||
|  |   typedef decltype( coalescedRead( in[0]()(0)(0) )) Simt; | ||||||
|  |  | ||||||
|   HAND_DECLARATIONS(ignore); |   const int Nsimd = SiteHalfSpinor::Nsimd(); | ||||||
|  |   const int lane=acceleratorSIMTlane(Nsimd); | ||||||
|  |  | ||||||
|  |   HAND_DECLARATIONS(Simt); | ||||||
|  |  | ||||||
|   int offset, ptype; |   int offset, ptype; | ||||||
|   StencilEntry *SE; |   StencilEntry *SE; | ||||||
| @@ -618,10 +730,16 @@ template<class Impl>  accelerator_inline | |||||||
| void WilsonKernels<Impl>::HandDhopSiteDagExt(StencilView &st,DoubledGaugeFieldView &U,SiteHalfSpinor *buf, | void WilsonKernels<Impl>::HandDhopSiteDagExt(StencilView &st,DoubledGaugeFieldView &U,SiteHalfSpinor *buf, | ||||||
| 						  int ss,int sU,const FermionFieldView &in, FermionFieldView &out) | 						  int ss,int sU,const FermionFieldView &in, FermionFieldView &out) | ||||||
| { | { | ||||||
|  |   auto st_p = st._entries_p;						 | ||||||
|  |   auto st_perm = st._permute_type;					 | ||||||
|   typedef typename Simd::scalar_type S; |   typedef typename Simd::scalar_type S; | ||||||
|   typedef typename Simd::vector_type V; |   typedef typename Simd::vector_type V; | ||||||
|  |   typedef decltype( coalescedRead( in[0]()(0)(0) )) Simt; | ||||||
|  |  | ||||||
|   HAND_DECLARATIONS(ignore); |   const int Nsimd = SiteHalfSpinor::Nsimd(); | ||||||
|  |   const int lane=acceleratorSIMTlane(Nsimd); | ||||||
|  |  | ||||||
|  |   HAND_DECLARATIONS(Simt); | ||||||
|  |  | ||||||
|   StencilEntry *SE; |   StencilEntry *SE; | ||||||
|   int offset, ptype; |   int offset, ptype; | ||||||
| @@ -682,3 +800,4 @@ NAMESPACE_END(Grid); | |||||||
| #undef HAND_RESULT | #undef HAND_RESULT | ||||||
| #undef HAND_RESULT_INT | #undef HAND_RESULT_INT | ||||||
| #undef HAND_RESULT_EXT | #undef HAND_RESULT_EXT | ||||||
|  | #undef HAND_DECLARATIONS | ||||||
|   | |||||||
| @@ -416,7 +416,21 @@ void WilsonKernels<Impl>::DhopDirKernel( StencilImpl &st, DoubledGaugeField &U,S | |||||||
| #undef LoopBody | #undef LoopBody | ||||||
| } | } | ||||||
|  |  | ||||||
| #define KERNEL_CALLNB(A) \ | #define KERNEL_CALL_TMP(A) \ | ||||||
|  |   const uint64_t    NN = Nsite*Ls;					\ | ||||||
|  |   auto U_p = & U_v[0];							\ | ||||||
|  |   auto in_p = & in_v[0];						\ | ||||||
|  |   auto out_p = & out_v[0];						\ | ||||||
|  |   auto st_p = st_v._entries_p;						\ | ||||||
|  |   auto st_perm = st_v._permute_type;					\ | ||||||
|  |   accelerator_forNB( ss, NN, Simd::Nsimd(), {				\ | ||||||
|  |       int sF = ss;							\ | ||||||
|  |       int sU = ss/Ls;							\ | ||||||
|  |       WilsonKernels<Impl>::A(st_perm,st_p,U_p,buf,sF,sU,in_p,out_p);	\ | ||||||
|  |     });									\ | ||||||
|  |   accelerator_barrier(); | ||||||
|  |  | ||||||
|  | #define KERNEL_CALLNB(A)						\ | ||||||
|   const uint64_t    NN = Nsite*Ls;					\ |   const uint64_t    NN = Nsite*Ls;					\ | ||||||
|   accelerator_forNB( ss, NN, Simd::Nsimd(), {				\ |   accelerator_forNB( ss, NN, Simd::Nsimd(), {				\ | ||||||
|       int sF = ss;							\ |       int sF = ss;							\ | ||||||
| @@ -445,20 +459,24 @@ void WilsonKernels<Impl>::DhopKernel(int Opt,StencilImpl &st,  DoubledGaugeField | |||||||
|  |  | ||||||
|    if( interior && exterior ) { |    if( interior && exterior ) { | ||||||
|      if (Opt == WilsonKernelsStatic::OptGeneric    ) { KERNEL_CALL(GenericDhopSite); return;} |      if (Opt == WilsonKernelsStatic::OptGeneric    ) { KERNEL_CALL(GenericDhopSite); return;} | ||||||
| #ifndef GRID_CUDA | #ifdef SYCL_HACK      | ||||||
|  |      if (Opt == WilsonKernelsStatic::OptHandUnroll ) { KERNEL_CALL_TMP(HandDhopSiteSycl);    return; } | ||||||
|  | #else | ||||||
|      if (Opt == WilsonKernelsStatic::OptHandUnroll ) { KERNEL_CALL(HandDhopSite);    return;} |      if (Opt == WilsonKernelsStatic::OptHandUnroll ) { KERNEL_CALL(HandDhopSite);    return;} | ||||||
|  | #endif      | ||||||
|  | #ifndef GRID_CUDA | ||||||
|      if (Opt == WilsonKernelsStatic::OptInlineAsm  ) {  ASM_CALL(AsmDhopSite);    return;} |      if (Opt == WilsonKernelsStatic::OptInlineAsm  ) {  ASM_CALL(AsmDhopSite);    return;} | ||||||
| #endif | #endif | ||||||
|    } else if( interior ) { |    } else if( interior ) { | ||||||
|      if (Opt == WilsonKernelsStatic::OptGeneric    ) { KERNEL_CALLNB(GenericDhopSiteInt); return;} |      if (Opt == WilsonKernelsStatic::OptGeneric    ) { KERNEL_CALLNB(GenericDhopSiteInt); return;} | ||||||
| #ifndef GRID_CUDA |  | ||||||
|      if (Opt == WilsonKernelsStatic::OptHandUnroll ) { KERNEL_CALLNB(HandDhopSiteInt);    return;} |      if (Opt == WilsonKernelsStatic::OptHandUnroll ) { KERNEL_CALLNB(HandDhopSiteInt);    return;} | ||||||
|  | #ifndef GRID_CUDA | ||||||
|      if (Opt == WilsonKernelsStatic::OptInlineAsm  ) {  ASM_CALL(AsmDhopSiteInt);    return;} |      if (Opt == WilsonKernelsStatic::OptInlineAsm  ) {  ASM_CALL(AsmDhopSiteInt);    return;} | ||||||
| #endif | #endif | ||||||
|    } else if( exterior ) { |    } else if( exterior ) { | ||||||
|      if (Opt == WilsonKernelsStatic::OptGeneric    ) { KERNEL_CALL(GenericDhopSiteExt); return;} |      if (Opt == WilsonKernelsStatic::OptGeneric    ) { KERNEL_CALL(GenericDhopSiteExt); return;} | ||||||
| #ifndef GRID_CUDA |  | ||||||
|      if (Opt == WilsonKernelsStatic::OptHandUnroll ) { KERNEL_CALL(HandDhopSiteExt);    return;} |      if (Opt == WilsonKernelsStatic::OptHandUnroll ) { KERNEL_CALL(HandDhopSiteExt);    return;} | ||||||
|  | #ifndef GRID_CUDA | ||||||
|      if (Opt == WilsonKernelsStatic::OptInlineAsm  ) {  ASM_CALL(AsmDhopSiteExt);    return;} |      if (Opt == WilsonKernelsStatic::OptInlineAsm  ) {  ASM_CALL(AsmDhopSiteExt);    return;} | ||||||
| #endif | #endif | ||||||
|    } |    } | ||||||
| @@ -476,20 +494,20 @@ void WilsonKernels<Impl>::DhopKernel(int Opt,StencilImpl &st,  DoubledGaugeField | |||||||
|  |  | ||||||
|    if( interior && exterior ) { |    if( interior && exterior ) { | ||||||
|      if (Opt == WilsonKernelsStatic::OptGeneric    ) { KERNEL_CALL(GenericDhopSiteDag); return;} |      if (Opt == WilsonKernelsStatic::OptGeneric    ) { KERNEL_CALL(GenericDhopSiteDag); return;} | ||||||
| #ifndef GRID_CUDA |  | ||||||
|      if (Opt == WilsonKernelsStatic::OptHandUnroll ) { KERNEL_CALL(HandDhopSiteDag);    return;} |      if (Opt == WilsonKernelsStatic::OptHandUnroll ) { KERNEL_CALL(HandDhopSiteDag);    return;} | ||||||
|  | #ifndef GRID_CUDA | ||||||
|      if (Opt == WilsonKernelsStatic::OptInlineAsm  ) {  ASM_CALL(AsmDhopSiteDag);     return;} |      if (Opt == WilsonKernelsStatic::OptInlineAsm  ) {  ASM_CALL(AsmDhopSiteDag);     return;} | ||||||
| #endif | #endif | ||||||
|    } else if( interior ) { |    } else if( interior ) { | ||||||
|      if (Opt == WilsonKernelsStatic::OptGeneric    ) { KERNEL_CALL(GenericDhopSiteDagInt); return;} |      if (Opt == WilsonKernelsStatic::OptGeneric    ) { KERNEL_CALL(GenericDhopSiteDagInt); return;} | ||||||
| #ifndef GRID_CUDA |  | ||||||
|      if (Opt == WilsonKernelsStatic::OptHandUnroll ) { KERNEL_CALL(HandDhopSiteDagInt);    return;} |      if (Opt == WilsonKernelsStatic::OptHandUnroll ) { KERNEL_CALL(HandDhopSiteDagInt);    return;} | ||||||
|  | #ifndef GRID_CUDA | ||||||
|      if (Opt == WilsonKernelsStatic::OptInlineAsm  ) {  ASM_CALL(AsmDhopSiteDagInt);     return;} |      if (Opt == WilsonKernelsStatic::OptInlineAsm  ) {  ASM_CALL(AsmDhopSiteDagInt);     return;} | ||||||
| #endif | #endif | ||||||
|    } else if( exterior ) { |    } else if( exterior ) { | ||||||
|      if (Opt == WilsonKernelsStatic::OptGeneric    ) { KERNEL_CALL(GenericDhopSiteDagExt); return;} |      if (Opt == WilsonKernelsStatic::OptGeneric    ) { KERNEL_CALL(GenericDhopSiteDagExt); return;} | ||||||
| #ifndef GRID_CUDA |  | ||||||
|      if (Opt == WilsonKernelsStatic::OptHandUnroll ) { KERNEL_CALL(HandDhopSiteDagExt);    return;} |      if (Opt == WilsonKernelsStatic::OptHandUnroll ) { KERNEL_CALL(HandDhopSiteDagExt);    return;} | ||||||
|  | #ifndef GRID_CUDA | ||||||
|      if (Opt == WilsonKernelsStatic::OptInlineAsm  ) {  ASM_CALL(AsmDhopSiteDagExt);     return;} |      if (Opt == WilsonKernelsStatic::OptInlineAsm  ) {  ASM_CALL(AsmDhopSiteDagExt);     return;} | ||||||
| #endif | #endif | ||||||
|    } |    } | ||||||
|   | |||||||
| @@ -1 +0,0 @@ | |||||||
| ../CayleyFermion5DInstantiation.cc.master |  | ||||||
| @@ -1 +0,0 @@ | |||||||
| ../ContinuedFractionFermion5DInstantiation.cc.master |  | ||||||
| @@ -1 +0,0 @@ | |||||||
| ../DomainWallEOFAFermionInstantiation.cc.master |  | ||||||
| @@ -1 +0,0 @@ | |||||||
| ../MobiusEOFAFermionInstantiation.cc.master |  | ||||||
| @@ -1 +0,0 @@ | |||||||
| ../PartialFractionFermion5DInstantiation.cc.master |  | ||||||
| @@ -1 +0,0 @@ | |||||||
| ../WilsonCloverFermionInstantiation.cc.master |  | ||||||
| @@ -1 +0,0 @@ | |||||||
| ../WilsonFermion5DInstantiation.cc.master |  | ||||||
| @@ -1 +0,0 @@ | |||||||
| ../WilsonFermionInstantiation.cc.master |  | ||||||
| @@ -1 +0,0 @@ | |||||||
| ../WilsonKernelsInstantiationGparity.cc.master |  | ||||||
| @@ -1 +0,0 @@ | |||||||
| ../WilsonTMFermionInstantiation.cc.master |  | ||||||
| @@ -1 +0,0 @@ | |||||||
| #define IMPLEMENTATION GparityWilsonImplDF |  | ||||||
| @@ -1 +0,0 @@ | |||||||
| ../CayleyFermion5DInstantiation.cc.master |  | ||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user