We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
hardware_info fails (again) on M1 MacBook Pro running Big Sur 11.4
**Describe the bug**
qutip fails to import with the following error:
```
Python 3.9.6 (default, Jun 28 2021, 19:24:41) 
[Clang 12.0.5 (clang-1205.0.22.9)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import qutip
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/homebrew/lib/python3.9/site-packages/qutip/__init__.py", line 115, in <module>
    info = qutip.hardware_info.hardware_info()
  File "/opt/homebrew/lib/python3.9/site-packages/qutip/hardware_info.py", line 133, in hardware_info
    out = _mac_hardware_info()
  File "/opt/homebrew/lib/python3.9/site-packages/qutip/hardware_info.py", line 50, in _mac_hardware_info
    results.update({'cpu_freq': int(float(os.popen('sysctl hw.cpufrequency')
IndexError: list index out of range
```

This appears to be caused by Apple having removed hw.cpufrequency from the list of sysctl's (see below)

**To Reproduce**
Installed qutip using homebrew/pip3 (after using the workaround of specifying OPENBLAS properly before building scipy etc... so that part is all sorted). Then python3 and import qutip.

```python
from qutip import identity
print(identity(2))
```
The terminal output (aftrer I hacked up a workaround for this issue):
```
Quantum object: dims = [[2], [2]], shape = (2, 2), type = oper, isherm = True
Qobj data =
[[1. 0.]
 [0. 1.]]
```

**Expected behavior**
qutip successfully initializes :-)

**Your Environment**
Please use `qutip.about()` to get the information about your environment and paste it here.
```
>>> qutip.about()

QuTiP: Quantum Toolbox in Python
================================
Copyright (c) QuTiP team 2011 and later.
Current admin team: Alexander Pitchford, Nathan Shammah, Shahnawaz Ahmed, Neill Lambert, Eric Giguère, Boxi Li, Jake Lishman and Simon Cross.
Board members: Daniel Burgarth, Robert Johansson, Anton F. Kockum, Franco Nori and Will Zeng.
Original developers: R. J. Johansson & P. D. Nation.
Previous lead developers: Chris Granade & A. Grimsmo.
Currently developed through wide collaboration. See https://github.com/qutip for details.

QuTiP Version:      4.6.2
Numpy Version:      1.21.0
Scipy Version:      1.7.0
Cython Version:     0.29.23
Matplotlib Version: 3.4.2
Python Version:     3.9.6
Number of CPUs:     8
BLAS Info:          OPENBLAS
OPENMP Installed:   False
INTEL MKL Ext:      False
Platform Info:      Darwin (arm64)
Installation path:  /opt/homebrew/lib/python3.9/site-packages/qutip
================================================================================
Please cite QuTiP in your publication.
================================================================================
```

**Additional context**
 No sysctl hw.cpufrequency at all on this machine, so it blows up (some error handling in that function would be good :-)

```$ sysctl hw
hw.ncpu: 8
hw.byteorder: 1234
hw.memsize: 17179869184
hw.activecpu: 8
hw.optional.amx_version: 2
hw.optional.arm64: 1
hw.optional.armv8_1_atomics: 1
hw.optional.armv8_2_fhm: 1
hw.optional.armv8_2_sha3: 1
hw.optional.armv8_2_sha512: 1
hw.optional.armv8_crc32: 1
hw.optional.breakpoint: 6
hw.optional.floatingpoint: 1
hw.optional.neon: 1
hw.optional.neon_fp16: 1
hw.optional.neon_hpfp: 1
hw.optional.ucnormal_mem: 1
hw.optional.watchpoint: 4
hw.cacheconfig: 8 1 1 0 0 0 0 0 0 0
hw.cachelinesize: 128
hw.cachesize: 3616980992 65536 4194304 0 0 0 0 0 0 0
hw.cpu64bit_capable: 1
hw.cpufamily: 458787763
hw.cpusubfamily: 2
hw.cpusubtype: 2
hw.cputype: 16777228
hw.ephemeral_storage: 0
hw.l1dcachesize: 65536
hw.l1icachesize: 131072
hw.l2cachesize: 4194304
hw.logicalcpu: 8
hw.logicalcpu_max: 8
hw.osenvironment: 
hw.packages: 1
hw.pagesize: 16384
hw.pagesize32: 16384
hw.physicalcpu: 8
hw.physicalcpu_max: 8
hw.serialdebugmode: 0
hw.tbfrequency: 24000000
hw.use_kernelmanagerd: 1
hw.use_recovery_securityd: 0
hw.targettype: J293
```



