From 9e682ddacc01b5175d5a4cdb589a847af53598fd Mon Sep 17 00:00:00 2001 From: bhimes Date: Wed, 1 May 2024 22:55:18 +0200 Subject: [PATCH 1/8] Monkeypatch in the caching of get_decoder_class Fixes #1833 --- bittensor/subtensor.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/bittensor/subtensor.py b/bittensor/subtensor.py index 22396e38e8..33c04c71c6 100644 --- a/bittensor/subtensor.py +++ b/bittensor/subtensor.py @@ -1,6 +1,7 @@ # The MIT License (MIT) # Copyright © 2021 Yuma Rao # Copyright © 2023 Opentensor Foundation +import functools # Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated # documentation files (the “Software”), to deal in the Software without restriction, including without limitation @@ -92,6 +93,21 @@ T = TypeVar("T") +####### +# Monkey patch in caching the get_decoder_class method +####### +@functools.cache +def patched_get_decoder_class(self, type_string): + return original_get_decoder_class(self, type_string) + + +if hasattr(RuntimeConfiguration, "get_decoder_class"): + original_get_decoder_class = RuntimeConfiguration.get_decoder_class + RuntimeConfiguration.get_decoder_class = patched_get_decoder_class + +####### + + class ParamWithTypes(TypedDict): name: str # Name of the parameter. type: str # ScaleType string of the parameter. From 33749e672bfe1dbe42b8a088fb4c35aa53b8738a Mon Sep 17 00:00:00 2001 From: bhimes Date: Thu, 2 May 2024 00:00:26 +0200 Subject: [PATCH 2/8] Change cache to lru_cache to keep compatibility with Python 3.8 (cache was added in 3.9) --- bittensor/subtensor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bittensor/subtensor.py b/bittensor/subtensor.py index 33c04c71c6..18747cd73e 100644 --- a/bittensor/subtensor.py +++ b/bittensor/subtensor.py @@ -96,7 +96,7 @@ ####### # Monkey patch in caching the get_decoder_class method ####### -@functools.cache +@functools.lru_cache(maxsize=None) def patched_get_decoder_class(self, type_string): return original_get_decoder_class(self, type_string) From 5a3a0a6d24222aa7f487806f7c65ed45a63cd45c Mon Sep 17 00:00:00 2001 From: bhimes Date: Thu, 2 May 2024 18:41:54 +0200 Subject: [PATCH 3/8] Added note to requirements to verify we do not change scalecodec until verifying compatibility with the monkeypatch. --- requirements/prod.txt | 2 ++ scripts/environments/apple_m1_environment.yml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/requirements/prod.txt b/requirements/prod.txt index 7a8d3edba0..99a4916d4b 100644 --- a/requirements/prod.txt +++ b/requirements/prod.txt @@ -26,6 +26,8 @@ pytest retry requests rich +# scalecodec should not be changed unless first verifying compatibility with the subtensor's +# monkeypatching of scalecodec.RuntimeConfiguration.get_decoder_class scalecodec==1.2.7 shtab==1.6.5 substrate-interface==1.7.5 diff --git a/scripts/environments/apple_m1_environment.yml b/scripts/environments/apple_m1_environment.yml index d789c31002..73228a97ab 100644 --- a/scripts/environments/apple_m1_environment.yml +++ b/scripts/environments/apple_m1_environment.yml @@ -229,6 +229,8 @@ dependencies: - retry==0.9.2 - rich==12.5.1 - rsa==4.9 +# scalecodec should not be changed unless first verifying compatibility with the subtensor's +# monkeypatching of scalecodec.RuntimeConfiguration.get_decoder_class - scalecodec==1.2.7 - scikit-learn==1.2.2 - scipy==1.10.1 From d3cd9b651901dc23d62804cb2f774350b655d962 Mon Sep 17 00:00:00 2001 From: bhimes Date: Thu, 2 May 2024 18:55:30 +0200 Subject: [PATCH 4/8] Added whitespace before comments in requirements files. --- requirements/prod.txt | 4 ++-- scripts/environments/apple_m1_environment.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/requirements/prod.txt b/requirements/prod.txt index 99a4916d4b..8bcd047c8f 100644 --- a/requirements/prod.txt +++ b/requirements/prod.txt @@ -26,8 +26,8 @@ pytest retry requests rich -# scalecodec should not be changed unless first verifying compatibility with the subtensor's -# monkeypatching of scalecodec.RuntimeConfiguration.get_decoder_class + # scalecodec should not be changed unless first verifying compatibility with the subtensor's + # monkeypatching of scalecodec.RuntimeConfiguration.get_decoder_class scalecodec==1.2.7 shtab==1.6.5 substrate-interface==1.7.5 diff --git a/scripts/environments/apple_m1_environment.yml b/scripts/environments/apple_m1_environment.yml index 73228a97ab..a8fcc13f21 100644 --- a/scripts/environments/apple_m1_environment.yml +++ b/scripts/environments/apple_m1_environment.yml @@ -229,8 +229,8 @@ dependencies: - retry==0.9.2 - rich==12.5.1 - rsa==4.9 -# scalecodec should not be changed unless first verifying compatibility with the subtensor's -# monkeypatching of scalecodec.RuntimeConfiguration.get_decoder_class + # scalecodec should not be changed unless first verifying compatibility with the subtensor's + # monkeypatching of scalecodec.RuntimeConfiguration.get_decoder_class - scalecodec==1.2.7 - scikit-learn==1.2.2 - scipy==1.10.1 From 04f61440a942d3f3d2077d6a2b7c39c9ea6ddb03 Mon Sep 17 00:00:00 2001 From: bhimes Date: Thu, 2 May 2024 19:38:37 +0200 Subject: [PATCH 5/8] Requirements comments format change. --- requirements/prod.txt | 4 +--- scripts/environments/apple_m1_environment.yml | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/requirements/prod.txt b/requirements/prod.txt index 8bcd047c8f..5a1e01bd1e 100644 --- a/requirements/prod.txt +++ b/requirements/prod.txt @@ -26,9 +26,7 @@ pytest retry requests rich - # scalecodec should not be changed unless first verifying compatibility with the subtensor's - # monkeypatching of scalecodec.RuntimeConfiguration.get_decoder_class -scalecodec==1.2.7 +scalecodec==1.2.7 # scalecodec should not be changed unless first verifying compatibility with the subtensor's monkeypatching of scalecodec.RuntimeConfiguration.get_decoder_class shtab==1.6.5 substrate-interface==1.7.5 termcolor diff --git a/scripts/environments/apple_m1_environment.yml b/scripts/environments/apple_m1_environment.yml index a8fcc13f21..530c8625ca 100644 --- a/scripts/environments/apple_m1_environment.yml +++ b/scripts/environments/apple_m1_environment.yml @@ -229,9 +229,7 @@ dependencies: - retry==0.9.2 - rich==12.5.1 - rsa==4.9 - # scalecodec should not be changed unless first verifying compatibility with the subtensor's - # monkeypatching of scalecodec.RuntimeConfiguration.get_decoder_class - - scalecodec==1.2.7 + - scalecodec==1.2.7 # scalecodec should not be changed unless first verifying compatibility with the subtensor's monkeypatching of scalecodec.RuntimeConfiguration.get_decoder_class - scikit-learn==1.2.2 - scipy==1.10.1 - sentencepiece==0.1.99 From 8deab63203796a47af59c69e887edbb964408d2a Mon Sep 17 00:00:00 2001 From: bhimes Date: Thu, 2 May 2024 20:13:27 +0200 Subject: [PATCH 6/8] get_decoder_class can take either a str or a dict. We are only able to cache hashable args, so we need to verify we're only sending strings to the cached function. This does add a bit of overhead (type checking), but is still much faster than without. --- bittensor/subtensor.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/bittensor/subtensor.py b/bittensor/subtensor.py index 18747cd73e..6db6446720 100644 --- a/bittensor/subtensor.py +++ b/bittensor/subtensor.py @@ -96,14 +96,20 @@ ####### # Monkey patch in caching the get_decoder_class method ####### -@functools.lru_cache(maxsize=None) -def patched_get_decoder_class(self, type_string): - return original_get_decoder_class(self, type_string) - - if hasattr(RuntimeConfiguration, "get_decoder_class"): original_get_decoder_class = RuntimeConfiguration.get_decoder_class - RuntimeConfiguration.get_decoder_class = patched_get_decoder_class + + @functools.lru_cache(maxsize=None) + def cached_get_decoder_class(self, type_string): + return original_get_decoder_class(self, type_string) + + def wrapper(self, type_string): + if isinstance(type_string, str): + return cached_get_decoder_class(self, type_string) + else: + return original_get_decoder_class(self, type_string) + + RuntimeConfiguration.get_decoder_class = wrapper ####### From 238668e503e7aeabb1d8c953fbd0980345de9b72 Mon Sep 17 00:00:00 2001 From: bhimes Date: Thu, 2 May 2024 21:00:16 +0200 Subject: [PATCH 7/8] Removed the wrapper, as we only ever send strings. --- bittensor/subtensor.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/bittensor/subtensor.py b/bittensor/subtensor.py index 6db6446720..4e88a00cb6 100644 --- a/bittensor/subtensor.py +++ b/bittensor/subtensor.py @@ -103,13 +103,7 @@ def cached_get_decoder_class(self, type_string): return original_get_decoder_class(self, type_string) - def wrapper(self, type_string): - if isinstance(type_string, str): - return cached_get_decoder_class(self, type_string) - else: - return original_get_decoder_class(self, type_string) - - RuntimeConfiguration.get_decoder_class = wrapper + RuntimeConfiguration.get_decoder_class = cached_get_decoder_class() ####### From 05b2794c6614ca5e68649427160f36bcb00f68ec Mon Sep 17 00:00:00 2001 From: bhimes Date: Thu, 2 May 2024 21:10:14 +0200 Subject: [PATCH 8/8] Removed empty parens --- bittensor/subtensor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bittensor/subtensor.py b/bittensor/subtensor.py index 4e88a00cb6..cf48c219f2 100644 --- a/bittensor/subtensor.py +++ b/bittensor/subtensor.py @@ -103,7 +103,7 @@ def cached_get_decoder_class(self, type_string): return original_get_decoder_class(self, type_string) - RuntimeConfiguration.get_decoder_class = cached_get_decoder_class() + RuntimeConfiguration.get_decoder_class = cached_get_decoder_class #######