PCEtLXtzdWJ0ZW1wbGF0ZSBjb21tb24vaGVhZGVyX2NvbW1vbn0tLT4JPCEtLXtpZiAkX0dFVFsnbW9kJ10gPT0gJ3ZpZXd0aHJlYWQnICYmICFlbXB0eSgkX0dbJ3RpZCddKX0tLT4KCTxsaW5rIHJlbD0iY2Fub25pY2FsIiBocmVmPSJodHRwczovL3d3dy5xaWRhbzEyMy5jb20vYmJzL3RocmVhZC17JF9HWyd0aWQnXX0tMS0xLmh0bWwiIC8+Cgk8IS0te2Vsc2VpZiAkX0dFVFsnbW9kJ10gPT0gJ2ZvcnVtZGlzcGxheScgJiYgIWVtcHR5KCRfR1snZmlkJ10pfS0tPgoJPGxpbmsgcmVsPSJjYW5vbmljYWwiIGhyZWY9Imh0dHBzOi8vd3d3LnFpZGFvMTIzLmNvbS9iYnMvZm9ydW0teyRfR1snZmlkJ119LTEuaHRtbCIgLz4KCTwhLS17ZWxzZWlmICRfR0VUWydtb2QnXSA9PSAnZ3VpZGUnfS0tPgoJPGxpbmsgcmVsPSJjYW5vbmljYWwiIGhyZWY9Imh0dHBzOi8vd3d3LnFpZGFvMTIzLmNvbS9iYnMvZ3VpZGUvIiAvPgoJPCEtLXtlbHNlaWYgJF9HWydiYXNlc2NyaXB0J10gPT0gJ2ZvcnVtJyAmJiAoZW1wdHkoJF9HRVRbJ21vZCddKSB8fCAkX0dFVFsnbW9kJ10gPT0gJ2luZGV4Jyl9LS0+Cgk8bGluayByZWw9ImNhbm9uaWNhbCIgaHJlZj0iaHR0cHM6Ly93d3cucWlkYW8xMjMuY29tL2Jicy8iIC8+Cgk8IS0tey9pZn0tLT4KCXJgbmB0PG1ldGEgbmFtZT0iYXBwbGljYXRpb24tbmFtZSIgY29udGVudD0iJF9HWydzZXR0aW5nJ11bJ2JibmFtZSddIiAvPgoJPG1ldGEgbmFtZT0ibXNhcHBsaWNhdGlvbi10b29sdGlwIiBjb250ZW50PSIkX0dbJ3NldHRpbmcnXVsnYmJuYW1lJ10iIC8+Cgk8IS0te2lmICRfR1snc2V0dGluZyddWydwb3J0YWxzdGF0dXMnXX0tLT48bWV0YSBuYW1lPSJtc2FwcGxpY2F0aW9uLXRhc2siIGNvbnRlbnQ9Im5hbWU9JF9HWydzZXR0aW5nJ11bJ25hdnMnXVsxXVsnbmF2bmFtZSddO2FjdGlvbi11cmk9e2VjaG8gIWVtcHR5KCRfR1snc2V0dGluZyddWydkb21haW4nXVsnYXBwJ11bJ3BvcnRhbCddKSA/ICRfR1snc2NoZW1lJ10uJzovLycuJF9HWydzZXR0aW5nJ11bJ2RvbWFpbiddWydhcHAnXVsncG9ydGFsJ10gOiAkX0dbc2l0ZXVybF0uJ3BvcnRhbC5waHAnfTtpY29uLXVyaT17JF9HW3NpdGV1cmxdfXtJTUdESVJ9L3BvcnRhbC5pY28iIC8+PCEtLXsvaWZ9LS0+Cgk8bWV0YSBuYW1lPSJtc2FwcGxpY2F0aW9uLXRhc2siIGNvbnRlbnQ9Im5hbWU9JF9HWydzZXR0aW5nJ11bJ25hdnMnXVsyXVsnbmF2bmFtZSddO2FjdGlvbi11cmk9e2VjaG8gIWVtcHR5KCRfR1snc2V0dGluZyddWydkb21haW4nXVsnYXBwJ11bJ2ZvcnVtJ10pID8gJF9HWydzY2hlbWUnXS4nOi8vJy4kX0dbJ3NldHRpbmcnXVsnZG9tYWluJ11bJ2FwcCddWydmb3J1bSddIDogJF9HW3NpdGV1cmxdLidmb3J1bS5waHAnfTtpY29uLXVyaT17JF9HW3NpdGV1cmxdfXtJTUdESVJ9L2Jicy5pY28iIC8+Cgk8IS0te2lmICRfR1snc2V0dGluZyddWydncm91cHN0YXR1cyddfS0tPjxtZXRhIG5hbWU9Im1zYXBwbGljYXRpb24tdGFzayIgY29udGVudD0ibmFtZT0kX0dbJ3NldHRpbmcnXVsnbmF2cyddWzNdWyduYXZuYW1lJ107YWN0aW9uLXVyaT17ZWNobyAhZW1wdHkoJF9HWydzZXR0aW5nJ11bJ2RvbWFpbiddWydhcHAnXVsnZ3JvdXAnXSkgPyAkX0dbJ3NjaGVtZSddLic6Ly8nLiRfR1snc2V0dGluZyddWydkb21haW4nXVsnYXBwJ11bJ2dyb3VwJ10gOiAkX0dbc2l0ZXVybF0uJ2dyb3VwLnBocCd9O2ljb24tdXJpPXskX0dbc2l0ZXVybF19e0lNR0RJUn0vZ3JvdXAuaWNvIiAvPjwhLS17L2lmfS0tPgoJPCEtLXtpZiBoZWxwZXJfYWNjZXNzOjpjaGVja19tb2R1bGUoJ2ZlZWQnKX0tLT48bWV0YSBuYW1lPSJtc2FwcGxpY2F0aW9uLXRhc2siIGNvbnRlbnQ9Im5hbWU9JF9HWydzZXR0aW5nJ11bJ25hdnMnXVs0XVsnbmF2bmFtZSddO2FjdGlvbi11cmk9e2VjaG8gIWVtcHR5KCRfR1snc2V0dGluZyddWydkb21haW4nXVsnYXBwJ11bJ2hvbWUnXSkgPyAkX0dbJ3NjaGVtZSddLic6Ly8nLiRfR1snc2V0dGluZyddWydkb21haW4nXVsnYXBwJ11bJ2hvbWUnXSA6ICRfR1tzaXRldXJsXS4naG9tZS5waHAnfTtpY29uLXVyaT17JF9HW3NpdGV1cmxdfXtJTUdESVJ9L2hvbWUuaWNvIiAvPjwhLS17L2lmfS0tPgoJPCEtLXtpZiAkX0dbJ2Jhc2VzY3JpcHQnXSA9PSAnZm9ydW0nICYmICRfR1snc2V0dGluZyddWydhcmNoaXZlciddfS0tPgoJCTxsaW5rIHJlbD0iYXJjaGl2ZXMiIHRpdGxlPSIkX0dbJ3NldHRpbmcnXVsnYmJuYW1lJ10iIGhyZWY9InskX0dbc2l0ZXVybF19YXJjaGl2ZXIvIiAvPgoJPCEtLXsvaWZ9LS0+Cgk8IS0te2lmICFlbXB0eSgkcnNzaGVhZCl9LS0+JHJzc2hlYWQ8IS0tey9pZn0tLT4KCTwhLS17aWYgd2lkdGhhdXRvKCl9LS0+CgkJPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBpZD0iY3NzX3dpZHRoYXV0byIgdHlwZT0idGV4dC9jc3MiIGhyZWY9J3skX0dbJ3NldHRpbmcnXVsnY3NzcGF0aCddfXtTVFlMRUlEfV93aWR0aGF1dG8uY3NzP3tWRVJIQVNIfScgLz4KCQk8c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCI+SFRNTE5PREUuY2xhc3NOYW1lICs9ICcgd2lkdGhhdXRvJzwvc2NyaXB0PgoJPCEtLXsvaWZ9LS0+Cgk8IS0te2lmICRfR1snYmFzZXNjcmlwdCddID09ICdmb3J1bScgfHwgJF9HWydiYXNlc2NyaXB0J10gPT0gJ2dyb3VwJ30tLT4KCQk8c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCIgc3JjPSJ7JF9HW3NldHRpbmddW2pzcGF0aF19Zm9ydW0uanM/e1ZFUkhBU0h9Ij48L3NjcmlwdD4KCTwhLS17ZWxzZWlmICRfR1snYmFzZXNjcmlwdCddID09ICdob21lJ30tLT4KCQk8c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCIgc3JjPSJ7JF9HW3NldHRpbmddW2pzcGF0aF19aG9tZS5qcz97VkVSSEFTSH0iPjwvc2NyaXB0PgoJPCEtLXtlbHNlaWYgJF9HWydiYXNlc2NyaXB0J10gPT0gJ3BvcnRhbCd9LS0+CgkJPHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0ieyRfR1tzZXR0aW5nXVtqc3BhdGhdfXBvcnRhbC5qcz97VkVSSEFTSH0iPjwvc2NyaXB0PgoJPCEtLXsvaWZ9LS0+Cgk8IS0te2lmICRfR1snYmFzZXNjcmlwdCddICE9ICdwb3J0YWwnICYmICRfR0VUWydkaXknXSA9PSAneWVzJyAmJiBjaGVja19kaXlfcGVybSgkdG9waWMpfS0tPgoJCTxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0IiBzcmM9InskX0dbc2V0dGluZ11banNwYXRoXX1wb3J0YWwuanM/e1ZFUkhBU0h9Ij48L3NjcmlwdD4KCTwhLS17L2lmfS0tPgoJPCEtLXtpZiAkX0dFVFsnZGl5J10gPT0gJ3llcycgJiYgY2hlY2tfZGl5X3Blcm0oJHRvcGljKX0tLT4KCQk8bGluayByZWw9InN0eWxlc2hlZXQiIHR5cGU9InRleHQvY3NzIiBpZD0iZGl5X2NvbW1vbiIgaHJlZj0ieyRfR1snc2V0dGluZyddWydjc3NwYXRoJ119e1NUWUxFSUR9X2Nzc19kaXkuY3NzP3tWRVJIQVNIfSIgLz4KCTwhLS17L2lmfS0tPgo8L2hlYWQ+Cgo8Ym9keSBpZD0ibnZfeyRfR1tiYXNlc2NyaXB0XX0iIGNsYXNzPSJwZ197Q1VSTU9EVUxFfXtpZiAkX0dbJ2Jhc2VzY3JpcHQnXSA9PT0gJ3BvcnRhbCcgJiYgQ1VSTU9EVUxFID09PSAnbGlzdCcgJiYgIWVtcHR5KCRjYXQpfSB7JGNhdFsnYm9keWNzcyddfXsvaWZ9IiBvbmtleWRvd249ImlmKGV2ZW50LmtleUNvZGU9PTI3KSByZXR1cm4gZmFsc2U7Ij4KCTxkaXYgaWQ9ImFwcGVuZF9wYXJlbnQiPjwvZGl2PjxkaXYgaWQ9ImFqYXh3YWl0aWQiPjwvZGl2PgoJPCEtLXtpZiAkX0dFVFsnZGl5J10gPT0gJ3llcycgJiYgY2hlY2tfZGl5X3Blcm0oJHRvcGljKX0tLT4KCQk8IS0te3RlbXBsYXRlIGNvbW1vbi9oZWFkZXJfZGl5fS0tPgoJPCEtLXsvaWZ9LS0+Cgk8IS0te2lmIGNoZWNrX2RpeV9wZXJtKCR0b3BpYyl9LS0+CgkJPCEtLXt0ZW1wbGF0ZSBjb21tb24vaGVhZGVyX2RpeW5hdn0tLT4KCTwhLS17L2lmfS0tPgoJPCEtLXtpZiBDVVJNT0RVTEUgPT0gJ3RvcGljJyAmJiAkdG9waWMgJiYgZW1wdHkoJHRvcGljWyd1c2VoZWFkZXInXSkgJiYgY2hlY2tfZGl5X3Blcm0oJHRvcGljKX0tLT4KCQkkZGl5bmF2Cgk8IS0tey9pZn0tLT4KCTwhLS17aWYgZW1wdHkoJHRvcGljKSB8fCAkdG9waWNbJ3VzZWhlYWRlciddfS0tPgoJCTwhLS17aWYgJF9HWydzZXR0aW5nJ11bJ21vYmlsZSddWydhbGxvd21vYmlsZSddICYmICghJF9HWydzZXR0aW5nJ11bJ2NhY2hlaW5kZXhsaWZlJ10gJiYgISRfR1snc2V0dGluZyddWydjYWNoZXRocmVhZG9uJ10gfHwgJF9HWyd1aWQnXSkgJiYgKCRfR0VUWydkaXknXSAhPSAneWVzJyB8fCAhJF9HRVRbJ2luYWpheCddKSAmJiAoJF9HWydtb2JpbGUnXSAhPSAnJyAmJiAkX0dbJ2Nvb2tpZSddWydtb2JpbGUnXSA9PSAnJyAmJiAkX0dFVFsnbW9iaWxlJ10gIT0gJ25vJyl9LS0+CgkJCTxkaXYgY2xhc3M9InhpMSBibSBibV9jIj4KCQkJICAgIHtsYW5nIHlvdXJfbW9iaWxlX2Jyb3dzZXJ9PGEgaHJlZj0ieyRfR1snc2l0ZXVybCddfWZvcnVtLnBocD9tb2JpbGU9eWVzIj57bGFuZyBnb190b19tb2JpbGV9PC9hPiA8c3BhbiBjbGFzcz0ieGcxIj58PC9zcGFuPiA8YSBocmVmPSIkX0dbJ3NldHRpbmcnXVsnbW9iaWxlJ11bJ25vbW9iaWxldXJsJ10iPntsYW5nIHRvX2JlX2NvbnRpbnVlfTwvYT4KCQkJPC9kaXY+CgkJPCEtLXsvaWZ9LS0+CgkJPCEtLXtpZiAhZW1wdHkoJF9HWydzZXR0aW5nJ11bJ3Nob3J0Y3V0J10pICYmICRfR1snbWVtYmVyJ11bY3JlZGl0c10gPj0gJF9HWydzZXR0aW5nJ11bJ3Nob3J0Y3V0J119LS0+CgkJCTxkaXYgaWQ9InNob3J0Y3V0Ij4KCQkJCTxzcGFuPjxhIGhyZWY9ImphdmFzY3JpcHQ6OyIgaWQ9InNob3J0Y3V0Y2xvc2VpZCIgdGl0bGU9IntsYW5nIGNsb3NlfSI+e2xhbmcgY2xvc2V9PC9hPjwvc3Bhbj4KCQkJCXtsYW5nIHNob3J0Y3V0X25vdGljZX0KCQkJCTxhIGhyZWY9ImphdmFzY3JpcHQ6OyIgaWQ9InNob3J0Y3V0dGlwIj57bGFuZyBzaG9ydGN1dF9hZGR9PC9hPgoKCQkJPC9kaXY+CgkJCTxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0Ij5zZXRUaW1lb3V0KHNldFNob3J0Y3V0LCAyMDAwKTs8L3NjcmlwdD4KCQk8IS0tey9pZn0tLT4KCQk8ZGl2IGlkPSJ0b3B0YiIgY2xhc3M9ImNsIj4KCQkJPCEtLXtob29rL2dsb2JhbF9jcG5hdl90b3B9LS0+CgkJCTxkaXYgY2xhc3M9IndwIj4KCQkJCTxkaXYgY2xhc3M9InoiPgoJCQkJCTwhLS17bG9vcCAkX0dbJ3NldHRpbmcnXVsndG9wbmF2cyddWzBdICRuYXZ9LS0+CgkJCQkJCTwhLS17aWYgaXNfYXJyYXkoJG5hdikgJiYgJG5hdlsnYXZhaWxhYmxlJ10gJiYgKCEkbmF2WydsZXZlbCddIHx8ICgkbmF2WydsZXZlbCddID09IDEgJiYgJF9HWyd1aWQnXSkgfHwgKCRuYXZbJ2xldmVsJ10gPT0gMiAmJiAkX0dbJ2FkbWluaWQnXSA+IDApIHx8ICgkbmF2WydsZXZlbCddID09IDMgJiYgJF9HWydhZG1pbmlkJ10gPT0gMSkpfS0tPiRuYXZbY29kZV08IS0tey9pZn0tLT4KCQkJCQk8IS0tey9sb29wfS0tPgoJCQkJCTwhLS17aG9vay9nbG9iYWxfY3BuYXZfZXh0cmExfS0tPgoJCQkJPC9kaXY+CgkJCQk8ZGl2IGNsYXNzPSJ5Ij4KCQkJCQk8YSBpZD0ic3dpdGNoYmxpbmQiIGhyZWY9ImphdmFzY3JpcHQ6OyIgb25jbGljaz0idG9nZ2xlQmxpbmQodGhpcykiIHRpdGxlPSJ7bGFuZyBzd2l0Y2hfYmxpbmR9IiBjbGFzcz0ic3dpdGNoYmxpbmQiPjwvYT4KCQkJCQk8IS0te2hvb2svZ2xvYmFsX2NwbmF2X2V4dHJhMn0tLT4KCQkJCQk8IS0te2xvb3AgJF9HWydzZXR0aW5nJ11bJ3RvcG5hdnMnXVsxXSAkbmF2fS0tPgoJCQkJCQk8IS0te2lmIGlzX2FycmF5KCRuYXYpICYmICRuYXZbJ2F2YWlsYWJsZSddICYmICghJG5hdlsnbGV2ZWwnXSB8fCAoJG5hdlsnbGV2ZWwnXSA9PSAxICYmICRfR1sndWlkJ10pIHx8ICgkbmF2WydsZXZlbCddID09IDIgJiYgJF9HWydhZG1pbmlkJ10gPiAwKSB8fCAoJG5hdlsnbGV2ZWwnXSA9PSAzICYmICRfR1snYWRtaW5pZCddID09IDEpKX0tLT4kbmF2W2NvZGVdPCEtLXsvaWZ9LS0+CgkJCQkJPCEtLXsvbG9vcH0tLT4KCQkJCQk8IS0te2lmIGVtcHR5KCRfR1snZGlzYWJsZWR3aWR0aGF1dG8nXSkgJiYgJF9HWydzZXR0aW5nJ11bJ3N3aXRjaHdpZHRoYXV0byddfS0tPgoJCQkJCQk8YSBocmVmPSJqYXZhc2NyaXB0OjsiIGlkPSJzd2l0Y2h3aWR0aCIgb25jbGljaz0id2lkdGhhdXRvKHRoaXMpIiB0aXRsZT0ie2lmIHdpZHRoYXV0bygpfXtsYW5nIHN3aXRjaF9uYXJyb3d9e2Vsc2V9e2xhbmcgc3dpdGNoX3dpZGV9ey9pZn0iIGNsYXNzPSJzd2l0Y2h3aWR0aCI+PCEtLXtpZiB3aWR0aGF1dG8oKX0tLT57bGFuZyBzd2l0Y2hfbmFycm93fTwhLS17ZWxzZX0tLT57bGFuZyBzd2l0Y2hfd2lkZX08IS0tey9pZn0tLT48L2E+CgkJCQkJPCEtLXsvaWZ9LS0+CgkJCQkJPCEtLXtpZiAkX0dbJ3VpZCddICYmICFlbXB0eSgkX0dbJ3N0eWxlJ11bJ2V4dHN0eWxlJ10pfS0tPjxhIGlkPSJzc2xjdCIgaHJlZj0iamF2YXNjcmlwdDo7IiBvbm1vdXNlb3Zlcj0iZGVsYXlTaG93KHRoaXMsIGZ1bmN0aW9uKCkge3Nob3dNZW51KHsnY3RybGlkJzonc3NsY3QnLCdwb3MnOiczNCEnfSl9KTsiPntsYW5nIGNoYW5nZXN0eWxlfTwvYT48IS0tey9pZn0tLT4KCQkJCQk8IS0te2lmIGNoZWNrX2RpeV9wZXJtKCR0b3BpYyl9LS0+CgkJCQkJCSRkaXluYXYKCQkJCQk8IS0tey9pZn0tLT4KCQkJCTwvZGl2PgoJCQk8L2Rpdj4KCQk8L2Rpdj4KCgkJPCEtLXtpZiAhSVNfUk9CT1R9LS0+CgkJCTwhLS17aWYgJF9HWyd1aWQnXSAmJiAhJF9HWydzZXR0aW5nJ11bJ2JiY2xvc2VkJ10gJiYgZW1wdHkoJF9HWydtZW1iZXInXVsnZnJlZXplJ10pICYmICRfR1snbWVtYmVyJ11bJ2dyb3VwaWQnXSAhPSA1fS0tPgoJCQk8dWwgaWQ9Im15cHJvbXB0X21lbnUiIGNsYXNzPSJwX3BvcCIgc3R5bGU9ImRpc3BsYXk6IG5vbmU7Ij4KCQkJCTxsaT48YSBocmVmPSJob21lLnBocD9tb2Q9c3BhY2UmZG89cG0iIGlkPSJwbV9udGMiIHN0eWxlPSJiYWNrZ3JvdW5kLXJlcGVhdDogbm8tcmVwZWF0OyBiYWNrZ3JvdW5kLXBvc2l0aW9uOiAwIDUwJTsiPjxlbSBjbGFzcz0icHJvbXB0X25ld3N7aWYgZW1wdHkoJF9HW21lbWJlcl1bbmV3cG1dKX1fMHsvaWZ9Ij48L2VtPntsYW5nIHBtX2NlbnRlcn08L2E+PC9saT4KCQkJCTwhLS17aWYgJF9HWydzZXR0aW5nJ11bJ2ZvbGxvd3N0YXR1cyddfS0tPgoJCQkJCTxsaT48YSBocmVmPSJob21lLnBocD9tb2Q9Zm9sbG93JmRvPWZvbGxvd2VyIj48ZW0gY2xhc3M9InByb21wdF9mb2xsb3dlcntpZiBlbXB0eSgkX0dbbWVtYmVyXVtuZXdwcm9tcHRfbnVtXVtmb2xsb3dlcl0pfV8wey9pZn0iPjwvZW0+PCEtLXtsYW5nIG5vdGljZV9pbnRlcmFjdGl2ZV9mb2xsb3dlcn0tLT57aWYgJF9HW21lbWJlcl1bbmV3cHJvbXB0X251bV1bZm9sbG93ZXJdfSgkX0dbbWVtYmVyXVtuZXdwcm9tcHRfbnVtXVtmb2xsb3dlcl0pey9pZn08L2E+PC9saT4KCQkJCQk8IS0te2lmICRfR1ttZW1iZXJdW25ld3Byb21wdF0gJiYgJF9HW21lbWJlcl1bbmV3cHJvbXB0X251bV1bZm9sbG93XX0tLT4KCQkJCQkJPGxpPjxhIGhyZWY9ImhvbWUucGhwP21vZD1mb2xsb3ciPjxlbSBjbGFzcz0icHJvbXB0X2NvbmNlcm4iPjwvZW0+PCEtLXtsYW5nIG5vdGljZV9pbnRlcmFjdGl2ZV9mb2xsb3d9LS0+KCRfR1ttZW1iZXJdW25ld3Byb21wdF9udW1dW2ZvbGxvd10pPC9hPjwvbGk+CgkJCQkJPCEtLXsvaWZ9LS0+CgkJCQk8IS0tey9pZn0tLT4KCQkJCTwhLS17aWYgJF9HW21lbWJlcl1bbmV3cHJvbXB0XX0tLT4KCQkJCQk8IS0te2xvb3AgJF9HWydtZW1iZXInXVsnY2F0ZWdvcnlfbnVtJ10gJGtleSAkdmFsfS0tPgoJCQkJCQk8bGk+PGEgaHJlZj0iaG9tZS5waHA/bW9kPXNwYWNlJmRvPW5vdGljZSZ2aWV3PSRrZXkiPjxlbSBjbGFzcz0ibm90aWNlXyRrZXkiPjwvZW0+PCEtLXtlY2hvIGxhbmcoJ3RlbXBsYXRlJywgJ25vdGljZV8nLiRrZXkpfS0tPig8c3BhbiBjbGFzcz0icnEiPiR2YWw8L3NwYW4+KTwvYT48L2xpPgoJCQkJCTwhLS17L2xvb3B9LS0+CgkJCQk8IS0tey9pZn0tLT4KCQkJCTwhLS17aWYgZW1wdHkoJF9HWydjb29raWUnXVsnaWdub3JlX25vdGljZSddKX0tLT4KCQkJCQk8bGkgY2xhc3M9Imlnbm9yZV9ub3RpY2VsaSI+PGEgaHJlZj0iamF2YXNjcmlwdDo7IiBvbmNsaWNrPSJzZXRjb29raWUoJ2lnbm9yZV9ub3RpY2UnLCAxKTtoaWRlTWVudSgnbXlwcm9tcHRfbWVudScpIiB0aXRsZT0ie2xhbmcgdGVtcG9yYXJpbHlfdG9fcmVtaW5kfSI+PGVtIGNsYXNzPSJpZ25vcmVfbm90aWNlIj48L2VtPjwvYT48L2xpPgoJCQkJPCEtLXsvaWZ9LS0+CgkJCTwvdWw+CgkJCTwhLS17L2lmfS0tPgoJCQk8IS0te2lmICRfR1sndWlkJ10gJiYgIWVtcHR5KCRfR1snc3R5bGUnXVsnZXh0c3R5bGUnXSl9LS0+CgkJCQk8ZGl2IGlkPSJzc2xjdF9tZW51IiBjbGFzcz0iY2wgcF9wb3AiIHN0eWxlPSJkaXNwbGF5OiBub25lOyI+CgkJCQkJPCEtLXtpZiAhJF9HW3N0eWxlXVtkZWZhdWx0ZXh0c3R5bGVdfS0tPjxzcGFuIGNsYXNzPSJzc2xjdF9idG4iIG9uY2xpY2s9ImV4dHN0eWxlKCcnKSIgdGl0bGU9IntsYW5nIGRlZmF1bHR9Ij48aT48L2k+PC9zcGFuPjwhLS17L2lmfS0tPgoJCQkJCTwhLS17bG9vcCAkX0dbJ3N0eWxlJ11bJ2V4dHN0eWxlJ10gJGV4dHN0eWxlfS0tPgoJCQkJCQk8c3BhbiBjbGFzcz0ic3NsY3RfYnRuIiBvbmNsaWNrPSJleHRzdHlsZSgnJGV4dHN0eWxlWzBdJykiIHRpdGxlPSIkZXh0c3R5bGVbMV0iPjxpIHN0eWxlPSdiYWNrZ3JvdW5kOiRleHRzdHlsZVsyXSc+PC9pPjwvc3Bhbj4KCQkJCQk8IS0tey9sb29wfS0tPgoJCQkJPC9kaXY+CgkJCTwhLS17L2lmfS0tPgoJCQk8IS0te2lmICRfR1sndWlkJ119LS0+CgkJCQk8dWwgaWQ9Im15aXRlbV9tZW51IiBjbGFzcz0icF9wb3AiIHN0eWxlPSJkaXNwbGF5OiBub25lOyI+CgkJCQkJPCEtLXtpZiAkX0dbJ3NldHRpbmcnXVsnZm9ydW1zdGF0dXMnXX0tLT48bGk+PGEgaHJlZj0iaG9tZS5waHA/bW9kPXNwYWNlJmRvPXRocmVhZCZ2aWV3PW1lIj57bGFuZyBteXBvc3R9PC9hPjwvbGk+PCEtLXsvaWZ9LS0+CgkJCQkJPCEtLXtpZiAkX0dbJ3NldHRpbmcnXVsnZmF2b3JpdGVzdGF0dXMnXX0tLT48bGk+PGEgaHJlZj0iaG9tZS5waHA/bW9kPXNwYWNlJmRvPWZhdm9yaXRlJnZpZXc9bWUiPntsYW5nIGZhdm9yaXRlfTwvYT48L2xpPjwhLS17L2lmfS0tPgoJCQkJCTwhLS17aWYgJF9HWydzZXR0aW5nJ11bJ2ZyaWVuZHN0YXR1cyddfS0tPjxsaT48YSBocmVmPSJob21lLnBocD9tb2Q9c3BhY2UmZG89ZnJpZW5kIj57bGFuZyBmcmllbmRzfTwvYT48L2xpPjwhLS17L2lmfS0tPgoJCQkJCTwhLS17aG9vay9nbG9iYWxfbXlpdGVtX2V4dHJhfS0tPgoJCQkJPC91bD4KCQkJPCEtLXsvaWZ9LS0+CgkJCTwhLS17c3VidGVtcGxhdGUgY29tbW9uL2hlYWRlcl9xbWVudX0tLT4KCQk8IS0tey9pZn0tLT4KCgkJPCEtLXthZC9oZWFkZXJiYW5uZXIvd3AgYV9ofS0tPgoJCTxkaXYgaWQ9ImhkIj4KCQkJPGRpdiBjbGFzcz0id3AiPgoJCQkJPGRpdiBjbGFzcz0iaGRjIGNsIj4KCQkJCQk8IS0te2V2YWwgJG1uaWQgPSBnZXRjdXJyZW50bmF2KCk7fS0tPgoJCQkJCTxoMj48IS0te2lmICFpc3NldCgkX0dbJ3NldHRpbmcnXVsnbmF2bG9nb3MnXVskbW5pZF0pfS0tPjxhIGhyZWY9IntpZiAkX0dbJ3NldHRpbmcnXVsnZG9tYWluJ11bJ2FwcCddWydkZWZhdWx0J119eyRfR1snc2NoZW1lJ119Oi8veyRfR1snc2V0dGluZyddWydkb21haW4nXVsnYXBwJ11bJ2RlZmF1bHQnXX0ve2Vsc2V9Li97L2lmfSIgdGl0bGU9IiRfR1snc2V0dGluZyddWydiYm5hbWUnXSI+eyRfR1snc3R5bGUnXVsnYm9hcmRsb2dvJ119PC9hPjwhLS17ZWxzZX0tLT4kX0dbJ3NldHRpbmcnXVsnbmF2bG9nb3MnXVskbW5pZF08IS0tey9pZn0tLT48L2gyPgoJCQkJCTwhLS17dGVtcGxhdGUgY29tbW9uL2hlYWRlcl91c2Vyc3RhdHVzfS0tPgoJCQkJPC9kaXY+CgoJCQkJPGRpdiBpZD0ibnYiPgoJCQkJCTxhIGhyZWY9ImphdmFzY3JpcHQ6OyIgaWQ9InFtZW51IiBvbm1vdXNlb3Zlcj0iZGVsYXlTaG93KHRoaXMsIGZ1bmN0aW9uICgpIHtzaG93TWVudSh7J2N0cmxpZCc6J3FtZW51JywncG9zJzonMzQhJywnY3RybGNsYXNzJzonYScsJ2R1cmF0aW9uJzoyfSk7c2hvd0ZvcnVtbWVudSgkX0dbZmlkXSk7fSkiPntsYW5nIG15X25hdn08L2E+CgkJCQkJPHVsPgoJCQkJCQk8IS0te2xvb3AgJF9HWydzZXR0aW5nJ11bJ25hdnMnXSAkbmF2fS0tPgoJCQkJCQkJPCEtLXtpZiBpc19hcnJheSgkbmF2KSAmJiAkbmF2WydhdmFpbGFibGUnXSAmJiAoISRuYXZbJ2xldmVsJ10gfHwgKCRuYXZbJ2xldmVsJ10gPT0gMSAmJiAkX0dbJ3VpZCddKSB8fCAoJG5hdlsnbGV2ZWwnXSA9PSAyICYmICRfR1snYWRtaW5pZCddID4gMCkgfHwgKCRuYXZbJ2xldmVsJ10gPT0gMyAmJiAkX0dbJ2FkbWluaWQnXSA9PSAxKSl9LS0+PGxpIHtpZiAkbW5pZCA9PSAkbmF2W25hdmlkXSB8fCBzdWJzdHIoJF9TRVJWRVJbJ1JFUVVFU1RfVVJJJ10sIDEpID09IHN0cl9yZXBsYWNlKCcuLycsICcnLCAkbmF2W2ZpbGVuYW1lXSl9Y2xhc3M9ImEiIHsvaWZ9JG5hdltuYXZdPjwvbGk+PCEtLXsvaWZ9LS0+CgkJCQkJCTwhLS17L2xvb3B9LS0+CgkJCQkJPC91bD4KCQkJCQk8IS0te2hvb2svZ2xvYmFsX25hdl9leHRyYX0tLT4KCQkJCTwvZGl2PgoJCQkJPCEtLXtpZiAhZW1wdHkoJF9HWydzZXR0aW5nJ11bJ3BsdWdpbnMnXVsnanNtZW51J10pfS0tPgoJCQkJCTx1bCBjbGFzcz0icF9wb3AgaF9wb3AiIGlkPSJwbHVnaW5fbWVudSIgc3R5bGU9ImRpc3BsYXk6IG5vbmUiPgoJCQkJCTwhLS17bG9vcCAkX0dbJ3NldHRpbmcnXVsncGx1Z2lucyddWydqc21lbnUnXSAkbW9kdWxlfS0tPgoJCQkJCQkgPCEtLXtpZiBpbl9hcnJheSgkbW9kdWxlWydhZG1pbmlkJ10sIGFycmF5KDAsIC0xKSkgfHwgKCRtb2R1bGVbJ2FkbWluaWQnXSAmJiAkX0dbJ2FkbWluaWQnXSA+IDAgJiYgJG1vZHVsZVsnYWRtaW5pZCddID49ICRfR1snYWRtaW5pZCddKX0tLT4KCQkJCQkJIDxsaT4kbW9kdWxlW3VybF08L2xpPgoJCQkJCQkgPCEtLXsvaWZ9LS0+CgkJCQkJPCEtLXsvbG9vcH0tLT4KCQkJCQk8L3VsPgoJCQkJPCEtLXsvaWZ9LS0+CgkJCQkkX0dbc2V0dGluZ11bbWVudW5hdnNdCgkJCQk8ZGl2IGlkPSJtdSIgY2xhc3M9ImNsIj4KCQkJCTwhLS17aWYgJF9HWydzZXR0aW5nJ11bJ3N1Ym5hdnMnXX0tLT4KCQkJCQk8IS0te2xvb3AgJF9HW3NldHRpbmddW3N1Ym5hdnNdICRuYXZpZCAkc3VibmF2fS0tPgoJCQkJCQk8IS0te2lmICRfR1snc2V0dGluZyddWyduYXZzdWJob3ZlciddIHx8ICRtbmlkID09ICRuYXZpZH0tLT4KCQkJCQkJPHVsIGNsYXNzPSJjbCB7aWYgJG1uaWQgPT0gJG5hdmlkfWN1cnJlbnR7L2lmfSIgaWQ9InNuYXZfJG5hdmlkIntpZiAkbW5pZCAhPSAkbmF2aWR9IHN0eWxlPSJkaXNwbGF5Om5vbmUiey9pZn0+CgkJCQkJCSRzdWJuYXYKCQkJCQkJPC91bD4KCQkJCQkJPCEtLXsvaWZ9LS0+CgkJCQkJPCEtLXsvbG9vcH0tLT4KCQkJCTwhLS17L2lmfS0tPgoJCQkJPC9kaXY+CgkJCQk8IS0te2FkL3N1Ym5hdmJhbm5lci9hX211fS0tPgoJCQkJPCEtLXtzdWJ0ZW1wbGF0ZSBjb21tb24vcHVic2VhcmNoZm9ybX0tLT4KCQkJPC9kaXY+CgkJPC9kaXY+CgoJCTwhLS17aG9vay9nbG9iYWxfaGVhZGVyfS0tPgoJPCEtLXsvaWZ9LS0+CgoJPGRpdiBpZD0id3AiIGNsYXNzPSJ3cCI+Cg==
qidao123.com ToB IT社区-企服评测·应用市场»论坛 › 容器及微服务 › 容器及微服务 › 云计算基础实验
返回列表 发新帖

