Repository: pykeen/pykeen
Issue:  IndexError: tensors used as indices must be long, byte or bool tensors
Root cause: Environment Incompatibility

### Describe the bug

When I instantiate a TriplesFactory on COLAB, I get the above error.
I see that it runs nomically on my local system, so I am not sure what this is about.

Still, I thought it warranted some attention.

### How to reproduce

COLAB link: https://colab.research.google.com/drive/10oqSFPj5UXvig9I5QHi7IwxmQnC0wxEE?usp=sharing

Do note that at the provided COLAB link there is also a short script to reproduce another bug which I was investigating before stumbling against this one, which seems considerably weirder.

The code in the COLAB can be summarized as follows:

```bash
pip install pykeen grape
```

```python
from grape.embedders import NodePiecePyKEEN
from grape.datasets.linqs import Cora

NodePiecePyKEEN().fit_transform(Cora().remove_singleton_nodes())
```

This will get you:

```
IndexError                                Traceback (most recent call last)
[<ipython-input-3-b4717177b450>](https://localhost:8080/#) in <module>()
      2 from grape.datasets.linqs import Cora
      3 
----> 4 embedding = NodePiecePyKEEN().fit_transform(Cora().remove_singleton_nodes())

20 frames
[/usr/local/lib/python3.7/dist-packages/embiggen/utils/abstract_models/abstract_embedding_model.py](https://localhost:8080/#) in fit_transform(self, graph, repository, version, return_dataframe)
    230         return self._cached_fit_transform(
    231             graph=graph,
--> 232             return_dataframe=return_dataframe,
    233         )

[/usr/local/lib/python3.7/dist-packages/cache_decorator/cache.py](https://localhost:8080/#) in wrapped(*args, **kwargs)
    595             if not cache_enabled:
    596                 self.logger.info("The cache is disabled")
--> 597                 result = function(*args, **kwargs)
    598                 self._check_return_type_compatability(result, self.cache_path)
    599                 return result

[/usr/local/lib/python3.7/dist-packages/embiggen/utils/abstract_models/abstract_embedding_model.py](https://localhost:8080/#) in _cached_fit_transform(self, graph, return_dataframe)
    179         result = self._fit_transform(
    180             graph=graph,
--> 181             return_dataframe=return_dataframe,
    182         )
    183 

[/usr/local/lib/python3.7/dist-packages/embiggen/embedders/pykeen_embedders/pykeen_embedder.py](https://localhost:8080/#) in _fit_transform(self, graph, return_dataframe)
    232                 disable=not self._verbose,
    233                 dynamic_ncols=True,
--> 234                 leave=False
    235             )
    236         )

[/usr/local/lib/python3.7/dist-packages/pykeen/training/training_loop.py](https://localhost:8080/#) in train(self, triples_factory, num_epochs, batch_size, slice_size, label_smoothing, sampler, continue_training, only_size_probing, use_tqdm, use_tqdm_batch, tqdm_kwargs, stopper, sub_batch_size, num_workers, clear_optimizer, checkpoint_directory, checkpoint_name, checkpoint_frequency, checkpoint_on_failure, drop_last, callbacks, callback_kwargs, gradient_clipping_max_norm, gradient_clipping_norm_type, gradient_clipping_max_abs_value, pin_memory)
    396                 gradient_clipping_max_abs_value=gradient_clipping_max_abs_value,
    397                 triples_factory=triples_factory,
--> 398                 pin_memory=pin_memory,
    399             )
    400 

[/usr/local/lib/python3.7/dist-packages/pykeen/training/training_loop.py](https://localhost:8080/#) in _train(self, triples_factory, num_epochs, batch_size, slice_size, label_smoothing, sampler, continue_training, only_size_probing, use_tqdm, use_tqdm_batch, tqdm_kwargs, stopper, sub_batch_size, num_workers, save_checkpoints, checkpoint_path, checkpoint_frequency, checkpoint_on_failure_file_path, best_epoch_model_file_path, last_best_epoch, drop_last, callbacks, callback_kwargs, gradient_clipping_max_norm, gradient_clipping_norm_type, gradient_clipping_max_abs_value, pin_memory)
    515             # return the relevant parameters slice_size and batch_size
    516             sub_batch_size, slice_size = self.sub_batch_and_slice(
--> 517                 batch_size=batch_size, sampler=sampler, triples_factory=triples_factory
    518             )
    519 

[/usr/local/lib/python3.7/dist-packages/pykeen/training/training_loop.py](https://localhost:8080/#) in sub_batch_and_slice(self, batch_size, sampler, triples_factory)
    933             batch_size=batch_size,
    934             sampler=sampler,
--> 935             triples_factory=triples_factory,
    936         )
    937         # If the sub_batch_size did not finish search with a possibility that fits the hardware, we have to try slicing

[/usr/local/lib/python3.7/dist-packages/pykeen/training/training_loop.py](https://localhost:8080/#) in _sub_batch_size_search(self, batch_size, sampler, triples_factory)
   1011                 sub_batch_size=sub_batch_size,
   1012                 sampler=sampler,
-> 1013                 only_size_probing=True,
   1014             )
   1015         except RuntimeError as runtime_error:

[/usr/local/lib/python3.7/dist-packages/pykeen/training/training_loop.py](https://localhost:8080/#) in _train(self, triples_factory, num_epochs, batch_size, slice_size, label_smoothing, sampler, continue_training, only_size_probing, use_tqdm, use_tqdm_batch, tqdm_kwargs, stopper, sub_batch_size, num_workers, save_checkpoints, checkpoint_path, checkpoint_frequency, checkpoint_on_failure_file_path, best_epoch_model_file_path, last_best_epoch, drop_last, callbacks, callback_kwargs, gradient_clipping_max_norm, gradient_clipping_norm_type, gradient_clipping_max_abs_value, pin_memory)
    639                             current_batch_size,
    640                             label_smoothing,
--> 641                             slice_size,
    642                         )
    643                         current_epoch_loss += batch_loss

[/usr/local/lib/python3.7/dist-packages/pykeen/training/training_loop.py](https://localhost:8080/#) in _forward_pass(self, batch, start, stop, current_batch_size, label_smoothing, slice_size)
    814             stop=stop,
    815             label_smoothing=label_smoothing,
--> 816             slice_size=slice_size,
    817         )
    818 

[/usr/local/lib/python3.7/dist-packages/pykeen/training/slcwa.py](https://localhost:8080/#) in _process_batch(self, batch, start, stop, label_smoothing, slice_size)
    105 
    106         # Compute negative and positive scores
--> 107         positive_scores = self.model.score_hrt(positive_batch, mode=self.mode)
    108         negative_scores = self.model.score_hrt(negative_batch, mode=self.mode).view(*negative_score_shape)
    109 

[/usr/local/lib/python3.7/dist-packages/pykeen/models/nbase.py](https://localhost:8080/#) in score_hrt(self, hrt_batch, mode)
    405         # Note: we do not delegate to the general method for performance reasons
    406         # Note: repetition is not necessary here
--> 407         h, r, t = self._get_representations(h=hrt_batch[:, 0], r=hrt_batch[:, 1], t=hrt_batch[:, 2], mode=mode)
    408         return self.interaction.score_hrt(h=h, r=r, t=t)
    409 

[/usr/local/lib/python3.7/dist-packages/pykeen/models/nbase.py](https://localhost:8080/#) in _get_representations(self, h, r, t, mode)
    520                 (h, head_representations),
    521                 (r, self.relation_representations),
--> 522                 (t, tail_representations),
    523             )
    524         ]

[/usr/local/lib/python3.7/dist-packages/pykeen/models/nbase.py](https://localhost:8080/#) in <listcomp>(.0)
    517         hr, rr, tr = [
    518             [representation.forward_unique(indices=indices) for representation in representations]
--> 519             for indices, representations in (
    520                 (h, head_representations),
    521                 (r, self.relation_representations),

[/usr/local/lib/python3.7/dist-packages/pykeen/models/nbase.py](https://localhost:8080/#) in <listcomp>(.0)
    516         tail_representations = [tail_representations[i] for i in self.interaction.tail_indices()]
    517         hr, rr, tr = [
--> 518             [representation.forward_unique(indices=indices) for representation in representations]
    519             for indices, representations in (
    520                 (h, head_representations),

[/usr/local/lib/python3.7/dist-packages/pykeen/nn/representation.py](https://localhost:8080/#) in forward_unique(self, indices)
    166             return self(None)
    167         unique, inverse = indices.unique(return_inverse=True)
--> 168         x_unique = self._plain_forward(indices=unique)
    169         # normalize *before* repeating
    170         if self.normalizer is not None:

[/usr/local/lib/python3.7/dist-packages/pykeen/nn/node_piece/representations.py](https://localhost:8080/#) in _plain_forward(self, indices)
    294         return self.aggregation(
    295             torch.cat(
--> 296                 [tokenization(indices=indices) for tokenization in self.token_representations],
    297                 dim=self.aggregation_index,
    298             ),

[/usr/local/lib/python3.7/dist-packages/pykeen/nn/node_piece/representations.py](https://localhost:8080/#) in <listcomp>(.0)
    294         return self.aggregation(
    295             torch.cat(
--> 296                 [tokenization(indices=indices) for tokenization in self.token_representations],
    297                 dim=self.aggregation_index,
    298             ),

[/usr/local/lib/python3.7/dist-packages/torch/nn/modules/module.py](https://localhost:8080/#) in _call_impl(self, *input, **kwargs)
   1128         if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
   1129                 or _global_forward_hooks or _global_forward_pre_hooks):
-> 1130             return forward_call(*input, **kwargs)
   1131         # Do not call functions when jit is used
   1132         full_backward_hooks, non_full_backward_hooks = [], []

[/usr/local/lib/python3.7/dist-packages/pykeen/nn/representation.py](https://localhost:8080/#) in forward(self, indices)
    141             The representations.
    142         """
--> 143         x = self._plain_forward(indices=indices)
    144         if self.normalizer is not None:
    145             x = self.normalizer(x)

[/usr/local/lib/python3.7/dist-packages/pykeen/nn/node_piece/representations.py](https://localhost:8080/#) in _plain_forward(self, indices)
    161         token_ids = self.assignment
    162         if indices is not None:
--> 163             token_ids = token_ids[indices]
    164 
    165         # lookup token representations, shape: (*, num_chosen_tokens, *shape)

IndexError: tensors used as indices must be long, byte or bool tensors
```