--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `qutip/hardware_info.py`
Content:
```
1 __all__ = ['hardware_info']
2 
3 import multiprocessing
4 import os
5 import sys
6 
7 import numpy as np
8 
9 
10 def _mac_hardware_info():
11     info = dict()
12     results = dict()
13     for l in [l.split(':') for l in os.popen('sysctl hw').readlines()[1:]]:
14         info[l[0].strip(' "').replace(' ', '_').lower().strip('hw.')] = \
15             l[1].strip('.\n ')
16     results.update({'cpus': int(info['physicalcpu'])})
17     results.update({'cpu_freq': int(float(os.popen('sysctl hw.cpufrequency')
18                                           .readlines()[0].split(':')[
19                                               1]) / 1000000)})
20     results.update({'memsize': int(int(info['memsize']) / (1024 ** 2))})
21     # add OS information
22     results.update({'os': 'Mac OSX'})
23     return results
24 
25 
26 def _linux_hardware_info():
27     results = {}
28     # get cpu number
29     sockets = 0
30     cores_per_socket = 0
31     frequency = 0.0
32     with open("/proc/cpuinfo") as f:
33         for l in [l.split(':') for l in f.readlines()]:
34             if (l[0].strip() == "physical id"):
35                 sockets = np.maximum(sockets,int(l[1].strip())+1)
36             if (l[0].strip() == "cpu cores"):
37                 cores_per_socket = int(l[1].strip())
38             if (l[0].strip() == "cpu MHz"):
39                 frequency = float(l[1].strip()) / 1000.
40     results.update({'cpus': sockets * cores_per_socket})
41     # get cpu frequency directly (bypasses freq scaling)
42     try:
43         with open(
44                 "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq") as f:
45             line = f.readlines()[0]
46         frequency = float(line.strip('\n')) / 1000000.
47     except:
48         pass
49     results.update({'cpu_freq': frequency})
50 
51     # get total amount of memory
52     mem_info = dict()
53     with open("/proc/meminfo") as f:
54         for l in [l.split(':') for l in f.readlines()]:
55             mem_info[l[0]] = l[1].strip('.\n ').strip('kB')
56     results.update({'memsize': int(mem_info['MemTotal']) / 1024})
57     # add OS information
58     results.update({'os': 'Linux'})
59     return results
60 
61 
62 def _freebsd_hardware_info():
63     results = {}
64     results.update({'cpus': int(os.popen('sysctl -n hw.ncpu').readlines()[0])})
65     results.update(
66         {'cpu_freq': int(os.popen('sysctl -n dev.cpu.0.freq').readlines()[0])})
67     results.update({'memsize': int(
68         os.popen('sysctl -n hw.realmem').readlines()[0]) / 1024})
69     results.update({'os': 'FreeBSD'})
70     return results
71 
72 
73 def _win_hardware_info():
74     try:
75         from comtypes.client import CoGetObject
76         winmgmts_root = CoGetObject(r"winmgmts:root\cimv2")
77         cpus = winmgmts_root.ExecQuery("Select * from Win32_Processor")
78         ncpus = 0
79         for cpu in cpus:
80             ncpus += int(cpu.Properties_['NumberOfCores'].Value)
81     except:
82         ncpus = int(multiprocessing.cpu_count())
83     return {'os': 'Windows', 'cpus': ncpus}
84 
85 
86 def hardware_info():
87     """
88     Returns basic hardware information about the computer.
89 
90     Gives actual number of CPU's in the machine, even when hyperthreading is
91     turned on.
92 
93     Returns
94     -------
95     info : dict
96         Dictionary containing cpu and memory information.
97 
98     """
99     if sys.platform == 'darwin':
100         out = _mac_hardware_info()
101     elif sys.platform == 'win32':
102         out = _win_hardware_info()
103     elif sys.platform in ['linux', 'linux2']:
104         out = _linux_hardware_info()
105     elif sys.platform.startswith('freebsd'):
106         out = _freebsd_hardware_info()
107     else:
108         out = {}
109     return out
110 
111 
112 if __name__ == '__main__':
113     print(hardware_info())
114
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/qutip/hardware_info.py b/qutip/hardware_info.py
--- a/qutip/hardware_info.py
+++ b/qutip/hardware_info.py
@@ -8,15 +8,27 @@
 
 
 def _mac_hardware_info():
-    info = dict()
-    results = dict()
-    for l in [l.split(':') for l in os.popen('sysctl hw').readlines()[1:]]:
-        info[l[0].strip(' "').replace(' ', '_').lower().strip('hw.')] = \
-            l[1].strip('.\n ')
+    info = {}
+    results = {}
+    with os.popen('sysctl hw') as f:
+        lines = f.readlines()
+    for line in lines[1:]:
+        key, _, value = line.partition(':')
+        key = key.strip(' "').replace(' ', '_').lower().strip('hw.')
+        value = value.strip('.\n ')
+        info[key] = value
     results.update({'cpus': int(info['physicalcpu'])})
-    results.update({'cpu_freq': int(float(os.popen('sysctl hw.cpufrequency')
-                                          .readlines()[0].split(':')[
-                                              1]) / 1000000)})
+    # Mac OS currently doesn't not provide hw.cpufrequency on the M1
+    with os.popen('sysctl hw.cpufrequency') as f:
+        cpu_freq_lines = f.readlines()
+    if cpu_freq_lines:
+        # Yay, hw.cpufrequency present
+        results.update({
+            'cpu_freq': float(cpu_freq_lines[0].split(':')[1]) / 1000000,
+        })
+    else:
+        # No hw.cpufrequency, assume Apple M1 CPU (all are 3.2 GHz currently)
+        results['cpu_freq'] = 3.2
     results.update({'memsize': int(int(info['memsize']) / (1024 ** 2))})
     # add OS information
     results.update({'os': 'Mac OSX'})
@@ -32,19 +44,19 @@
     with open("/proc/cpuinfo") as f:
         for l in [l.split(':') for l in f.readlines()]:
             if (l[0].strip() == "physical id"):
-                sockets = np.maximum(sockets,int(l[1].strip())+1)
+                sockets = np.maximum(sockets, int(l[1].strip()) + 1)
             if (l[0].strip() == "cpu cores"):
                 cores_per_socket = int(l[1].strip())
             if (l[0].strip() == "cpu MHz"):
                 frequency = float(l[1].strip()) / 1000.
-    results.update({'cpus': sockets * cores_per_socket})
+    results.update({'cpus': int(sockets * cores_per_socket)})
     # get cpu frequency directly (bypasses freq scaling)
     try:
         with open(
                 "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq") as f:
             line = f.readlines()[0]
         frequency = float(line.strip('\n')) / 1000000.
-    except:
+    except Exception:
         pass
     results.update({'cpu_freq': frequency})
 
@@ -78,7 +90,7 @@
         ncpus = 0
         for cpu in cpus:
             ncpus += int(cpu.Properties_['NumberOfCores'].Value)
-    except:
+    except Exception:
         ncpus = int(multiprocessing.cpu_count())
     return {'os': 'Windows', 'cpus': ncpus}

{"golden_diff": "diff --git a/qutip/hardware_info.py b/qutip/hardware_info.py\n--- a/qutip/hardware_info.py\n+++ b/qutip/hardware_info.py\n@@ -8,15 +8,27 @@\n \n \n def _mac_hardware_info():\n-    info = dict()\n-    results = dict()\n-    for l in [l.split(':') for l in os.popen('sysctl hw').readlines()[1:]]:\n-        info[l[0].strip(' \"').replace(' ', '_').lower().strip('hw.')] = \\\n-            l[1].strip('.\\n ')\n+    info = {}\n+    results = {}\n+    with os.popen('sysctl hw') as f:\n+        lines = f.readlines()\n+    for line in lines[1:]:\n+        key, _, value = line.partition(':')\n+        key = key.strip(' \"').replace(' ', '_').lower().strip('hw.')\n+        value = value.strip('.\\n ')\n+        info[key] = value\n     results.update({'cpus': int(info['physicalcpu'])})\n-    results.update({'cpu_freq': int(float(os.popen('sysctl hw.cpufrequency')\n-                                          .readlines()[0].split(':')[\n-                                              1]) / 1000000)})\n+    # Mac OS currently doesn't not provide hw.cpufrequency on the M1\n+    with os.popen('sysctl hw.cpufrequency') as f:\n+        cpu_freq_lines = f.readlines()\n+    if cpu_freq_lines:\n+        # Yay, hw.cpufrequency present\n+        results.update({\n+            'cpu_freq': float(cpu_freq_lines[0].split(':')[1]) / 1000000,\n+        })\n+    else:\n+        # No hw.cpufrequency, assume Apple M1 CPU (all are 3.2 GHz currently)\n+        results['cpu_freq'] = 3.2\n     results.update({'memsize': int(int(info['memsize']) / (1024 ** 2))})\n     # add OS information\n     results.update({'os': 'Mac OSX'})\n@@ -32,19 +44,19 @@\n     with open(\"/proc/cpuinfo\") as f:\n         for l in [l.split(':') for l in f.readlines()]:\n             if (l[0].strip() == \"physical id\"):\n-                sockets = np.maximum(sockets,int(l[1].strip())+1)\n+                sockets = np.maximum(sockets, int(l[1].strip()) + 1)\n             if (l[0].strip() == \"cpu cores\"):\n                 cores_per_socket = int(l[1].strip())\n             if (l[0].strip() == \"cpu MHz\"):\n                 frequency = float(l[1].strip()) / 1000.\n-    results.update({'cpus': sockets * cores_per_socket})\n+    results.update({'cpus': int(sockets * cores_per_socket)})\n     # get cpu frequency directly (bypasses freq scaling)\n     try:\n         with open(\n                 \"/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq\") as f:\n             line = f.readlines()[0]\n         frequency = float(line.strip('\\n')) / 1000000.\n-    except:\n+    except Exception:\n         pass\n     results.update({'cpu_freq': frequency})\n \n@@ -78,7 +90,7 @@\n         ncpus = 0\n         for cpu in cpus:\n             ncpus += int(cpu.Properties_['NumberOfCores'].Value)\n-    except:\n+    except Exception:\n         ncpus = int(multiprocessing.cpu_count())\n     return {'os': 'Windows', 'cpus': ncpus}\n", "issue": "hardware_info fails (again) on M1 MacBook Pro running Big Sur 11.4\n**Describe the bug**\r\nqutip fails to import with the following error:\r\n```\r\nPython 3.9.6 (default, Jun 28 2021, 19:24:41) \r\n[Clang 12.0.5 (clang-1205.0.22.9)] on darwin\r\nType \"help\", \"copyright\", \"credits\" or \"license\" for more information.\r\n>>> import qutip\r\nTraceback (most recent call last):\r\n  File \"<stdin>\", line 1, in <module>\r\n  File \"/opt/homebrew/lib/python3.9/site-packages/qutip/__init__.py\", line 115, in <module>\r\n    info = qutip.hardware_info.hardware_info()\r\n  File \"/opt/homebrew/lib/python3.9/site-packages/qutip/hardware_info.py\", line 133, in hardware_info\r\n    out = _mac_hardware_info()\r\n  File \"/opt/homebrew/lib/python3.9/site-packages/qutip/hardware_info.py\", line 50, in _mac_hardware_info\r\n    results.update({'cpu_freq': int(float(os.popen('sysctl hw.cpufrequency')\r\nIndexError: list index out of range\r\n```\r\n\r\nThis appears to be caused by Apple having removed hw.cpufrequency from the list of sysctl's (see below)\r\n\r\n**To Reproduce**\r\nInstalled qutip using homebrew/pip3 (after using the workaround of specifying OPENBLAS properly before building scipy etc... so that part is all sorted). Then python3 and import qutip.\r\n\r\n```python\r\nfrom qutip import identity\r\nprint(identity(2))\r\n```\r\nThe terminal output (aftrer I hacked up a workaround for this issue):\r\n```\r\nQuantum object: dims = [[2], [2]], shape = (2, 2), type = oper, isherm = True\r\nQobj data =\r\n[[1. 0.]\r\n [0. 1.]]\r\n```\r\n\r\n**Expected behavior**\r\nqutip successfully initializes :-)\r\n\r\n**Your Environment**\r\nPlease use `qutip.about()` to get the information about your environment and paste it here.\r\n```\r\n>>> qutip.about()\r\n\r\nQuTiP: Quantum Toolbox in Python\r\n================================\r\nCopyright (c) QuTiP team 2011 and later.\r\nCurrent admin team: Alexander Pitchford, Nathan Shammah, Shahnawaz Ahmed, Neill Lambert, Eric Gigu\u00e8re, Boxi Li, Jake Lishman and Simon Cross.\r\nBoard members: Daniel Burgarth, Robert Johansson, Anton F. Kockum, Franco Nori and Will Zeng.\r\nOriginal developers: R. J. Johansson & P. D. Nation.\r\nPrevious lead developers: Chris Granade & A. Grimsmo.\r\nCurrently developed through wide collaboration. See https://github.com/qutip for details.\r\n\r\nQuTiP Version:      4.6.2\r\nNumpy Version:      1.21.0\r\nScipy Version:      1.7.0\r\nCython Version:     0.29.23\r\nMatplotlib Version: 3.4.2\r\nPython Version:     3.9.6\r\nNumber of CPUs:     8\r\nBLAS Info:          OPENBLAS\r\nOPENMP Installed:   False\r\nINTEL MKL Ext:      False\r\nPlatform Info:      Darwin (arm64)\r\nInstallation path:  /opt/homebrew/lib/python3.9/site-packages/qutip\r\n================================================================================\r\nPlease cite QuTiP in your publication.\r\n================================================================================\r\n```\r\n\r\n**Additional context**\r\n No sysctl hw.cpufrequency at all on this machine, so it blows up (some error handling in that function would be good :-)\r\n\r\n```$ sysctl hw\r\nhw.ncpu: 8\r\nhw.byteorder: 1234\r\nhw.memsize: 17179869184\r\nhw.activecpu: 8\r\nhw.optional.amx_version: 2\r\nhw.optional.arm64: 1\r\nhw.optional.armv8_1_atomics: 1\r\nhw.optional.armv8_2_fhm: 1\r\nhw.optional.armv8_2_sha3: 1\r\nhw.optional.armv8_2_sha512: 1\r\nhw.optional.armv8_crc32: 1\r\nhw.optional.breakpoint: 6\r\nhw.optional.floatingpoint: 1\r\nhw.optional.neon: 1\r\nhw.optional.neon_fp16: 1\r\nhw.optional.neon_hpfp: 1\r\nhw.optional.ucnormal_mem: 1\r\nhw.optional.watchpoint: 4\r\nhw.cacheconfig: 8 1 1 0 0 0 0 0 0 0\r\nhw.cachelinesize: 128\r\nhw.cachesize: 3616980992 65536 4194304 0 0 0 0 0 0 0\r\nhw.cpu64bit_capable: 1\r\nhw.cpufamily: 458787763\r\nhw.cpusubfamily: 2\r\nhw.cpusubtype: 2\r\nhw.cputype: 16777228\r\nhw.ephemeral_storage: 0\r\nhw.l1dcachesize: 65536\r\nhw.l1icachesize: 131072\r\nhw.l2cachesize: 4194304\r\nhw.logicalcpu: 8\r\nhw.logicalcpu_max: 8\r\nhw.osenvironment: \r\nhw.packages: 1\r\nhw.pagesize: 16384\r\nhw.pagesize32: 16384\r\nhw.physicalcpu: 8\r\nhw.physicalcpu_max: 8\r\nhw.serialdebugmode: 0\r\nhw.tbfrequency: 24000000\r\nhw.use_kernelmanagerd: 1\r\nhw.use_recovery_securityd: 0\r\nhw.targettype: J293\r\n```\r\n\r\n\n", "before_files": [{"content": "__all__ = ['hardware_info']\n\nimport multiprocessing\nimport os\nimport sys\n\nimport numpy as np\n\n\ndef _mac_hardware_info():\n    info = dict()\n    results = dict()\n    for l in [l.split(':') for l in os.popen('sysctl hw').readlines()[1:]]:\n        info[l[0].strip(' \"').replace(' ', '_').lower().strip('hw.')] = \\\n            l[1].strip('.\\n ')\n    results.update({'cpus': int(info['physicalcpu'])})\n    results.update({'cpu_freq': int(float(os.popen('sysctl hw.cpufrequency')\n                                          .readlines()[0].split(':')[\n                                              1]) / 1000000)})\n    results.update({'memsize': int(int(info['memsize']) / (1024 ** 2))})\n    # add OS information\n    results.update({'os': 'Mac OSX'})\n    return results\n\n\ndef _linux_hardware_info():\n    results = {}\n    # get cpu number\n    sockets = 0\n    cores_per_socket = 0\n    frequency = 0.0\n    with open(\"/proc/cpuinfo\") as f:\n        for l in [l.split(':') for l in f.readlines()]:\n            if (l[0].strip() == \"physical id\"):\n                sockets = np.maximum(sockets,int(l[1].strip())+1)\n            if (l[0].strip() == \"cpu cores\"):\n                cores_per_socket = int(l[1].strip())\n            if (l[0].strip() == \"cpu MHz\"):\n                frequency = float(l[1].strip()) / 1000.\n    results.update({'cpus': sockets * cores_per_socket})\n    # get cpu frequency directly (bypasses freq scaling)\n    try:\n        with open(\n                \"/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq\") as f:\n            line = f.readlines()[0]\n        frequency = float(line.strip('\\n')) / 1000000.\n    except:\n        pass\n    results.update({'cpu_freq': frequency})\n\n    # get total amount of memory\n    mem_info = dict()\n    with open(\"/proc/meminfo\") as f:\n        for l in [l.split(':') for l in f.readlines()]:\n            mem_info[l[0]] = l[1].strip('.\\n ').strip('kB')\n    results.update({'memsize': int(mem_info['MemTotal']) / 1024})\n    # add OS information\n    results.update({'os': 'Linux'})\n    return results\n\n\ndef _freebsd_hardware_info():\n    results = {}\n    results.update({'cpus': int(os.popen('sysctl -n hw.ncpu').readlines()[0])})\n    results.update(\n        {'cpu_freq': int(os.popen('sysctl -n dev.cpu.0.freq').readlines()[0])})\n    results.update({'memsize': int(\n        os.popen('sysctl -n hw.realmem').readlines()[0]) / 1024})\n    results.update({'os': 'FreeBSD'})\n    return results\n\n\ndef _win_hardware_info():\n    try:\n        from comtypes.client import CoGetObject\n        winmgmts_root = CoGetObject(r\"winmgmts:root\\cimv2\")\n        cpus = winmgmts_root.ExecQuery(\"Select * from Win32_Processor\")\n        ncpus = 0\n        for cpu in cpus:\n            ncpus += int(cpu.Properties_['NumberOfCores'].Value)\n    except:\n        ncpus = int(multiprocessing.cpu_count())\n    return {'os': 'Windows', 'cpus': ncpus}\n\n\ndef hardware_info():\n    \"\"\"\n    Returns basic hardware information about the computer.\n\n    Gives actual number of CPU's in the machine, even when hyperthreading is\n    turned on.\n\n    Returns\n    -------\n    info : dict\n        Dictionary containing cpu and memory information.\n\n    \"\"\"\n    if sys.platform == 'darwin':\n        out = _mac_hardware_info()\n    elif sys.platform == 'win32':\n        out = _win_hardware_info()\n    elif sys.platform in ['linux', 'linux2']:\n        out = _linux_hardware_info()\n    elif sys.platform.startswith('freebsd'):\n        out = _freebsd_hardware_info()\n    else:\n        out = {}\n    return out\n\n\nif __name__ == '__main__':\n    print(hardware_info())\n", "path": "qutip/hardware_info.py"}], "after_files": [{"content": "__all__ = ['hardware_info']\n\nimport multiprocessing\nimport os\nimport sys\n\nimport numpy as np\n\n\ndef _mac_hardware_info():\n    info = {}\n    results = {}\n    with os.popen('sysctl hw') as f:\n        lines = f.readlines()\n    for line in lines[1:]:\n        key, _, value = line.partition(':')\n        key = key.strip(' \"').replace(' ', '_').lower().strip('hw.')\n        value = value.strip('.\\n ')\n        info[key] = value\n    results.update({'cpus': int(info['physicalcpu'])})\n    # Mac OS currently doesn't not provide hw.cpufrequency on the M1\n    with os.popen('sysctl hw.cpufrequency') as f:\n        cpu_freq_lines = f.readlines()\n    if cpu_freq_lines:\n        # Yay, hw.cpufrequency present\n        results.update({\n            'cpu_freq': float(cpu_freq_lines[0].split(':')[1]) / 1000000,\n        })\n    else:\n        # No hw.cpufrequency, assume Apple M1 CPU (all are 3.2 GHz currently)\n        results['cpu_freq'] = 3.2\n    results.update({'memsize': int(int(info['memsize']) / (1024 ** 2))})\n    # add OS information\n    results.update({'os': 'Mac OSX'})\n    return results\n\n\ndef _linux_hardware_info():\n    results = {}\n    # get cpu number\n    sockets = 0\n    cores_per_socket = 0\n    frequency = 0.0\n    with open(\"/proc/cpuinfo\") as f:\n        for l in [l.split(':') for l in f.readlines()]:\n            if (l[0].strip() == \"physical id\"):\n                sockets = np.maximum(sockets, int(l[1].strip()) + 1)\n            if (l[0].strip() == \"cpu cores\"):\n                cores_per_socket = int(l[1].strip())\n            if (l[0].strip() == \"cpu MHz\"):\n                frequency = float(l[1].strip()) / 1000.\n    results.update({'cpus': int(sockets * cores_per_socket)})\n    # get cpu frequency directly (bypasses freq scaling)\n    try:\n        with open(\n                \"/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq\") as f:\n            line = f.readlines()[0]\n        frequency = float(line.strip('\\n')) / 1000000.\n    except Exception:\n        pass\n    results.update({'cpu_freq': frequency})\n\n    # get total amount of memory\n    mem_info = dict()\n    with open(\"/proc/meminfo\") as f:\n        for l in [l.split(':') for l in f.readlines()]:\n            mem_info[l[0]] = l[1].strip('.\\n ').strip('kB')\n    results.update({'memsize': int(mem_info['MemTotal']) / 1024})\n    # add OS information\n    results.update({'os': 'Linux'})\n    return results\n\n\ndef _freebsd_hardware_info():\n    results = {}\n    results.update({'cpus': int(os.popen('sysctl -n hw.ncpu').readlines()[0])})\n    results.update(\n        {'cpu_freq': int(os.popen('sysctl -n dev.cpu.0.freq').readlines()[0])})\n    results.update({'memsize': int(\n        os.popen('sysctl -n hw.realmem').readlines()[0]) / 1024})\n    results.update({'os': 'FreeBSD'})\n    return results\n\n\ndef _win_hardware_info():\n    try:\n        from comtypes.client import CoGetObject\n        winmgmts_root = CoGetObject(r\"winmgmts:root\\cimv2\")\n        cpus = winmgmts_root.ExecQuery(\"Select * from Win32_Processor\")\n        ncpus = 0\n        for cpu in cpus:\n            ncpus += int(cpu.Properties_['NumberOfCores'].Value)\n    except Exception:\n        ncpus = int(multiprocessing.cpu_count())\n    return {'os': 'Windows', 'cpus': ncpus}\n\n\ndef hardware_info():\n    \"\"\"\n    Returns basic hardware information about the computer.\n\n    Gives actual number of CPU's in the machine, even when hyperthreading is\n    turned on.\n\n    Returns\n    -------\n    info : dict\n        Dictionary containing cpu and memory information.\n\n    \"\"\"\n    if sys.platform == 'darwin':\n        out = _mac_hardware_info()\n    elif sys.platform == 'win32':\n        out = _win_hardware_info()\n    elif sys.platform in ['linux', 'linux2']:\n        out = _linux_hardware_info()\n    elif sys.platform.startswith('freebsd'):\n        out = _freebsd_hardware_info()\n    else:\n        out = {}\n    return out\n\n\nif __name__ == '__main__':\n    print(hardware_info())\n", "path": "qutip/hardware_info.py"}]}