云计算基础实验

[复制链接]
发表于 2024-12-5 08:17:18 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
云计算基础实验报告

实验一 Linux环境下算法的测试

一, 根据基本计算头脑,验证和求解,设计算法。
根据运行需要,自行完成(C和Python)环境配置。
1.1验证卡布列克常数6174

原理过程:

  • 循环输入一个1000-9999之间的数字,找出其最大数和其最小数,并进行相减。直到其末了值得到6174.
  • 输出此卡布列克常数的运算过程以及结果
       

算法实现(在C语言环境运行)
  1. #include<stdio.h>
  2. void sort(int a[], int num)   //将数字按照从大到小的顺序排列
  3. {
  4.     int i, j, temp;
  5.     for (i = 0; i < num; i++)
  6.         for (j = i + 1; j < num; j++)
  7.             if (a[i] > a[j])
  8.             {
  9.                 temp = a[i];
  10.                 a[i] = a[j];
  11.                 a[j] = temp;
  12.             }
  13. }
  14. int main() {
  15.     int n = 1000, count, result, s;
  16.     int a[4];   //存储一个4位数
  17.     int max, min;   //存放最大值最小值
  18.     printf("验证[1000-9999]卡布列克常数6174:");
  19.     while (n <= 9999)
  20.     {
  21.         count = 1; result = 0;
  22.         s = n;
  23.         
  24.         while (n != 6174 && result != 6174 && count <= 7)
  25.         {
  26.             a[0] = s % 10;                        /*分别算出4位数,再将其存放在数组中*/
  27.             a[1] = s / 10 % 10;
  28.             a[2] = s / 100 % 10;
  29.             a[3] = s / 1000;
  30.             sort(a, 4);   //调用函数
  31.             max = 1000 * a[3] + 100 * a[2] + 10 * a[1] + a[0]; //计算最大值
  32.             min = 1000 * a[0] + 100 * a[1] + 10 * a[2] + a[3];//计算最小值
  33.             printf("[%d] : %d - %d = %d\n", count, max, min, max - min);
  34.             result = max - min;
  35.             count++;    //统计进行了几次计算
  36.             
  37.             if (result == 6174 && count < 8)
  38.             {
  39.                 printf("%d is the num.\n", n);
  40.                 printf("-----------------------\n");
  41.             }
  42.             
  43.                   
  44.             s = result; //将进行减的值赋给s,回到while循环判断
  45.         }   
  46.         n = n + 1;
  47.     }
  48.     return 0;
  49. }