### Environment

On COLAB the environment is Python 3.7. Possibly that is the reason it is not working? Does this mean that PyKEEN does not execute on COLAB at all?

| Key             | Value                    |
|-----------------|--------------------------|
| OS              | posix                    |
| Platform        | Linux                    |
| Release         | 5.4.188+                 |
| Time            | Wed Aug 10 14:32:57 2022 |
| Python          | 3.7.13                   |
| PyKEEN          | 1.8.1                    |
| PyKEEN Hash     | UNHASHED                 |
| PyKEEN Branch   |                          |
| PyTorch         | 1.12.0+cu113             |
| CUDA Available? | false                    |
| CUDA Version    | 11.3                     |
| cuDNN Version   | 8302                     |

### Additional information

_No response_

### Issue Template Checks

- [X] This is not a feature request (use a different issue template if it is)
- [X] This is not a question (use the [discussions](https://github.com/pykeen/pykeen/discussions/new) forum instead)
- [X] I've read the text explaining why including environment information is important and understand if I omit this information that my issue will be dismissed

Hi @LucaCappelletti94 ,

we only support Python >= 3.8.

Moreover, without being familiar with GRAPE, it is hard to tell from the small snippet how it interacts with PyKEEN, and thus where the error comes from.

GRAPE only works as a wrapper; shortening the code is required to get the error. Does the `Python >= 3.8` requirement mean that currently, PyKEEN does not run on COLAB? I hoped to write some tutorials.

does colab only run python 3.7? it's awfully hard for us to keep up with the downstream environments where people are trying to run PyKEEN, let us know if/when you figure it out or join the discussion here https://github.com/pykeen/pykeen/issues/843

It functionally only runs 3.7. [There are gimmicks to make it run 3.8 ](https://stackoverflow.com/questions/60775160/install-python-3-8-kernel-in-google-colaboratory), but it is pretty safe to assume that the average user will not be knowledgeable enough to find and run such things.

For the model wrappers I use in GRAPE, I have added a clear exception that tells the user that the PyKEEN models are not available in Python <3.8, with a few reasons and possible solutions to updating their environment.

Closing as this is not an error of PyKEEN but mostly a limitation of COLAB.