pbs_cray_hyperthread.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. # coding: utf-8
  2. # Copyright (C) 1994-2018 Altair Engineering, Inc.
  3. # For more information, contact Altair at www.altair.com.
  4. #
  5. # This file is part of the PBS Professional ("PBS Pro") software.
  6. #
  7. # Open Source License Information:
  8. #
  9. # PBS Pro is free software. You can redistribute it and/or modify it under the
  10. # terms of the GNU Affero General Public License as published by the Free
  11. # Software Foundation, either version 3 of the License, or (at your option) any
  12. # later version.
  13. #
  14. # PBS Pro is distributed in the hope that it will be useful, but WITHOUT ANY
  15. # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  16. # FOR A PARTICULAR PURPOSE.
  17. # See the GNU Affero General Public License for more details.
  18. #
  19. # You should have received a copy of the GNU Affero General Public License
  20. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  21. #
  22. # Commercial License Information:
  23. #
  24. # For a copy of the commercial license terms and conditions,
  25. # go to: (http://www.pbspro.com/UserArea/agreement.html)
  26. # or contact the Altair Legal Department.
  27. #
  28. # Altair’s dual-license business model allows companies, individuals, and
  29. # organizations to create proprietary derivative works of PBS Pro and
  30. # distribute them - whether embedded or bundled with other software -
  31. # under a commercial license agreement.
  32. #
  33. # Use of Altair’s trademarks, including but not limited to "PBS™",
  34. # "PBS Professional®", and "PBS Pro™" and Altair’s logos is subject to Altair's
  35. # trademark licensing policies.
  36. from tests.functional import *
  37. from ptl.utils.pbs_crayutils import CrayUtils
  38. import os
  39. @tags('cray')
  40. class TestCrayHyperthread(TestFunctional):
  41. """
  42. The test will submit a job script that calls aprun with the
  43. option that will allow callers to use the hyperthreads
  44. on a hyperthreaded compute node.
  45. """
  46. def setUp(self):
  47. if not self.du.get_platform().startswith('cray'):
  48. self.skipTest("Test suite only meant to run on a Cray")
  49. TestFunctional.setUp(self)
  50. def test_hyperthread(self):
  51. """
  52. Check for a compute node that has hyperthreads, if there is one
  53. submit a job to that node requesting the hyperthreads. Check
  54. there are no errors in the job error output.
  55. If there is no node with hyperthreads, skip the test.
  56. """
  57. # Get the compute nodes from PBS and see if they are threaded
  58. cu = CrayUtils()
  59. all_nodes = self.server.status(NODE)
  60. threaded = 0
  61. for n in all_nodes:
  62. if n['resources_available.vntype'] == 'cray_compute':
  63. numthreads = cu.get_numthreads(
  64. n['resources_available.PBScraynid'])
  65. if numthreads > 1:
  66. self.logger.info("Node %s has %s hyperthreads" %
  67. (n['resources_available.vnode'],
  68. numthreads))
  69. ncpus = n['resources_available.ncpus']
  70. vnode = n['resources_available.vnode']
  71. threaded = 1
  72. break
  73. if not threaded:
  74. self.skipTest("Test suite needs nodes with hyperthreads")
  75. # There is a node with hyperthreads, get the number of cpus
  76. aprun_args = '-j %d -n %d' % (int(numthreads), int(ncpus))
  77. self.server.manager(MGR_CMD_SET, SERVER,
  78. {'job_history_enable': 'True'})
  79. j1 = Job(TEST_USER, {ATTR_l + '.select': '1:ncpus=%d:vnode=%s' %
  80. (int(ncpus), vnode),
  81. ATTR_N: 'hyperthread'})
  82. scr = []
  83. scr += ['hostname\n']
  84. scr += ['/bin/sleep 5\n']
  85. scr += ['aprun -b %s /bin/hostname\n' % aprun_args]
  86. sub_dir = self.du.mkdtemp(uid=TEST_USER.uid)
  87. j1.create_script(scr)
  88. jid1 = self.server.submit(j1, submit_dir=sub_dir)
  89. self.server.expect(JOB, {ATTR_state: 'R'}, id=jid1)
  90. # Verify the contents of the output/error files
  91. self.server.expect(JOB, {'job_state': 'F'}, id=jid1, extend='x')
  92. error_file = os.path.join(
  93. sub_dir, 'hyperthread.e' + jid1.split('.')[0])
  94. self.assertEqual(os.stat(error_file).st_size, 0,
  95. msg="Job error file should be empty")