复制代码
结果显示(运行截图)

1.2蒙特卡洛算法

原理过程:
定义一个常量NUM_POINTS,体现要天生的随机点的数量。
利用rand()函数天生随机点,并查抄这些点是否落在单位圆内(即x^2 + y^2 <= 1)
每天生一个落在单位圆内的点,计数器inside_circle就增长1
计算并输出π的估计值。
算法实现(

在C语言环境运行)
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4. #define NUM_POINTS 1000000
  5. int main() {
  6.     int inside_circle = 0;
  7.     double x, y;
  8.     // 初始化随机数种子
  9.     srand(time(NULL));
  10.     // 生成NUM_POINTS个随机点
  11.     for (int i = 0; i < NUM_POINTS; i++) {
  12.         // 生成0到1之间的随机数作为x和y坐标
  13.         x = (double)rand() / RAND_MAX;
  14.         y = (double)rand() / RAND_MAX;
  15.         // 检查点是否在单位圆内
  16.         if (x * x + y * y <= 1.0) {
  17.             inside_circle++;
  18.         }
  19.     }
  20.     // 计算π的估计值
  21.     double pi = 4.0 * inside_circle / NUM_POINTS;
  22.     printf("估计的π值为: %.6f\n", pi);
  23.     return 0;
  24. }
