Repository: mindsdb/lightwood

Issue:
Apple M1 support
## Your Environment
* Operating system: macOS in an M1 apple computer

## Describe your issue
As reported by @alejandrovillegas, installation currently fails in MacBooks with M1 processors. See attached log for more details.
[m1_issue.txt](https://github.com/mindsdb/lightwood/files/7042557/m1_issue.txt)




Discussion:
If you stumble upon this issue and need support, please shout, right now I'm not sure how many users run into this and how much we should care
Potentially useful resources to get this running:
1. https://www.hendrik-erz.de/post/setting-up-python-numpy-and-pytorch-natively-on-apple-m1
2. https://www.mostlyphysics.net/blog/2021/2/6/scientific-computing-on-an-apple-m1-system

We have to remember to post an update once @alejandrovillegas figures out how to run on his machine
Update: Loads of libraries still failing, I don't expect this to work until at least 6-18 months in.
Update: as detailed in #953, it is now possible to manually get a working installation if using `miniconda` and `conda-forge`.

Resolving patch:
diff --git a/lightwood/helpers/seed.py b/lightwood/helpers/seed.py
--- a/lightwood/helpers/seed.py
+++ b/lightwood/helpers/seed.py
@@ -1,7 +1,11 @@
 import random
 import torch
 import numpy as np
-import mxnet as mx
+
+try:
+    import mxnet as mx
+except Exception:
+    mx = None
 
 
 def seed(seed_nr: int) -> None:
@@ -10,4 +14,6 @@ def seed(seed_nr: int) -> None:
     torch.backends.cudnn.benchmark = False
     np.random.seed(seed_nr)
     random.seed(seed_nr)
-    mx.random.seed(seed_nr)
+
+    if mx is not None:
+        mx.random.seed(seed_nr)
diff --git a/lightwood/mixer/__init__.py b/lightwood/mixer/__init__.py
--- a/lightwood/mixer/__init__.py
+++ b/lightwood/mixer/__init__.py
@@ -7,7 +7,6 @@
 from lightwood.mixer.sktime import SkTime
 from lightwood.mixer.arima import ARIMAMixer
 from lightwood.mixer.ets import ETSMixer
-from lightwood.mixer.gluonts import GluonTSMixer
 from lightwood.mixer.regression import Regression
 
 try:
@@ -25,6 +24,11 @@
 except Exception:
     ProphetMixer = None
 
+try:
+    from lightwood.mixer.gluonts import GluonTSMixer
+except Exception:
+    GluonTSMixer = None
+
 try:
     from lightwood.mixer.lightgbm import LightGBM
     from lightwood.mixer.lightgbm_array import LightGBMArray


Test patch:
diff --git a/tests/integration/advanced/test_timeseries.py b/tests/integration/advanced/test_timeseries.py
--- a/tests/integration/advanced/test_timeseries.py
+++ b/tests/integration/advanced/test_timeseries.py
@@ -572,28 +572,31 @@ def test_11_output_date_format(self):
 
     def test_12_gluonts(self):
         """ Tests GluonTS mixer """
-        data = pd.read_csv('tests/data/arrivals.csv')
-        for i, subdata in enumerate([data, data[data['Country'] == 'US']]):
-            order_by = 'T'
-            train_df, test_df = self.split_arrivals(subdata, grouped=False)
-            pdef = {'target': 'Traffic',
-                    'timeseries_settings': {
-                        'order_by': order_by,
-                        'window': 4 * 5,
-                        'horizon': 4 * 2}}
-            if i == 0:
-                pdef['timeseries_settings']['group_by'] = ['Country']
-            jai = json_ai_from_problem(train_df, ProblemDefinition.from_dict(pdef))
-            jai.model['args']['submodels'] = [{
-                "module": "GluonTSMixer",
-                "args": {}
-            }]
-            predictor = predictor_from_json_ai(jai)
-            predictor.learn(train_df)
-            predictor.predict(test_df.iloc[[-1]], args={'time_format': 'infer'})
-
-            # adjust
-            adjust_n_epochs = 5
-            predictor.adjust(test_df, adjust_args={'n_epochs': adjust_n_epochs})
-            predictor.predict(test_df.iloc[[-1]], args={'time_format': 'infer'})
-            assert predictor.mixers[0].n_epochs == adjust_n_epochs
+        from lightwood.mixer import GluonTSMixer
+
+        if GluonTSMixer is not None:
+            data = pd.read_csv('tests/data/arrivals.csv')
+            for i, subdata in enumerate([data, data[data['Country'] == 'US']]):
+                order_by = 'T'
+                train_df, test_df = self.split_arrivals(subdata, grouped=False)
+                pdef = {'target': 'Traffic',
+                        'timeseries_settings': {
+                            'order_by': order_by,
+                            'window': 4 * 5,
+                            'horizon': 4 * 2}}
+                if i == 0:
+                    pdef['timeseries_settings']['group_by'] = ['Country']
+                jai = json_ai_from_problem(train_df, ProblemDefinition.from_dict(pdef))
+                jai.model['args']['submodels'] = [{
+                    "module": "GluonTSMixer",
+                    "args": {}
+                }]
+                predictor = predictor_from_json_ai(jai)
+                predictor.learn(train_df)
+                predictor.predict(test_df.iloc[[-1]], args={'time_format': 'infer'})
+
+                # adjust
+                adjust_n_epochs = 5
+                predictor.adjust(test_df, adjust_args={'n_epochs': adjust_n_epochs})
+                predictor.predict(test_df.iloc[[-1]], args={'time_format': 'infer'})
+                assert predictor.mixers[0].n_epochs == adjust_n_epochs