We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[BUG] No module named 'fcntl' while importing the package
Hey,
Working on windows 11, Python 3.7 and tried importing the package.
Got the error in the title, is there a way around it since it's exclusive to Linux?

![fcntl](https://user-images.githubusercontent.com/61480454/164317686-5303f264-5fc7-42c0-89b5-d16a125ae11f.png)
 

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `deepspeed/utils/debug.py`
Content:
```
1 """ debug utils """
2 
3 import fcntl
4 
5 # for debug purposes map module and param objects to their fully qualified names
6 module_names = {}
7 param_names = {}
8 
9 
10 def debug_extract_module_and_param_names(model):
11     # extract the fully qualified names as soon as the model is acquired
12     global module_names
13     global param_names
14     # XXX: can probably make a map of param2module and vice-versa
15     module_names = {module: name for name, module in model.named_modules()}
16     param_names = {param: name for name, param in model.named_parameters()}
17 
18 
19 def debug_module2name(module):
20     if module in module_names:
21         return module_names[module]
22     else:
23         return "unknown"
24 
25 
26 def debug_module2name_id(module):
27     return f"name={debug_module2name(module)} id={module.id}"
28 
29 
30 def debug_module2name_class(module):
31     return f"name={debug_module2name(module)} {module.__class__.__name__}"
32 
33 
34 def debug_param2name(param):
35     if param in param_names:
36         return param_names[param]
37     else:
38         return "unknown"
39 
40 
41 def debug_param2name_id(param):
42     return f"name={debug_param2name(param)} id={param.ds_id}"
43 
44 
45 def debug_param2name_id_shape(param):
46     return f"name={debug_param2name(param)} id={param.ds_id} shape={param.data.shape}"
47 
48 
49 def debug_param2name_id_shape_device(param):
50     return f"name={debug_param2name(param)} id={param.ds_id} shape={param.data.shape} device={param.device}"
51 
52 
53 def debug_param2name_id_numel(param):
54     return f"name={debug_param2name(param)} id={param.ds_id} numel={param.numel()}"
55 
56 
57 def debug_param2name_id_shape_status(param):
58     return f"name={debug_param2name(param)} id={param.ds_id} shape={param.data.shape} status={param.ds_status}"
59 
60 
61 def printflock(*msgs):
62     """
63 
64     For printing messages for all concurrent gpus w/o getting interleaved text.
65 
66     This is useful when debugging issues where multi-gpus don't sync.
67 
68     1. Enable the force debug in say partitioning and zero3 files
69     2. Override the usual versions with ::
70 
71         def print_rank_0(message, debug=False, force=False):
72             rank = torch.distributed.get_rank()
73             printflock(f"[{rank}] {message}")
74     3. run the program and you get both logs non-interleaved
75 
76     But this makes it very difficult to make sense of the output, so the ``log_rank_file`` helper
77     function might be more useful, as it's easier to send each log stream into a separate file and
78     then compare those.
79 
80     """
81 
82     with open(__file__, "r") as fh:
83         fcntl.flock(fh, fcntl.LOCK_EX)
84         try:
85             print(*msgs)
86         finally:
87             fcntl.flock(fh, fcntl.LOCK_UN)
88 
89 
90 fh = None
91 
92 
93 def log_rank_file(rank, *msgs):
94     """
95     Print to a log file of the given rank
96 
97     This is useful for debugging hanging in sync processes. Here is a possible workflow:
98 
99     1. Enable the force debug in say partitioning and zero3 files
100     2. Override the usual versions of print_rank_0 in those files with ::
101 
102         def print_rank_0(message, debug=False, force=False):
103             rank = torch.distributed.get_rank()
104             log_rank_file(rank, message)
105 
106     3. run the program
107     4. fix up the expected differences, e.g. different cuda numbers ::
108 
109         perl -pi -e 's|cuda:1|cuda:0|' log_rank_*
110 
111     5. now diff and see where names and ids diverge - you will find where the gpus don't do the same
112     work (e.g. when some layers get conditionally skipped on one gpu but not all)
113 
114         diff -u log_rank_0.txt log_rank_1.txt | less
115 
116     """
117     global fh
118     if fh is None:
119         fh = open(f"log_rank_{rank}.txt", "w")
120     for m in msgs:
121         fh.write(f"{m}\n")
122     fh.flush()
123 
124 
125 def print_backward_tensors(tensor):
126     def _print_bwd_tensors(grad_fn):
127         print(f"Backward tensors in {grad_fn}")
128         for funcs in grad_fn.next_functions:
129             if funcs[0]:
130                 try:
131                     tensor = getattr(funcs[0], 'variable')
132                     print(funcs[0])
133                     print(
134                         f"Tensor - id: {id(tensor)}, shape: {tensor.shape}, data: {tensor}, grad: {tensor.grad}"
135                     )
136                 except AttributeError as e:
137                     _print_bwd_tensors(funcs[0])
138 
139     if hasattr(tensor, 'grad_fn'):
140         _print_bwd_tensors(tensor.grad_fn)
141
```
--- 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/deepspeed/utils/debug.py b/deepspeed/utils/debug.py
--- a/deepspeed/utils/debug.py
+++ b/deepspeed/utils/debug.py
@@ -1,6 +1,7 @@
 """ debug utils """
 
-import fcntl
+# For lazy import with printflock()
+fcntl = None
 
 # for debug purposes map module and param objects to their fully qualified names
 module_names = {}
@@ -78,6 +79,9 @@
     then compare those.
 
     """
+    global fcntl
+    if fcntl == None:
+        import fcntl
 
     with open(__file__, "r") as fh:
         fcntl.flock(fh, fcntl.LOCK_EX)

{"golden_diff": "diff --git a/deepspeed/utils/debug.py b/deepspeed/utils/debug.py\n--- a/deepspeed/utils/debug.py\n+++ b/deepspeed/utils/debug.py\n@@ -1,6 +1,7 @@\n \"\"\" debug utils \"\"\"\n \n-import fcntl\n+# For lazy import with printflock()\n+fcntl = None\n \n # for debug purposes map module and param objects to their fully qualified names\n module_names = {}\n@@ -78,6 +79,9 @@\n     then compare those.\n \n     \"\"\"\n+    global fcntl\n+    if fcntl == None:\n+        import fcntl\n \n     with open(__file__, \"r\") as fh:\n         fcntl.flock(fh, fcntl.LOCK_EX)\n", "issue": "[BUG] No module named 'fcntl' while importing the package\nHey,\r\nWorking on windows 11, Python 3.7 and tried importing the package.\r\nGot the error in the title, is there a way around it since it's exclusive to Linux?\r\n\r\n![fcntl](https://user-images.githubusercontent.com/61480454/164317686-5303f264-5fc7-42c0-89b5-d16a125ae11f.png)\r\n \n", "before_files": [{"content": "\"\"\" debug utils \"\"\"\n\nimport fcntl\n\n# for debug purposes map module and param objects to their fully qualified names\nmodule_names = {}\nparam_names = {}\n\n\ndef debug_extract_module_and_param_names(model):\n    # extract the fully qualified names as soon as the model is acquired\n    global module_names\n    global param_names\n    # XXX: can probably make a map of param2module and vice-versa\n    module_names = {module: name for name, module in model.named_modules()}\n    param_names = {param: name for name, param in model.named_parameters()}\n\n\ndef debug_module2name(module):\n    if module in module_names:\n        return module_names[module]\n    else:\n        return \"unknown\"\n\n\ndef debug_module2name_id(module):\n    return f\"name={debug_module2name(module)} id={module.id}\"\n\n\ndef debug_module2name_class(module):\n    return f\"name={debug_module2name(module)} {module.__class__.__name__}\"\n\n\ndef debug_param2name(param):\n    if param in param_names:\n        return param_names[param]\n    else:\n        return \"unknown\"\n\n\ndef debug_param2name_id(param):\n    return f\"name={debug_param2name(param)} id={param.ds_id}\"\n\n\ndef debug_param2name_id_shape(param):\n    return f\"name={debug_param2name(param)} id={param.ds_id} shape={param.data.shape}\"\n\n\ndef debug_param2name_id_shape_device(param):\n    return f\"name={debug_param2name(param)} id={param.ds_id} shape={param.data.shape} device={param.device}\"\n\n\ndef debug_param2name_id_numel(param):\n    return f\"name={debug_param2name(param)} id={param.ds_id} numel={param.numel()}\"\n\n\ndef debug_param2name_id_shape_status(param):\n    return f\"name={debug_param2name(param)} id={param.ds_id} shape={param.data.shape} status={param.ds_status}\"\n\n\ndef printflock(*msgs):\n    \"\"\"\n\n    For printing messages for all concurrent gpus w/o getting interleaved text.\n\n    This is useful when debugging issues where multi-gpus don't sync.\n\n    1. Enable the force debug in say partitioning and zero3 files\n    2. Override the usual versions with ::\n\n        def print_rank_0(message, debug=False, force=False):\n            rank = torch.distributed.get_rank()\n            printflock(f\"[{rank}] {message}\")\n    3. run the program and you get both logs non-interleaved\n\n    But this makes it very difficult to make sense of the output, so the ``log_rank_file`` helper\n    function might be more useful, as it's easier to send each log stream into a separate file and\n    then compare those.\n\n    \"\"\"\n\n    with open(__file__, \"r\") as fh:\n        fcntl.flock(fh, fcntl.LOCK_EX)\n        try:\n            print(*msgs)\n        finally:\n            fcntl.flock(fh, fcntl.LOCK_UN)\n\n\nfh = None\n\n\ndef log_rank_file(rank, *msgs):\n    \"\"\"\n    Print to a log file of the given rank\n\n    This is useful for debugging hanging in sync processes. Here is a possible workflow:\n\n    1. Enable the force debug in say partitioning and zero3 files\n    2. Override the usual versions of print_rank_0 in those files with ::\n\n        def print_rank_0(message, debug=False, force=False):\n            rank = torch.distributed.get_rank()\n            log_rank_file(rank, message)\n\n    3. run the program\n    4. fix up the expected differences, e.g. different cuda numbers ::\n\n        perl -pi -e 's|cuda:1|cuda:0|' log_rank_*\n\n    5. now diff and see where names and ids diverge - you will find where the gpus don't do the same\n    work (e.g. when some layers get conditionally skipped on one gpu but not all)\n\n        diff -u log_rank_0.txt log_rank_1.txt | less\n\n    \"\"\"\n    global fh\n    if fh is None:\n        fh = open(f\"log_rank_{rank}.txt\", \"w\")\n    for m in msgs:\n        fh.write(f\"{m}\\n\")\n    fh.flush()\n\n\ndef print_backward_tensors(tensor):\n    def _print_bwd_tensors(grad_fn):\n        print(f\"Backward tensors in {grad_fn}\")\n        for funcs in grad_fn.next_functions:\n            if funcs[0]:\n                try:\n                    tensor = getattr(funcs[0], 'variable')\n                    print(funcs[0])\n                    print(\n                        f\"Tensor - id: {id(tensor)}, shape: {tensor.shape}, data: {tensor}, grad: {tensor.grad}\"\n                    )\n                except AttributeError as e:\n                    _print_bwd_tensors(funcs[0])\n\n    if hasattr(tensor, 'grad_fn'):\n        _print_bwd_tensors(tensor.grad_fn)\n", "path": "deepspeed/utils/debug.py"}], "after_files": [{"content": "\"\"\" debug utils \"\"\"\n\n# For lazy import with printflock()\nfcntl = None\n\n# for debug purposes map module and param objects to their fully qualified names\nmodule_names = {}\nparam_names = {}\n\n\ndef debug_extract_module_and_param_names(model):\n    # extract the fully qualified names as soon as the model is acquired\n    global module_names\n    global param_names\n    # XXX: can probably make a map of param2module and vice-versa\n    module_names = {module: name for name, module in model.named_modules()}\n    param_names = {param: name for name, param in model.named_parameters()}\n\n\ndef debug_module2name(module):\n    if module in module_names:\n        return module_names[module]\n    else:\n        return \"unknown\"\n\n\ndef debug_module2name_id(module):\n    return f\"name={debug_module2name(module)} id={module.id}\"\n\n\ndef debug_module2name_class(module):\n    return f\"name={debug_module2name(module)} {module.__class__.__name__}\"\n\n\ndef debug_param2name(param):\n    if param in param_names:\n        return param_names[param]\n    else:\n        return \"unknown\"\n\n\ndef debug_param2name_id(param):\n    return f\"name={debug_param2name(param)} id={param.ds_id}\"\n\n\ndef debug_param2name_id_shape(param):\n    return f\"name={debug_param2name(param)} id={param.ds_id} shape={param.data.shape}\"\n\n\ndef debug_param2name_id_shape_device(param):\n    return f\"name={debug_param2name(param)} id={param.ds_id} shape={param.data.shape} device={param.device}\"\n\n\ndef debug_param2name_id_numel(param):\n    return f\"name={debug_param2name(param)} id={param.ds_id} numel={param.numel()}\"\n\n\ndef debug_param2name_id_shape_status(param):\n    return f\"name={debug_param2name(param)} id={param.ds_id} shape={param.data.shape} status={param.ds_status}\"\n\n\ndef printflock(*msgs):\n    \"\"\"\n\n    For printing messages for all concurrent gpus w/o getting interleaved text.\n\n    This is useful when debugging issues where multi-gpus don't sync.\n\n    1. Enable the force debug in say partitioning and zero3 files\n    2. Override the usual versions with ::\n\n        def print_rank_0(message, debug=False, force=False):\n            rank = torch.distributed.get_rank()\n            printflock(f\"[{rank}] {message}\")\n    3. run the program and you get both logs non-interleaved\n\n    But this makes it very difficult to make sense of the output, so the ``log_rank_file`` helper\n    function might be more useful, as it's easier to send each log stream into a separate file and\n    then compare those.\n\n    \"\"\"\n    global fcntl\n    if fcntl == None:\n        import fcntl\n\n    with open(__file__, \"r\") as fh:\n        fcntl.flock(fh, fcntl.LOCK_EX)\n        try:\n            print(*msgs)\n        finally:\n            fcntl.flock(fh, fcntl.LOCK_UN)\n\n\nfh = None\n\n\ndef log_rank_file(rank, *msgs):\n    \"\"\"\n    Print to a log file of the given rank\n\n    This is useful for debugging hanging in sync processes. Here is a possible workflow:\n\n    1. Enable the force debug in say partitioning and zero3 files\n    2. Override the usual versions of print_rank_0 in those files with ::\n\n        def print_rank_0(message, debug=False, force=False):\n            rank = torch.distributed.get_rank()\n            log_rank_file(rank, message)\n\n    3. run the program\n    4. fix up the expected differences, e.g. different cuda numbers ::\n\n        perl -pi -e 's|cuda:1|cuda:0|' log_rank_*\n\n    5. now diff and see where names and ids diverge - you will find where the gpus don't do the same\n    work (e.g. when some layers get conditionally skipped on one gpu but not all)\n\n        diff -u log_rank_0.txt log_rank_1.txt | less\n\n    \"\"\"\n    global fh\n    if fh is None:\n        fh = open(f\"log_rank_{rank}.txt\", \"w\")\n    for m in msgs:\n        fh.write(f\"{m}\\n\")\n    fh.flush()\n\n\ndef print_backward_tensors(tensor):\n    def _print_bwd_tensors(grad_fn):\n        print(f\"Backward tensors in {grad_fn}\")\n        for funcs in grad_fn.next_functions:\n            if funcs[0]:\n                try:\n                    tensor = getattr(funcs[0], 'variable')\n                    print(funcs[0])\n                    print(\n                        f\"Tensor - id: {id(tensor)}, shape: {tensor.shape}, data: {tensor}, grad: {tensor.grad}\"\n                    )\n                except AttributeError as e:\n                    _print_bwd_tensors(funcs[0])\n\n    if hasattr(tensor, 'grad_fn'):\n        _print_bwd_tensors(tensor.grad_fn)\n", "path": "deepspeed/utils/debug.py"}]}