复制代码
结果显示(运行截图)

1.3冰雹猜想验证(验证范围1~100)

原理过程:
输入一个1-100之间的整数n,如果n为偶数,就将它变成n/2,如果除后变成奇数,则将它乘3加1,不断重复运算,经过有限步数后,是否可以得到1

算法实现(在C语言环境运行)
  1. #include<stdio.h>
  2. int main()
  3. {
  4.     int i,number,count=0;
  5.     for(i=1; i<=100; i++)
  6.     {
  7.         number = i;
  8.         printf("%d : ",number);
  9.         while(number != 1)
  10.         {
  11.             if (number % 2 == 0)
  12.             {
  13.                 number /= 2;
  14.                 printf("%d - ", number);
  15.             }
  16.             else
  17.             {
  18.                 number = number * 3 + 1;
  19.                 printf("%d - ", number);
  20.             }
  21.             count++;
  22.         }
  23.         printf("共执行了%d步\n",count);  
  24. }
  25. return 0;
  26. }
复制代码
结果显示(运行截图)

1.4亲和数验证(验证范围1~10000)

原理过程:
如果整数A的全部因子(包括1,但不包括其本身)之和等于整数B,整数B的因子(包括1,但不包括其本身)之和等于整数A,则整数A与B称为密切数。

算法实现(在C语言环境运行)
  1. #include<stdio.h>
  2. int main()
  3. {
  4.     int a=1, i=1;
  5.     int j=1;
  6.     for(a=1; a<=10000; a++)
  7.     {
  8.         int B = 0, A = 0;
  9.         for(i=1; i<a; i++)
  10.         {
  11.             if(a%i==0)
  12.                 {
  13.                     B = B + i;
  14.                 }
  15.         }
  16.         for(j=1; j<B; j++)
  17.         {
  18.             if(B%j == 0)
  19.                 {
  20.                     A = A + j;
  21.                 }
  22.         }
  23.         if(A == a )
  24.             {
  25.                 printf("%d和%d是亲和数\n",a,B);
  26.             }
  27.     }
  28.     return 0;
  29. }
