Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support reading all configurable attributes from configuration file #176

Merged
merged 4 commits into from
Jul 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,7 @@ wheelhouse
# documents
doc/build
doc/pages

# lsp
.cache
compile_commands.json
4 changes: 1 addition & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@ project(qfvm LANGUAGES CXX C)

if(NOT CMAKE_BUILD_TYPE)
message(STATUS "Build type not set - defaulting to Release")
set(CMAKE_BUILD_TYPE Debug)
set(CMAKE_BUILD_TYPE Release)
endif()
set(CMAKE_BUILD_TYPE Debug)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CUDA_ARCHITECTURES 70;75;80;90)
Expand Down Expand Up @@ -42,7 +41,6 @@ else()
endif()
endif()

list ( APPEND PRJ_COMPILE_OPTIONS -g)
#install eigen
set(EIGEN3_ROOT ${CMAKE_SOURCE_DIR}/thirdparty/Eigen3)
set(EIGEN3_INCLUDE_DIR ${EIGEN3_ROOT}/include/eigen3)
Expand Down
66 changes: 54 additions & 12 deletions quafu/users/userapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.

import json
import os
import warnings
from typing import Optional

from ..exceptions import APITokenNotFound, UserError, validate_server_resp
Expand All @@ -27,6 +29,7 @@ class User(object):
exec_api = "qbackend/scq_kit/"
exec_async_api = "qbackend/scq_kit_asyc/"
exec_recall_api = "qbackend/scq_task_recall/"
backend_type = "quafu"

def __init__(
self, api_token: Optional[str] = None, token_dir: Optional[str] = None
Expand All @@ -45,12 +48,25 @@ def __init__(
self.token_dir = token_dir

if api_token is None:
self._api_token = self._load_account_token()
self._api_token = self._load_account()
else:
self._api_token = api_token

self.priority = 2

@classmethod
def list_configurable_attributes(cls):
"""Return all attributes that are configuratble in configuration file"""
# get all configurable attributes
attributes = [
attr
for attr in list(cls.__dict__.keys())
if not attr.startswith("__")
and not callable(getattr(cls, attr))
and not isinstance(getattr(cls, attr), property)
]
return attributes

@property
def api_token(self):
if self._api_token is None:
Expand All @@ -62,7 +78,7 @@ def api_token(self):

def save_apitoken(self, apitoken=None):
"""
Save api-token associate your Quafu account.
Save the api-token of your Quafu account.
"""
if apitoken is not None:
import warnings
Expand All @@ -75,25 +91,51 @@ def save_apitoken(self, apitoken=None):
self._api_token = apitoken

file_dir = self.token_dir
if not os.path.exists(file_dir):
os.mkdir(file_dir)
with open(file_dir + "api", "w") as f:
f.write(self.api_token + "\n")
f.write(self.url)
file_path = os.path.join(file_dir, "api")

data = None
if os.path.exists(file_path):
# if the configuration file exists
# only update api token
with open(file_path, "r") as f:
data = json.load(f)
data["token"] = self.api_token
else:
# if the configuration file does not exist
# set default configuration for api_token and url
data = {"token": self.api_token, "url": self.url}
if not os.path.exists(file_dir):
os.mkdir(file_dir)

def _load_account_token(self):
with open(file_path, "w") as f:
json.dump(data, f)

def _load_account(self):
"""
Load Quafu account, only api at present.

TODO: expand to load more user information
"""
file_dir = self.token_dir + "api"
file_dir = os.path.join(self.token_dir, "api")
attr_names = self.__class__.list_configurable_attributes()

if not os.path.exists(file_dir):
raise UserError("Please first save api token using `User.save_apitoken()`")
with open(file_dir, "r") as f:
items = f.readlines()
token = items[0].strip()
self.__class__.url = items[1].strip()
try:
data = json.load(f)
token = data["token"]
for attr_name in attr_names:
if attr_name in data:
setattr(self.__class__, attr_name, data[attr_name])
except json.JSONDecodeError:
warnings.warn(
"Deprecated config file format, suggest to fix this warning by running save_apitoken() again"
)
f.seek(0)
items = f.readlines()
token = items[0].strip()
self.__class__.url = items[1].strip()
return token

def _get_backends_info(self):
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
long_description=long_description,
long_description_content_type="text/markdown",
extras_require={"test": ["pytest"]},
cmake_args=["-DCMAKE_BUILD_TYPE:STRING=Debug"],
# cmake_args=["-DCMAKE_BUILD_TYPE:STRING=Debug"],
python_requires=">=3.8",
zip_safe=False,
setup_cfg=True,
Expand Down
2 changes: 1 addition & 1 deletion tests/quafu/algorithms/estimator_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def build_circuit(self):
)
return circ, test_ising

@patch("quafu.users.userapi.User._load_account_token", autospec=True)
@patch("quafu.users.userapi.User._load_account", autospec=True)
@patch("quafu.users.userapi.User.get_available_backends", autospec=True)
@patch("quafu.tasks.tasks.Task.send", autospec=True)
def test_run(self, mock_send, mock_backends, mock_load_account):
Expand Down
Loading