复制代码
结果显示(运行截图)

实验二 MPI分布式运行框架设计

一、 实验目标
设计运行框架,了解运行环境需求。
nfs的应用
mpi的安装和利用
mpi的环境测试
二、 实验环境
Ubuntu 22.04 (LTS),
VM环境下,网络架构NAT,
计算节点数:4个
三、 基本步调介绍:
3.1 构建四台计算节点

  • 每个节点计算机的网络均采用NAT模式,构建一个内部的计算集群.
  • 设置每个节点的hostname,依次是node01, node02, node03, node04。
  • 根据上一步序次,依次设置每个节点ip,范围(192.168.26.111~114)。




四台主机都需要进行此配置

3.2 构建四台计算节点之间相互免密钥访问(利用rsa方式天生)

#公钥和密钥都已天生


3.3 给四台主机安装nfs并实现永久挂载

  • 四台节点,全部安装nfs及nfs-utils
//下载nfs


  • node01节点作为运行主节点,启动并运行nfs服务程序,该程序随系统启动。


  • node01节点作为运行主节点,提供挂载的目次资源。
挂载目次/var/mpi4.0/,如果没有此目次,则先创建,再修改配置文件提供挂载。


  • 别的节点node02~04,实现永久挂载主节点node01的共享目次,并具有读写权限。
770:可读可写,
sync:共享目次同步文件,
no_root_squash:root权限设置**
//现永久挂载主机 node01节点的共享目次

///在node02-04客户端上安装nfs-common(客户端包)

///在node01上重启nfs服务器,在node02-04上挂载目次到node01实现目次共享

#mount:这是用来挂载文件系统的命令。
#-t nfs:这指定了文件系统的类型为NFS。
#-o nolock:这是挂载选项,nolock体现客户端不锁定文件,这可以提高性能,但可能不恰当需要严酷文件锁定的应用。
#192.168.26.111:/var/mpi4.0:这是NFS服务器的IP地点和要挂载的远程目次的路径。这里假设NFS服务器的IP地点是192.168.26.111,而且您想要挂载的目次是/var/mpi4.0。
/var/mp14.0:这是当地挂载点的路径,即您希望将远程目次挂载到当地的哪个位置。


//编辑配置文件实现永久挂载
3.4 在node01节点上安装mpi4.0

  • 通过官方网站链接,下载mpi4.0源码包(四台主机都要安装)
https://www.mpich.org/static/downloads/4.0/mpich-4.0.tar.gz

编译安装mpi到/var/mpi4.0/(四台假造机都要实行)
解压缩文件包
//解压

//安装编译软件

a) 进入mpich解压目次,安装make
//绿色为可实行文件,蓝色为目次

b) 设置安装目次(以下配置信息,仅供参考,未写完备,实行会有错误提示。请根据错误提示,修改正确)
**#./configure –disable-fortran --prefix=/**var/mpi4.0
**报错:**configure: error: The Fortran compiler gfortran does not accept programs that call the same
#–disable-fortran:告诉配置脚本在编译过程中不利用Fortran编译器支持。
–prefix=/var/mpi4.0**:** 指定了软件安装的前缀路径,软件将被安装到**/var/mpi4.0****目次下,所有相关的可实行文件、库文件、头文件等都将被放置在这个目次及其子目次中。**

**//**配置安装乐成

c) make编译

d) make install 安装

#赋值放置程序的文件夹到共享目次/var/mpi4.0


#安装mpich

#切换到daisy用户(由于你如果用root用户编译运行程序,会导致权限过大)

#利用6个进程实行./cpi(下面显示运行结果和运行时间)

e) 退出到用户的主目次
#cd
f) 通过编辑.bashrc文件修改环境变量(每次打开终端时都会加载的启动项)
  1. vim .bashrc
复制代码

g) 测试环境变量设置
#source ~/.bashrc
#which mpicc 查察位置信息
#which mpiexec

h) 在/var/mpi4.0/examples下,创建主机名称聚集文件csmpd.hosts,
  1. vim csmpd.hosts
复制代码
文件内容如下:

3.5环境测试

  • 测试运行MPICH的例子程序
查询怎样编译mpi源代码,怎样运行mpi程序

  • 例子程序运行截图
#rank是你返回的进程号
#size就是进程数

四、 Helloworld程序代码实现及测试展示:
4.1程序源码:
  1. /*hello.c*/
  2. #include <stdio.h>
  3. #include "mpi.h"
  4. int main( int argc, char *argv[] )
  5. {
  6.     int rank;
  7.     int size;
  8.     MPI_Init( 0, 0 );
  9.     MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  10.     MPI_Comm_size(MPI_COMM_WORLD, &size);
  11.     printf( "Hello world from process %d of %d\n", rank, size );
  12.     MPI_Finalize();
  13.     return 0;
  14. }
复制代码

4.2程序编译输出文件
  1. $mpicc –o hello hello.c
复制代码

4.3运行
  1. $mpiexec –n <processes> ./hello
  2. $mpiexec -f csmpd.hosts –n <processes> ./hello
复制代码
【截图显示】

实验三 基本MPI环境的程序测试

一、 实验目标
逐一测试,提供的mpi实验程序文件。
熟悉 MPI 编程,加深对其编程的明白。
二、实验环境
Ubuntu 22.04 (LTS),
VM环境下,网络架构NAT,
计算节点数:4个
三、代码测试与截图
3.1代码泉源程序5.4
详细代码如下:
  1. /*文件名:who.c*/
  2. #include "mpi.h"
  3. #include <stdio.h>
  4. int main(int argc,char **argv)
  5. {
  6.           int myid, numprocs;
  7.           int namelen;
  8.           char processor_name[MPI_MAX_PROCESSOR_NAME];
  9.           MPI_Init(&argc,&argv);
  10.           MPI_Comm_rank(MPI_COMM_WORLD,&myid);//获得本进程ID
  11.           MPI_Comm_size(MPI_COMM_WORLD,&numprocs);//获得总的进程数目
  12.           MPI_Get_processor_name(processor_name,&namelen);//获得本进程的机器名
  13.           printf("Hello World! Process %d of %d on %s\n",myid, numprocs, processor_name);
  14.           MPI_Finalize();
  15. }
复制代码
结果显示(运行截图)

3.2代码泉源程序5.5
详细代码如下:
  1. /*文件名:message.c*/
  2. #include <stdio.h>
  3. #include "mpi.h"
  4. #include <string.h>
  5. int main(int argc, char** argv)
  6. {
  7.      int myid,numprocs,source;
  8.      MPI_Status status;
  9.      char message[100];
  10.      MPI_Init(&argc,&argv);
  11.      MPI_Comm_rank(MPI_COMM_WORLD, &myid);
  12.      MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
  13.      if (myid != 0)
  14.      {
  15.            strcpy(message, "Hello World!");//为发送字符串赋值
  16.            //发送字符串时长度要加1,从而包括串结束标志
  17.            MPI_Send(message,strlen(message)+1, MPI_CHAR, 0,99,MPI_COMM_WORLD);
  18.      }
  19.      else
  20.      {
  21.            //除0进程的其他进程接收来自于0进程的字符串数据
  22.            for (source = 1; source < numprocs; source++)
  23.           {
  24.                  MPI_Recv(message, 100, MPI_CHAR, source, 99,MPI_COMM_WORLD, &status);
  25.                  printf("I am process %d. I recv string '%s' from process %d.\n", myid, message,source);
  26.           }
  27.      }
  28.      MPI_Finalize();
  29. }
复制代码
结果显示(运行截图)

3.3代码泉源程序5.7
详细代码如下:
  1. #define N 100000000
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <time.h>
  5. #include "mpi.h"
  6. int main(int argc, char** argv)
  7. {
  8.   int myid,numprocs;
  9.   int i;
  10.   double local=0.0;
  11.   double inte,tmp=0.0,x;
  12.   MPI_Init(&argc, &argv);
  13.   MPI_Comm_rank(MPI_COMM_WORLD, &myid);
  14.   MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
  15.   srand((int)time(0));//设置随机数种子
  16. /*各节点分别计算一部分积分值*/
  17. /*以下代码在不同节点运行的结果不同*/
  18.   for(i=myid;i<N;i=i+numprocs)
  19.   {
  20.     x=10.0*rand()/(RAND_MAX+1.0);//求函数值
  21.     tmp=x*x/N;
  22.     local=tmp+local;//各节点计算面积和
  23.   }       
  24. //计算总的面积和,得到积分值
  25.   MPI_Reduce(&local,&inte,1,MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD);
  26.   if(myid==0)
  27.   {
  28.     printf("The integal of x*x=%16.15f\n",inte);
  29.   }
  30.   MPI_Finalize();
  31. }
复制代码
结果显示(运行截图)

3.4代码泉源程序5.8
详细代码如下:

  • 初始化MPI****环境。
  • 获取当进步程的ID (myid) 和总进程数 (numprocs)****。
  • 利用随机数天生器天生 N*N* 个在 [1, 10] 区间内的随机数 x*x*****。
  • 计算每个随机数 x*x* 对应的 x2*x*2 并累加到 local 变量中。
  • 调用自定义的归约函数 Myreduce**,将所有进程的 local** 值汇总到根节点(进程0**)。**
  • 如果当进步程是根节点,打印出积分结果。
  • 结束MPI****环境。
  1. /*文件名 myreduce.c*/
  2. #define N 100000000
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <time.h>
  6. #include "mpi.h"
  7. void Myreduce(double sendbuf, double *recvbuf, int root); // 修改函数原型
  8. int main(int argc, char** argv) {
  9.     int myid, numprocs;
  10.     double local = 0.0;
  11.     double inte;
  12.     double x;
  13.     MPI_Init(&argc, &argv);
  14.     MPI_Comm_rank(MPI_COMM_WORLD, &myid);
  15.     MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
  16.     // 采用归约对y=x*x在[1,10]区间求积分
  17.     srand((unsigned)time(NULL) + myid); // 使用myid作为种子的一部分
  18.     int localN = N / numprocs; // 每个进程处理的随机数数量
  19.     for (int i = 0; i < localN; i++) {
  20.         x = 10.0 * rand() / (RAND_MAX / 10.0 + 1.0); // 生成[1,10]区间的随机数
  21.         local += x * x / N; // 累加到local变量中
  22.     }
  23.     Myreduce(local, &inte, 0); // 调用自定义的规约函数,传递local的值
  24.     if (myid == 0) {
  25.         printf("id:%d 总进程:%d The integral of x*x = %16.15f\n",myid,numprocs,inte);
  26.     }
  27.     MPI_Finalize();
  28.     return 0;
  29. }
  30. // 自定义的归约函数
  31. void Myreduce(double sendbuf, double *recvbuf, int root) {
  32.     MPI_Status status;
  33.     int myid, numprocs;
  34.     MPI_Comm_rank(MPI_COMM_WORLD, &myid);
  35.     MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
  36.     // 非root节点向root节点发送数据
  37.     if (myid != root) {
  38.         MPI_Send(&sendbuf, 1, MPI_DOUBLE, root, 99, MPI_COMM_WORLD);
  39.     } else {
  40.         *recvbuf = 0.0; // 初始化接收缓冲区
  41.         // root节点接收数据并对数据求和,完成规约操作
  42.         for (int i = 0; i < numprocs; i++) {
  43.             if (i != root) {
  44.                 double tmp;
  45.                 MPI_Recv(&tmp, 1, MPI_DOUBLE, i, 99, MPI_COMM_WORLD, &status);
  46.                 *recvbuf += tmp; // 累加求和
  47.             }
  48.         }
  49.     }
  50. }
复制代码
结果显示(运行截图)

实验四 卡布列克常数的MPI测试
一、 实验题目
用 MPI 方式遍历数据,证实卡布列克常数6174猜想。
二、实验目标
熟悉 MPI 编程,加深对其编程的明白。
三、实验环境
Ubuntu 22.04 (LTS),
VM环境下,网络架构NAT,
计算节点数:4个
四、原理介绍:
6174猜想:一个恣意的四位正整数(全雷同的除外,如1111)。将数字重新组合成一个最大的数和最小的数相减,重复这个过程,最多七步,必得6174。
例如:
输入:2000
输出:
第1步:2000-0002=1998
第2步:9981-1899=8082
第3步:8820-0288=8532
第4步:8532-2358=6174
分步解题:

  • 遍历所有的四位数,判断。
  • 分解数字的千位,百位,十位,个位,放置在4个变量中,排序,将最大的放在最前面,最小的放在末了面。
  • 利用4个变量的值,构建四位数,最大值及最小值,并计算差值
  • 如差值不是6174,则重复步调2.如果差值为6174,则程序打印输出最闭幕果,程序结束。
用各自节点分别计算的数据范围,分担计算任务。
例如,如果有4个节点呆板,就将10009999****分成四个小范围,分给****4****个节点计算验证。如果有****3****个节点呆板,就将****10009999分成三个小范围,分给3个节点计算验证。
五、 程序代码实现及测试:
  1. #include <mpi.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <unistd.h>
  5. //找出最大值和最小值
  6. void sort_digits(int num, int *sorted, int *largest, int *smallest) {
  7.     for (int i = 0; i < 4; ++i) {
  8.         sorted[i] = num % 10;
  9.         num /= 10;
  10.     }
  11.     // Sort the digits
  12.     for (int i = 0; i < 3; ++i) {
  13.         for (int j = i + 1; j < 4; ++j) {
  14.             if (sorted[i] > sorted[j]) {
  15.                 int temp = sorted[i];
  16.                 sorted[i] = sorted[j];
  17.                 sorted[j] = temp;
  18.             }
  19.         }
  20.     }
  21.     //将排序好的数组数编排成最大的数和最小的数
  22.     *largest = sorted[0] * 1000 + sorted[1] * 100 + sorted[2] * 10 + sorted[3];
  23.     *smallest = sorted[3] * 1000 + sorted[2] * 100 + sorted[1] * 10 + sorted[0];
  24. }
  25. //检查是否能在7步以内得到6174,输出运行节点和步骤
  26. void check_convergence(int num, int myid, char *hostname) {
  27.     int steps = 0;
  28.     int sorted[4], largest, smallest;
  29.     printf("进程 %d: 数字 %d on %s\n",myid, num,hostname);
  30.     while (num != 6174 && steps < 7) {
  31.         sort_digits(num, sorted, &largest, &smallest);
  32.         num = largest - smallest;
  33.         steps++;
  34.         printf("进程 %d: 第%d步: %d - %d = %d on %s\n", myid, steps, largest, smallest, num, hostname);
  35.     }
  36.     if (num == 6174) {
  37.         printf("进程 %d: Convergence to 6174 after %d 步: %d - %d = 6174 on %s\n",myid, steps, largest, smallest,hostname);
  38.     }
  39. }
  40. int main(int argc, char **argv) {
  41.     int myid, numprocs;
  42.     char hostname[256];
  43.     MPI_Init(&argc, &argv);
  44.     MPI_Comm_rank(MPI_COMM_WORLD, &myid);
  45.     MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
  46.     gethostname(hostname, sizeof(hostname));
  47.     int start = 1000 + myid * (9999 / numprocs);
  48.     int end = 1000 + (myid + 1) * (9999 / numprocs);
  49.     if (myid == numprocs - 1) {
  50.         end = 9999;
  51.     }
  52.     for (int i = start; i <= end; ++i) {
  53.         if (i % 1111 != 0) { //不包含四位数都相同的数
  54.             check_convergence(i, myid, hostname);
  55.         }
  56.     }
  57.     MPI_Finalize();
  58.     return 0;
  59. }
复制代码


实验五 基于蒙特卡洛算法求π值的MPI程序设计

一、 实验题目
用 MPI 技术计算π的值,运行代码参考程序5.6。
二、实验目标
熟悉 MPI 编程,加深对其编程的明白。
三、实验环境
Ubuntu 22.04 (LTS),
VM环境下,网络架构NAT,
计算节点数:4个
四、程序代码实现及测试
  1. /*文件名:mtpi.c*/
  2. #include "mpi.h"
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <time.h> // 包含 time.h 头文件
  6. int main(int argc, char **argv) {
  7.     int myid, numprocs;
  8.     int namelen;
  9.     long count = 1000000;
  10.     char processor_name[MPI_MAX_PROCESSOR_NAME];
  11.     MPI_Status status;
  12.     MPI_Init(&argc, &argv); // 初始化 MPI 环境
  13.     MPI_Comm_rank(MPI_COMM_WORLD, &myid); // 得到当前进程的进程号
  14.     MPI_Comm_size(MPI_COMM_WORLD, &numprocs); // 得到通信域中的总进程数
  15.     MPI_Get_processor_name(processor_name, &namelen); // 得到节点主机名称
  16.     srand((int)time(0)); // 设置随机种子
  17.     double y;
  18.     double x;
  19.     long m = 0, m1 = 0, i = 0;
  20.     double pi = 0.0, n = 0.0;
  21.     for (i = 0; i < count; i++) {
  22.         x = (double)rand() / (double)RAND_MAX; // 得到0~1之间的随机数,x坐标
  23.         y = (double)rand() / (double)RAND_MAX; // 得到0~1之间的随机数,y坐标
  24.         if ((x - 0.5) * (x - 0.5) + (y - 0.5) * (y - 0.5) < 0.25) // 判断产生的随机点坐标是否在圆内
  25.             m++;
  26.     }
  27.     n = 4.0 * m / 1000000;
  28.     printf("Process %d of %d on %s pi= %f\n", myid, numprocs, processor_name, n);
  29.     if (myid != 0) { // 判断是否是主节点
  30.         MPI_Send(&m, 1, MPI_LONG, 0, 1, MPI_COMM_WORLD); // 子节点向主节点传送结果
  31.     } else {
  32.         long p = m; // 主进程也参与计算,所以初始化 p 为 m
  33.         // 分别接收来自于不同子节点的数据
  34.         for (int source = 1; source < numprocs; source++) {
  35.             MPI_Recv(&m1, 1, MPI_LONG, source, 1, MPI_COMM_WORLD, &status); // 主节点接收数据
  36.             p += m1;
  37.         }
  38.         pi = 4.0 * p / (count * numprocs); // 汇总计算 pi 值
  39.         printf("pi= %f\n", pi);
  40.     }
  41.     MPI_Finalize(); // 结束 MPI 环境
  42.     return 0;
  43. }
复制代码
五、运行结果效果图

实验六 并行计算的综合设计

一、 实验题目
用 MPI 技术去验证角谷猜想,要求验证数据的范围尽可能的大。
二、实验目标
熟悉 MPI 编程,加深对其编程的明白。
三、实验环境
Ubuntu 22.04 (LTS),
VM环境下,网络架构NAT,
计算节点数:4个
四、程序代码实现及测试
  1. #include <stdio.h>
  2. #include <mpi.h>
  3. // 函数用于验证角谷猜想,并返回到达1所需的步骤数
  4. int collatzSteps(int number) {
  5.     int steps = 0;
  6.     while (number != 1) {
  7.         if (number % 2 == 0) {
  8.             number /= 2;
  9.         } else {
  10.             number = number * 3 + 1;
  11.         }
  12.         steps++;
  13.     }
  14.     return steps;
  15. }
  16. int main(int argc, char** argv) {
  17.     int rank, size;
  18.     int start, end, step;
  19.     int namelen;
  20.     char processor_name[MPI_MAX_PROCESSOR_NAME];
  21.     MPI_Init(&argc, &argv); // 初始化MPI环境
  22.     MPI_Comm_size(MPI_COMM_WORLD, &size); // 获取进程总数
  23.     MPI_Comm_rank(MPI_COMM_WORLD, &rank); // 获取当前进程标识
  24.     MPI_Get_processor_name(processor_name, &namelen); // 获取节点名称
  25.     // 确定每个进程的起始和结束值
  26.     int total_numbers = 100; // 总共需要计算的数
  27.     start = rank * (total_numbers / size) + 1;
  28.     if (rank == size - 1) {
  29.         // 最后一个进程需要处理剩余的数
  30.         end = total_numbers;
  31.     } else {
  32.         end = start + (total_numbers / size) - 1;
  33.     }
  34.     // 输出当前进程的编号和所在节点名称
  35.     printf("Process %d is on %s\n", rank, processor_name);
  36.     // 验证角谷猜想并输出结果
  37.     for (int i = start; i <= end; i++) {
  38.         step = collatzSteps(i);
  39.         printf("%d 执行了 %d 步, 等于1 on %s\n",i, step,processor_name);
  40.     }
  41.     MPI_Finalize(); // 结束MPI环境
  42.     return 0;
  43. }
复制代码
五、运行结果效果图

实验七 并行计算的综合设计

一、 实验题目
用 MPI 技术去验证亲和数组合的个数。
要求验证数据,程序运行时间大于20分钟以上。
二、实验目标
熟悉 MPI 编程,加深对其编程的明白。
三、实验环境
Ubuntu 22.04 (LTS),
VM环境下,网络架构NAT,
计算节点数:4个
四、程序代码实现及测试
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <mpi.h>
  4. // 函数用于计算一个数的约数之和
  5. int sum_of_divisors(int n) {
  6.     int sum = 0;
  7.     for (int i = 1; i <= n / 2; i++) {
  8.         if (n % i == 0) {
  9.             sum += i;
  10.         }
  11.     }
  12.     return sum;
  13. }
  14. // 主程序
  15. int main(int argc, char** argv) {
  16.     int rank, size;
  17.     char processor_name[MPI_MAX_PROCESSOR_NAME];
  18.     int namelen;
  19.     MPI_Init(&argc, &argv);
  20.     MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  21.     MPI_Comm_size(MPI_COMM_WORLD, &size);
  22.     MPI_Get_processor_name(processor_name, &namelen); // 获取进程所在的节点名称
  23.     // 设置验证的上限值
  24.     int limit = 10000;
  25.     // 计算每个进程的起始和结束值
  26.     int start = rank * (limit / size);
  27.     int end = (rank + 1) * (limit / size) - 1;
  28.     if (rank == size - 1) {
  29.         end = limit;
  30.     }
  31.     // 寻找亲和数并输出结果
  32.     for (int a = start; a <= end; a++) {
  33.         int B = sum_of_divisors(a);
  34.         int A = sum_of_divisors(B);
  35.         if (A == a) {
  36.             printf(" 进程 %d: 亲和数: %d and %d on %s\n", rank, a, B,processor_name);
  37.         }
  38.     }
  39.     MPI_Finalize();
  40.     return 0;
  41. }
复制代码
五、运行结果效果图
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <mpi.h>
  4. // 函数用于计算一个数的约数之和
  5. int sum_of_divisors(int n) {
  6.     int sum = 0;
  7.     for (int i = 1; i <= n / 2; i++) {
  8.         if (n % i == 0) {
  9.             sum += i;
  10.         }
  11.     }
  12.     return sum;
  13. }
  14. // 主程序
  15. int main(int argc, char** argv) {
  16.     int rank, size;
  17.     char processor_name[MPI_MAX_PROCESSOR_NAME];
  18.     int namelen;
  19.     MPI_Init(&argc, &argv);
  20.     MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  21.     MPI_Comm_size(MPI_COMM_WORLD, &size);
  22.     MPI_Get_processor_name(processor_name, &namelen); // 获取进程所在的节点名称
  23.     // 设置验证的上限值
  24.     int limit = 10000;
  25.     // 计算每个进程的起始和结束值
  26.     int start = rank * (limit / size);
  27.     int end = (rank + 1) * (limit / size) - 1;
  28.     if (rank == size - 1) {
  29.         end = limit;
  30.     }
  31.     // 寻找亲和数并输出结果
  32.     for (int a = start; a <= end; a++) {
  33.         int B = sum_of_divisors(a);
  34.         int A = sum_of_divisors(B);
  35.         if (A == a) {
  36.             printf(" 进程 %d: 亲和数: %d and %d on %s\n", rank, a, B,processor_name);
  37.         }
  38.     }
  39.     MPI_Finalize();
  40.     return 0;
  41. }
复制代码
五、运行结果效果图

回复

使用道具 举报

返回列表 发新帖
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录

QQ|手机版|qidao123.com IT社区;IT企服评测▪应用市场 ( 浙ICP备20004199|浙ICP备20004199号 )|网站地图

GMT+8, 2026-10-23 01:30 , Processed in 0.074811 second(s), 8 queries , Redis On.

Powered by Discuz! X3.5 Licensed

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表