diff --git a/iwrap/generators/actor_generators/muscle3_cpp/resources/Makefile.jinja2 b/iwrap/generators/actor_generators/muscle3_cpp/resources/Makefile.jinja2 index 53c97690..3a66779c 100644 --- a/iwrap/generators/actor_generators/muscle3_cpp/resources/Makefile.jinja2 +++ b/iwrap/generators/actor_generators/muscle3_cpp/resources/Makefile.jinja2 @@ -28,11 +28,7 @@ MUSCLE3_PKG=libmuscle {% endif %} # main IMAS libs to be used -{% if build_info.al_version.startswith('4.') %} -IMAS_LIB_NAME=imas-cpp -{% else %} IMAS_LIB_NAME=al-cpp -{% endif %} CORE_LIBS_FLAGS= $(shell pkg-config --cflags $(IMAS_LIB_NAME) ymmsl $(MUSCLE3_PKG)) CORE_LIBS=$(shell pkg-config --libs $(IMAS_LIB_NAME) ymmsl $(MUSCLE3_PKG)) diff --git a/iwrap/generators/actor_generators/muscle3_cpp/resources/macros/legacy_ids.jinja2 b/iwrap/generators/actor_generators/muscle3_cpp/resources/macros/legacy_ids.jinja2 index 6cd6d23c..cf364d51 100644 --- a/iwrap/generators/actor_generators/muscle3_cpp/resources/macros/legacy_ids.jinja2 +++ b/iwrap/generators/actor_generators/muscle3_cpp/resources/macros/legacy_ids.jinja2 @@ -1,10 +1,5 @@ {% macro imports(al_version) -%} - -{% if al_version.startswith('4.') %} -#include "UALClasses.h" -{% else %} #include "ALClasses.h" -{% endif %} {%- endmacro -%} {% macro declare(ids_name, ids_var_name) -%} diff --git a/iwrap/generators/actor_generators/muscle3_fortran/resources/Makefile.jinja2 b/iwrap/generators/actor_generators/muscle3_fortran/resources/Makefile.jinja2 index 69ed3ba6..9ff3a82d 100644 --- a/iwrap/generators/actor_generators/muscle3_fortran/resources/Makefile.jinja2 +++ b/iwrap/generators/actor_generators/muscle3_fortran/resources/Makefile.jinja2 @@ -42,11 +42,7 @@ MUSCLE3_PKG=libmuscle_fortran {% endif %} # main IMAS libs to be used -{% if build_info.al_version.startswith('4.') %} -IMAS_LIB_NAME=imas-$(FC) -{% else %} IMAS_LIB_NAME=al-fortran -{% endif %} CORE_LIBS_FLAGS:= $(shell pkg-config --cflags $(IMAS_LIB_NAME) ymmsl $(MUSCLE3_PKG)) CORE_LIBS:=$(shell pkg-config --libs $(IMAS_LIB_NAME) ymmsl $(MUSCLE3_PKG)) diff --git a/iwrap/generators/actor_generators/python_actor/resources/common/base_actor.py.jinja2 b/iwrap/generators/actor_generators/python_actor/resources/common/base_actor.py.jinja2 index 607caa30..f435cb7e 100644 --- a/iwrap/generators/actor_generators/python_actor/resources/common/base_actor.py.jinja2 +++ b/iwrap/generators/actor_generators/python_actor/resources/common/base_actor.py.jinja2 @@ -5,7 +5,7 @@ import sys from . import actor_info from .code_parameters import CodeParameters from .definitions import Argument -from .runtime_settings import RuntimeSettings, DebugMode, RunMode +from .runtime_settings import RuntimeSettings, DebugMode, RunMode, SandboxLifeTime from .definitions import Actor from .sandbox import Sandbox from .runners import Runner @@ -39,6 +39,12 @@ class ActorBaseClass(Actor): self.__runtime_settings = runtime_settings self.is_standalone = self.is_standalone_run() + # Standalone actors use persistent IDS storage in the sandbox between calls. + if self.is_standalone and self.__runtime_settings.sandbox.life_time == SandboxLifeTime.ACTOR_RUN: + self.__logger.debug( + "Promoting sandbox lifetime from ACTOR_RUN to WORKFLOW_RUN for standalone actor storage." + ) + self.__runtime_settings.sandbox.life_time = SandboxLifeTime.WORKFLOW_RUN self.sandbox.initialize() self.__initialized = True value = func(self, *args, **kwargs ) diff --git a/iwrap/generators/actor_generators/python_actor/resources/common/runtime_settings.py b/iwrap/generators/actor_generators/python_actor/resources/common/runtime_settings.py index bbaceeba..330a9fa5 100644 --- a/iwrap/generators/actor_generators/python_actor/resources/common/runtime_settings.py +++ b/iwrap/generators/actor_generators/python_actor/resources/common/runtime_settings.py @@ -69,20 +69,19 @@ class IdsStorageSettings: """Settings of temporary storage being used while passing IDSes between the actor and the code. Attributes: - db_name (str, default='tmp'): name of the database to be used - backend (str, default=imas.ids_defs.MEMORY_BACKEND): backend to be used - persistent_backend (str, default=imas.ids_defs.MDSPLUS_BACKEND): backend to be used when temporary data - cannot be stored in memory (e.g. while running actor in a standalone mode, - when the code is run as separate process, so it doesn’t share memory with other actors. + backend (int, default=imas.ids_defs.MEMORY_BACKEND): backend to be used + persistent_backend (int, default=imas.ids_defs.HDF5_BACKEND): backend to be used when + temporary data cannot be stored in memory (e.g. while running actor in a standalone + mode, when the code is run as separate process, so it doesn't share memory with other + actors). The sandbox directory is used as the data path via an IMAS URI. """ # Class logger __logger = logging.getLogger(__name__ + "." + __qualname__) def __init__(self): - self.db_name = "tmp" self.backend = imas.ids_defs.MEMORY_BACKEND - self.persistent_backend = imas.ids_defs.MDSPLUS_BACKEND + self.persistent_backend = imas.ids_defs.HDF5_BACKEND class RuntimeSettings: diff --git a/iwrap/generators/binder_generators/python/common/data_storages/data_descriptions.py b/iwrap/generators/binder_generators/python/common/data_storages/data_descriptions.py index ef1b8c3f..7d3f0f17 100644 --- a/iwrap/generators/binder_generators/python/common/data_storages/data_descriptions.py +++ b/iwrap/generators/binder_generators/python/common/data_storages/data_descriptions.py @@ -1,48 +1,24 @@ class IDSDescription: - @property - def uri(self): - uri = ( - f"imas:{self.backend_id}" - f"?user={self.user};database={self.database};version={self.version};" - f"shot={self.shot};run={self.run};idx={self.idx}" - f"#{self.ids_type}:{self.occurrence}" - ) - return uri + """Identifies a single IDS inside an IMAS data entry using URI.""" - def __init__(self, db_entry, ids_name, occurrence): - self.backend_id = db_entry.backend_id - self.user = db_entry.user_name - self.database = db_entry.db_name - self.version = db_entry.dd_version[0] if db_entry.dd_version else "" - try: - self.pulse = db_entry.pulse - except AttributeError: - self.pulse = db_entry.shot - self.run = db_entry.run - self.idx = db_entry._dbe_impl._db_ctx.ctx + def __init__(self, base_uri: str, ids_name: str, occurrence: int): + self.base_uri = base_uri self.ids_type = ids_name self.occurrence = occurrence self.intent = None + @property + def uri(self) -> str: + """IMAS URI including IDS type and occurrence fragment.""" + return f"{self.base_uri}#{self.ids_type}:{self.occurrence}" + def save(self, stream): stream.write("------- IDS -------\n") stream.write(self.ids_type) stream.write("\n") - stream.write(str(self.pulse)) - stream.write("\n") - stream.write(str(self.run)) - stream.write("\n") stream.write(str(self.occurrence)) stream.write("\n") - stream.write(str(self.backend_id)) - stream.write("\n") - stream.write(str(self.idx)) - stream.write("\n") - stream.write(self.database) - stream.write("\n") - stream.write(self.user) - stream.write("\n") - stream.write(self.version) + stream.write(self.base_uri) stream.write("\n") def convert_to_native_type(self): diff --git a/iwrap/generators/binder_generators/python/common/data_storages/ids_converter.py b/iwrap/generators/binder_generators/python/common/data_storages/ids_converter.py index eaca7b89..2d5edb35 100644 --- a/iwrap/generators/binder_generators/python/common/data_storages/ids_converter.py +++ b/iwrap/generators/binder_generators/python/common/data_storages/ids_converter.py @@ -23,12 +23,11 @@ def initialize( storage_settings: IdsStorageSettings, ) -> None: - db_name = storage_settings.db_name if is_standalone: backend_id = storage_settings.persistent_backend else: backend_id = storage_settings.backend - self.__data_storage.initialize(sandbox_dir, db_name, backend_id) + self.__data_storage.initialize(sandbox_dir, backend_id) def finalize(self) -> None: self.__data_storage.finalize() @@ -71,5 +70,8 @@ def convert_to_actor_type(self, ids_description: IDSDescription): ids = self.__data_storage.read_data(ids_description) return ids + def sync_for_external_access(self): + self.__data_storage.sync_for_external_access() + def release(self, ids_description: IDSDescription): self.__data_storage.release_data(ids_description.ids_type) diff --git a/iwrap/generators/binder_generators/python/common/data_storages/legacy_storage.py b/iwrap/generators/binder_generators/python/common/data_storages/legacy_storage.py index a7ef9932..d0506d0e 100644 --- a/iwrap/generators/binder_generators/python/common/data_storages/legacy_storage.py +++ b/iwrap/generators/binder_generators/python/common/data_storages/legacy_storage.py @@ -1,20 +1,22 @@ -from pathlib import Path - import imas from .data_descriptions import IDSDescription from .generic_storage import GenericIDSStorage +_BACKEND_NAMES = { + imas.ids_defs.MEMORY_BACKEND: "memory", + imas.ids_defs.HDF5_BACKEND: "hdf5", + imas.ids_defs.MDSPLUS_BACKEND: "mdsplus", + imas.ids_defs.ASCII_BACKEND: "ascii", +} + class LegacyIDSStorage(GenericIDSStorage): def __init__(self): self.__occ_dict = {} self.__db_entry = None - self.__backend_id: int = -1 - self.__db_name: str = "" - self.__pulse: int = -1 - self.__run: int = -1 - self.__sandbox_dir: str = "" + self.__uri: str = "" + self.__backend_name: str = "" def __get_occurrence(self, ids_name): occ = 1 + self.__occ_dict.get(ids_name, -1) @@ -25,86 +27,48 @@ def __release_occurrence(self, ids_name): occ = self.__occ_dict.get(ids_name, 1) self.__occ_dict[ids_name] = occ - 1 - def __open_db(self): - if self.__backend_id == imas.ids_defs.MEMORY_BACKEND: - return - - try: - self.__db_entry.open() - except Exception as e: - raise RuntimeError( - f"Error opening the temporary DB:\n" - f" backend = {self.__backend_id}\n" - f" name = {self.__db_name}\n" - f" pulse = {self.__pulse}\n" - f" run = {self.__run}\n" - f" dir = {self.__sandbox_dir}\n" - f"Original exception: {e}" - ) from e - - def __close_db(self): - if self.__backend_id == imas.ids_defs.MEMORY_BACKEND: - return - self.__db_entry.close() - - def initialize(self, sandbox_dir: str, db_name: str, backend_id): + def initialize(self, sandbox_dir: str, backend_id: int): + backend_name = _BACKEND_NAMES.get(backend_id) + if backend_name is None: + raise ValueError( + f"Unsupported backend_id {backend_id}. " + f"Supported backends: {list(_BACKEND_NAMES.keys())}" + ) - self.__pulse = 1 - self.__run = 1 - self.__backend_id = backend_id - self.__db_name = db_name - self.__sandbox_dir = sandbox_dir + self.__uri = f"imas:{backend_name}?path={sandbox_dir}" + self.__backend_name = backend_name - Path(sandbox_dir, "tmp", "3", "0").mkdir(parents=True, exist_ok=True) - - self.__db_entry = imas.DBEntry( # pylint: disable=no-member - backend_id=self.__backend_id, # backend_id - db_name=self.__db_name, # db_name - pulse=self.__pulse, # shot / pulse - run=self.__run, # run - user_name=self.__sandbox_dir, # AL hack to use sandbox dir - ) try: - self.__db_entry.create() + self.__db_entry = imas.DBEntry(self.__uri, "w") except Exception as e: raise RuntimeError( f"Error creating the temporary DB:\n" - f" backend = {self.__backend_id}\n" - f" name = {self.__db_name}\n" - f" pulse = {self.__pulse}\n" - f" run = {self.__run}\n" - f" dir = {self.__sandbox_dir}\n" + f" uri = {self.__uri}\n" f"Original exception: {e}" ) from e - self.__close_db() - def prepare_data(self, ids_name): occurrence = self.__get_occurrence(ids_name) - self.__open_db() - ids_description = IDSDescription(self.__db_entry, ids_name, occurrence) - self.__close_db() - return ids_description + return IDSDescription(self.__uri, ids_name, occurrence) def save_data(self, ids_description: IDSDescription, legacy_ids): - self.__open_db() self.__db_entry.put(legacy_ids, ids_description.occurrence) - self.__close_db() - def read_data(self, ids_description: IDSDescription): - self.__open_db() - legacy_ids = self.__db_entry.get( - ids_description.ids_type, ids_description.occurrence - ) - self.__close_db() + def sync_for_external_access(self): + # External standalone processes must own persistent backends while they run. + if self.__backend_name != "memory" and self.__db_entry is not None: + self.__db_entry.close() + self.__db_entry = None - return legacy_ids + def read_data(self, ids_description: IDSDescription): + if self.__db_entry is None: + self.__db_entry = imas.DBEntry(self.__uri, "a") + return self.__db_entry.get(ids_description.ids_type, ids_description.occurrence) def release_data(self, ids_name): self.__release_occurrence(ids_name) def finalize(self): - try: - self.__db_entry.close(erase=True) - except Exception: + if self.__db_entry is not None: self.__db_entry.close() + self.__db_entry = None diff --git a/iwrap/generators/binder_generators/python/cpp_binding/resources/binder.py b/iwrap/generators/binder_generators/python/cpp_binding/resources/binder.py index c4d0b1ef..fc3f24d8 100644 --- a/iwrap/generators/binder_generators/python/cpp_binding/resources/binder.py +++ b/iwrap/generators/binder_generators/python/cpp_binding/resources/binder.py @@ -196,6 +196,7 @@ def run_standalone( # prepares input files Binder.save_input(method_name, ids_ctypes_list, param_ctype, sandbox_dir) + self.ids_converter.sync_for_external_access() self.__logger.debug("EXECUTING command: " + str(exec_command)) exec_system_cmd(exec_command, output_stream=output_stream) diff --git a/iwrap/generators/binder_generators/python/cpp_binding/resources/data_c_binding.py b/iwrap/generators/binder_generators/python/cpp_binding/resources/data_c_binding.py index ec9ed960..5034189e 100644 --- a/iwrap/generators/binder_generators/python/cpp_binding/resources/data_c_binding.py +++ b/iwrap/generators/binder_generators/python/cpp_binding/resources/data_c_binding.py @@ -8,62 +8,38 @@ class IDSCType(ctypes.Structure, IDSDescription): _fields_ = ( ("ids_type_", ctypes.c_byte * 132), - ("pulse", ctypes.c_int), - ("run", ctypes.c_int), ("occurrence", ctypes.c_int), - ("backend_id", ctypes.c_int), - ("idx", ctypes.c_int), - ("database_", ctypes.c_byte * 132), - ("user_", ctypes.c_byte * 132), - ("version_", ctypes.c_byte * 132), + ("uri_", ctypes.c_byte * 4096), ) @property def ids_type(self): - return "".join((chr(x) for x in self.ids_type_[:])).strip() + return bytes(self.ids_type_).split(b"\0", 1)[0].decode("ascii") @ids_type.setter def ids_type(self, ids_type_): - self.ids_type_[:] = len(self.ids_type_) * [ord(" ")] - self.ids_type_[: len(ids_type_)] = [ord(x) for x in ids_type_] + encoded = ids_type_.encode("ascii") + if len(encoded) >= ctypes.sizeof(self.ids_type_): + raise ValueError(f"IDS type is too long for C buffer: {ids_type_}") + ctypes.memset(self.ids_type_, 0, ctypes.sizeof(self.ids_type_)) + ctypes.memmove(self.ids_type_, encoded, len(encoded)) @property - def database(self): - return "".join((chr(x) for x in self.database_[:])).strip() + def base_uri(self): + return bytes(self.uri_).split(b"\0", 1)[0].decode("ascii") - @database.setter - def database(self, database_): - self.database_[:] = len(self.database_) * [ord(" ")] - self.database_[: len(database_)] = [ord(x) for x in database_] - - @property - def user(self): - return "".join((chr(x) for x in self.user_[:])).strip() - - @user.setter - def user(self, user_): - self.user_[:] = len(self.user_) * [ord(" ")] - self.user_[: len(user_)] = [ord(x) for x in user_] - - @property - def version(self): - return "".join((chr(x) for x in self.version_[:])).strip() - - @version.setter - def version(self, version_): - self.version_[:] = len(self.version_) * [ord(" ")] - self.version_[: len(version_)] = [ord(x) for x in version_] + @base_uri.setter + def base_uri(self, uri_): + encoded = uri_.encode("ascii") + if len(encoded) >= ctypes.sizeof(self.uri_): + raise ValueError(f"URI is too long for C buffer: {uri_}") + ctypes.memset(self.uri_, 0, ctypes.sizeof(self.uri_)) + ctypes.memmove(self.uri_, encoded, len(encoded)) def __init__(self, ids_description: IDSDescription): self.ids_type = ids_description.ids_type - self.pulse = ids_description.pulse - self.run = ids_description.run self.occurrence = ids_description.occurrence - self.backend_id = ids_description.backend_id - self.idx = ids_description.idx - self.database = ids_description.database - self.user = ids_description.user - self.version = ids_description.version + self.base_uri = ids_description.base_uri def convert_to_native_type(self): return ctypes.byref(self) diff --git a/iwrap/generators/binder_generators/python/java_binding/resources/binder.py b/iwrap/generators/binder_generators/python/java_binding/resources/binder.py index 97c826c3..dfbf140a 100644 --- a/iwrap/generators/binder_generators/python/java_binding/resources/binder.py +++ b/iwrap/generators/binder_generators/python/java_binding/resources/binder.py @@ -185,6 +185,7 @@ def run_standalone( # prepares input files Binder.save_input(method_name, ids_ctypes_list, param_ctype, sandbox_dir) + self.ids_converter.sync_for_external_access() self.__logger.debug("EXECUTING command: " + str(exec_command)) exec_system_cmd(exec_command, output_stream=output_stream) diff --git a/iwrap/generators/binder_generators/python/java_binding/resources/data_j_binding.py b/iwrap/generators/binder_generators/python/java_binding/resources/data_j_binding.py index 592fe7e1..5d4644d6 100644 --- a/iwrap/generators/binder_generators/python/java_binding/resources/data_j_binding.py +++ b/iwrap/generators/binder_generators/python/java_binding/resources/data_j_binding.py @@ -10,27 +10,15 @@ class JavaIDSDescription(IDSDescription): def __init__(self, ids_description: IDSDescription): self.ids_description_class = JClass("IDSDescription") self.ids_type = ids_description.ids_type - self.pulse = ids_description.pulse - self.run = ids_description.run self.occurrence = ids_description.occurrence - self.backend_id = ids_description.backend_id - self.idx = ids_description.idx - self.database = ids_description.database - self.user = ids_description.user - self.version = ids_description.version + self.base_uri = ids_description.base_uri def convert_to_native_type(self): java_ids_description = self.ids_description_class() java_ids_description.ids_type = self.ids_type - java_ids_description.pulse = self.pulse - java_ids_description.run = self.run java_ids_description.occurrence = self.occurrence - java_ids_description.backend_id = self.backend_id - java_ids_description.idx = self.idx - java_ids_description.database = self.database - java_ids_description.user = self.user - java_ids_description.version = self.version + java_ids_description.uri = self.base_uri return java_ids_description diff --git a/iwrap/generators/wrapper_generators/cpp_wrapper/resources/Makefile.jinja2 b/iwrap/generators/wrapper_generators/cpp_wrapper/resources/Makefile.jinja2 index f95df8bb..7b189e59 100644 --- a/iwrap/generators/wrapper_generators/cpp_wrapper/resources/Makefile.jinja2 +++ b/iwrap/generators/wrapper_generators/cpp_wrapper/resources/Makefile.jinja2 @@ -14,22 +14,14 @@ WRAPPER_DIR=$(dir $(realpath $(firstword $(MAKEFILE_LIST)))) COMPILER_FLAGS={{ code_description.settings.compiler_flags or '' }} -{% if build_info.al_version.startswith('4.') %} -AL_MAJOR=4 -{% else %} AL_MAJOR=5 -{% endif %} CXXFLAGS= -g -fpic -pthread $(COMPILER_FLAGS) -DAL_MAJOR=${AL_MAJOR} CODE_LIB_FILE=$(notdir {{code_description.implementation.code_path}}) CODE_LIB_DEF=./lib/$(CODE_LIB_FILE) # main IMAS libs to be used -{% if build_info.al_version.startswith('4.') %} -IMAS_LIB_NAME=imas-cpp -{% else %} IMAS_LIB_NAME=al-cpp -{% endif %} CORE_LIBS_FLAGS= $(shell pkg-config --cflags $(IMAS_LIB_NAME)) CORE_LIBS=$(shell pkg-config --libs $(IMAS_LIB_NAME)) diff --git a/iwrap/generators/wrapper_generators/cpp_wrapper/resources/macros/legacy_ids.jinja2 b/iwrap/generators/wrapper_generators/cpp_wrapper/resources/macros/legacy_ids.jinja2 index f9af9e04..3d3e1b12 100644 --- a/iwrap/generators/wrapper_generators/cpp_wrapper/resources/macros/legacy_ids.jinja2 +++ b/iwrap/generators/wrapper_generators/cpp_wrapper/resources/macros/legacy_ids.jinja2 @@ -1,10 +1,5 @@ {% macro imports(al_version) -%} - -{% if al_version.startswith('4.') %} -#include "UALClasses.h" -{% else %} #include "ALClasses.h" -{% endif %} {%- endmacro -%} {% macro declare(ids_name, ids_var_name) -%} @@ -14,11 +9,19 @@ IdsNs::IDS::{{ ids_name }}* {{ ids_var_name }} = &db_entry_{{ ids_var_name }}->_{{ ids_name }}; {%- endmacro -%} +{% macro declare_local(ids_name, ids_var_name) -%} + IdsNs::IDS::{{ ids_name }} {{ ids_var_name }}_local; + IdsNs::IDS::{{ ids_name }}* {{ ids_var_name }} = &{{ ids_var_name }}_local; + IdsNs::IDS *db_entry_{{ ids_var_name }} = nullptr; +{%- endmacro -%} + +{% macro attach_db(ids_name, ids_var_name) -%} + db_entry_{{ ids_var_name }} = init_db({{ ids_var_name }}_desc); + {{ ids_var_name }} = &db_entry_{{ ids_var_name }}->_{{ ids_name }}; +{%- endmacro -%} + {% macro get(ids_var_name) -%} - open_db(db_entry_{{ ids_var_name }}, {{ ids_var_name }}_desc); - {{ ids_var_name }}->setPulseCtx(db_entry_{{ ids_var_name }}->getPulseCtx()); {{ ids_var_name }}->get({{ ids_var_name }}_desc->occurrence); - close_db(db_entry_{{ ids_var_name }}); {%- endmacro -%} {%- macro provenance(ids_var_name, sbrt_data, code_parameters) -%} @@ -28,13 +31,15 @@ {%- endmacro -%} {% macro put(ids_var_name) -%} - open_db(db_entry_{{ ids_var_name }}, {{ ids_var_name }}_desc); {{ ids_var_name }}->put({{ ids_var_name }}_desc->occurrence); - close_db(db_entry_{{ ids_var_name }}); {%- endmacro -%} {% macro deallocate(ids_var_name) -%} // Should not be called until IMAS-3937 will be resolved // {{ ids_var_name }}->clear(); - delete db_entry_{{ ids_var_name }}; + if (db_entry_{{ ids_var_name }} != nullptr && std::string({{ ids_var_name }}_desc->uri).rfind("imas:memory?", 0) != 0) + { + close_db(db_entry_{{ ids_var_name }}); + delete db_entry_{{ ids_var_name }}; + } {%- endmacro -%} diff --git a/iwrap/generators/wrapper_generators/cpp_wrapper/resources/macros/subroutines.jinja2 b/iwrap/generators/wrapper_generators/cpp_wrapper/resources/macros/subroutines.jinja2 index c43a3b72..73344280 100644 --- a/iwrap/generators/wrapper_generators/cpp_wrapper/resources/macros/subroutines.jinja2 +++ b/iwrap/generators/wrapper_generators/cpp_wrapper/resources/macros/subroutines.jinja2 @@ -23,9 +23,25 @@ extern "C" void {{actor_name | lower}}_wrapper_{{ sbrt_role | lower }}( { std:string status_msg = "OK"; +{% if mpi_compiler_cmd %} + //---- MPI ---- + int mpi_rank; + int was_mpi_initialized, was_mpi_finalized; + + MPI_Initialized(&was_mpi_initialized); + if (!was_mpi_initialized) + MPI_Init(NULL, NULL); + MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank); + +{% endif %} + {% for argument in sbrt_data.arguments %} // IDS : {{ argument.name }} ------------------------ +{% if mpi_compiler_cmd %} + {{ ids_macro.declare_local(argument.type, argument.name ) }} +{% else %} {{ ids_macro.declare(argument.type, argument.name ) }} +{% endif %} {% endfor %} {% if code_parameters.parameters and sbrt_data.need_code_parameters %} @@ -38,18 +54,18 @@ extern "C" void {{actor_name | lower}}_wrapper_{{ sbrt_role | lower }}( {% endif %} - {% if mpi_compiler_cmd %} - //---- MPI ---- - int mpi_rank; - int was_mpi_initialized, was_mpi_finalized; - - MPI_Initialized(&was_mpi_initialized); - if (!was_mpi_initialized) - MPI_Init(NULL, NULL); - MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank); +{% if mpi_compiler_cmd %} + {% for argument in sbrt_data.arguments if argument.intent == 'IN' %} + {{ ids_macro.attach_db(argument.type, argument.name ) }} + {% endfor %} + {% for argument in sbrt_data.arguments if argument.intent == 'OUT' %} + if (mpi_rank == 0) + { + {{ ids_macro.attach_db(argument.type, argument.name ) }} + } + {% endfor %} {% endif %} - {% for argument in sbrt_data.arguments if argument.intent == 'IN' %} //--------- Get IDS : {{ argument.name }} ------------------------ {{ ids_macro.get( argument.name) }} @@ -103,8 +119,15 @@ extern "C" void {{actor_name | lower}}_wrapper_{{ sbrt_role | lower }}( {% endif %} {% for argument in sbrt_data.arguments %} - //--------- PUT IDS : {{ argument.name }} ------------------------ + //--------- RELEASE IDS : {{ argument.name }} ------------------------ +{% if mpi_compiler_cmd and argument.intent == 'OUT' %} + if (mpi_rank == 0) + { + {{ ids_macro.deallocate( argument.name) }} + } +{% else %} {{ ids_macro.deallocate( argument.name) }} +{% endif %} {% endfor %} diff --git a/iwrap/generators/wrapper_generators/cpp_wrapper/resources/src/defs.h b/iwrap/generators/wrapper_generators/cpp_wrapper/resources/src/defs.h index 7acdc0f8..59b7e68f 100644 --- a/iwrap/generators/wrapper_generators/cpp_wrapper/resources/src/defs.h +++ b/iwrap/generators/wrapper_generators/cpp_wrapper/resources/src/defs.h @@ -6,14 +6,8 @@ const int MPI_ROOT_RANK = 0; typedef struct { char ids_name[132]; - int pulse; - int run; int occurrence; - int backend_id; - int idx; - char db_name[132]; - char user[132]; - char version[132]; + char uri[4096]; } ids_description_t; #endif // _DEFS diff --git a/iwrap/generators/wrapper_generators/cpp_wrapper/resources/src/iwrap_tools.cpp b/iwrap/generators/wrapper_generators/cpp_wrapper/resources/src/iwrap_tools.cpp index 6b9e0e9b..b302e514 100644 --- a/iwrap/generators/wrapper_generators/cpp_wrapper/resources/src/iwrap_tools.cpp +++ b/iwrap/generators/wrapper_generators/cpp_wrapper/resources/src/iwrap_tools.cpp @@ -6,33 +6,6 @@ #include "iwrap_tools.h" #include "serialization_tools.h" - -char* iwrap_trim(char* text, int text_size = -1) -{ - - int size = -1; - - if (*text == '\0') - return text; - - char* last_char_ptr = text + strlen(text) -1; - - if (text_size > 0) - size = text_size; - else - size = strlen(text); - - last_char_ptr = text + size -1; - - while(last_char_ptr >= text && isspace(*last_char_ptr)) - { - *last_char_ptr = '\0'; - last_char_ptr--; - } - - return text; -} - int read_input(const char* file_name, ids_description_t db_entry_desc_array[], int array_expected_size) { ifstream fin; @@ -136,46 +109,19 @@ void convert_status_info(std::string in_status_msg, char** out_status_msg) IdsNs::IDS* init_db(ids_description_t* db_entry_desc) { - IdsNs::IDS* db_entry = NULL; - - if ( db_entry_desc->backend_id == MEMORY_BACKEND){ - db_entry = new IdsNs::IDS(db_entry_desc->idx); - } else { - db_entry = new IdsNs::IDS(db_entry_desc->pulse, db_entry_desc->run, 0, 0); - } - + IdsNs::IDS* db_entry = new IdsNs::IDS(); + db_entry->open(db_entry_desc->uri, FORCE_OPEN_PULSE); return db_entry; - } +} int open_db(IdsNs::IDS* db_entry, ids_description_t* db_entry_desc) { - char* user = NULL; - char* db_name = NULL; - char* version = NULL; - - - if ( db_entry_desc->backend_id == MEMORY_BACKEND){ - db_entry->setPulseCtx(db_entry_desc->idx); - }else{ - user = iwrap_trim(db_entry_desc->user, sizeof db_entry_desc->user); - db_name = iwrap_trim(db_entry_desc->db_name, sizeof db_entry_desc->db_name); - version = iwrap_trim(db_entry_desc->version, sizeof db_entry_desc->version); - - db_entry->setBackend(static_cast(db_entry_desc->backend_id)); - db_entry->openEnv(user, db_name, version); - } - return 0; - } +} void close_db(IdsNs::IDS* db_entry) { - if ( db_entry->getBackend() == MEMORY_BACKEND) - { - return; - } - db_entry->close(); } diff --git a/iwrap/generators/wrapper_generators/cpp_wrapper/resources/src/iwrap_tools.h b/iwrap/generators/wrapper_generators/cpp_wrapper/resources/src/iwrap_tools.h index 0209f3a9..e97d5c64 100644 --- a/iwrap/generators/wrapper_generators/cpp_wrapper/resources/src/iwrap_tools.h +++ b/iwrap/generators/wrapper_generators/cpp_wrapper/resources/src/iwrap_tools.h @@ -3,13 +3,8 @@ #include "defs.h" -{% if build_info.al_version.startswith('4.') %} - #include "UALClasses.h" -{% else %} - #include "ALClasses.h" -{% endif %} +#include "ALClasses.h" -char* iwrap_trim(char* text, int text_size); int read_input(const char* file_name, ids_description_t db_entry_desc_array[], int array_expected_size); diff --git a/iwrap/generators/wrapper_generators/cpp_wrapper/resources/src/serialization_tools.cpp b/iwrap/generators/wrapper_generators/cpp_wrapper/resources/src/serialization_tools.cpp index 26d319df..5366c169 100644 --- a/iwrap/generators/wrapper_generators/cpp_wrapper/resources/src/serialization_tools.cpp +++ b/iwrap/generators/wrapper_generators/cpp_wrapper/resources/src/serialization_tools.cpp @@ -8,15 +8,9 @@ void read_data(std::ifstream *stream, ids_description_t *ids_description) { stream->ignore(INT_MAX, '\n'); *stream >> ids_description->ids_name; - *stream >> ids_description->pulse; - *stream >> ids_description->run; *stream >> ids_description->occurrence; - *stream >> ids_description->backend_id; - *stream >> ids_description->idx; - *stream >> ids_description->db_name; - *stream >> ids_description->user; - *stream >> ids_description->version; stream->ignore(INT_MAX, '\n'); + stream->getline(ids_description->uri, sizeof(ids_description->uri)); } void read_data(std::ifstream *stream, int *var) { diff --git a/iwrap/generators/wrapper_generators/fortran_wrapper/resources/Makefile.jinja2 b/iwrap/generators/wrapper_generators/fortran_wrapper/resources/Makefile.jinja2 index 1f525b0e..873ebd44 100644 --- a/iwrap/generators/wrapper_generators/fortran_wrapper/resources/Makefile.jinja2 +++ b/iwrap/generators/wrapper_generators/fortran_wrapper/resources/Makefile.jinja2 @@ -26,11 +26,7 @@ CODE_LIB_FILE=$(notdir {{code_description.implementation.code_path}}) CODE_LIB_DEF=./lib/$(CODE_LIB_FILE) # main IMAS libs to be used -{% if build_info.al_version.startswith('4.') %} -IMAS_LIB_NAME=imas-$(FC) -{% else %} IMAS_LIB_NAME=al-fortran -{% endif %} CORE_LIBS_FLAGS:= $(shell pkg-config --cflags "$(IMAS_LIB_NAME)") CORE_LIBS:=$(shell pkg-config --libs "$(IMAS_LIB_NAME)") @@ -84,6 +80,8 @@ build/%.o: src/%.f90 @mkdir -p ./build $(FC) $(FFLAGS) -O0 -c -w $^ -o $@ $(INCLUDES) +build/RWTools.o: build/defs.o build/iwrap_converters.o + ../lib/lib$(ACTOR_NAME).so: build/defs.o build/RWTools.o build/iwrap_converters.o build/fortrantools.o build/fortran_wrapper.o @echo " * $^ -> $@" @mkdir -p ../lib diff --git a/iwrap/generators/wrapper_generators/fortran_wrapper/resources/macros/legacy_ids.jinja2 b/iwrap/generators/wrapper_generators/fortran_wrapper/resources/macros/legacy_ids.jinja2 index fac52178..da7293fc 100644 --- a/iwrap/generators/wrapper_generators/fortran_wrapper/resources/macros/legacy_ids.jinja2 +++ b/iwrap/generators/wrapper_generators/fortran_wrapper/resources/macros/legacy_ids.jinja2 @@ -9,10 +9,8 @@ {%- endmacro -%} {% macro get(ids_var_name) -%} - call open_db( {{ ids_var_name }}_desc, idx, status_code) ids_full_name = create_ids_full_name({{ ids_var_name }}_desc) call ids_get(idx, ids_full_name, {{ ids_var_name }}) - call close_db( {{ ids_var_name }}_desc, idx) {%- endmacro -%} {%- macro provenance(ids_var_name, sbrt_data, code_parameters) -%} @@ -27,10 +25,8 @@ {%- endmacro -%} {% macro put(ids_var_name) -%} - call open_db( {{ ids_var_name }}_desc, idx, status_code) ids_full_name = create_ids_full_name({{ ids_var_name }}_desc) call ids_put(idx, ids_full_name, {{ ids_var_name }}) - call close_db( {{ ids_var_name }}_desc, idx) {%- endmacro -%} {% macro deallocate(ids_var_name) -%} diff --git a/iwrap/generators/wrapper_generators/fortran_wrapper/resources/macros/subroutines.jinja2 b/iwrap/generators/wrapper_generators/fortran_wrapper/resources/macros/subroutines.jinja2 index 239436aa..e6d574ef 100644 --- a/iwrap/generators/wrapper_generators/fortran_wrapper/resources/macros/subroutines.jinja2 +++ b/iwrap/generators/wrapper_generators/fortran_wrapper/resources/macros/subroutines.jinja2 @@ -55,6 +55,12 @@ SUBROUTINE {{actor_name | lower}}_wrapper_{{ sbrt_role | lower }}(& nullify(status_msg) status_code = 0 +{% if sbrt_data.arguments %} + !--------- Open DB (once for all IDSes) -------- + call open_db({{ sbrt_data.arguments[0].name }}_desc, idx, status_code) + if (status_code /= 0) RETURN +{% endif %} + {% for argument in sbrt_data.arguments if argument.intent == 'IN' %} !--------- Get IDS : {{ argument.name }} ------------------------ {{ ids_macro.get( argument.name) }} @@ -114,6 +120,11 @@ SUBROUTINE {{actor_name | lower}}_wrapper_{{ sbrt_role | lower }}(& {{ ids_macro.deallocate( argument.name) }} {% endfor %} +{% if sbrt_data.arguments %} + !--------- Close DB (once for all IDSes) -------- + call close_db({{ sbrt_data.arguments[0].name }}_desc, idx) +{% endif %} + {% if code_parameters.parameters and sbrt_data.need_code_parameters and ('legacy' in code_parameters.format)%} ! ------Deallocating code parameters ---------------------------- deallocate(imas_code_params%parameters_value) diff --git a/iwrap/generators/wrapper_generators/fortran_wrapper/resources/src/RWTools.f90 b/iwrap/generators/wrapper_generators/fortran_wrapper/resources/src/RWTools.f90 index 99b15215..bd8884a5 100644 --- a/iwrap/generators/wrapper_generators/fortran_wrapper/resources/src/RWTools.f90 +++ b/iwrap/generators/wrapper_generators/fortran_wrapper/resources/src/RWTools.f90 @@ -1,5 +1,6 @@ module rwtool use iwrap_defs + use iwrap_converters interface readfile module procedure & @@ -24,14 +25,8 @@ subroutine readids(ids_description) read(10,*) ! skip line " ----- IDS ----- " call read_chars( ids_description%ids_name) - read(10,*) ids_description%pulse - read(10,*) ids_description%run read(10,*) ids_description%occurrence - read(10,*) ids_description%backend_id - read(10,*) ids_description%idx - call read_chars( ids_description%db_name) - call read_chars( ids_description%user) - call read_chars( ids_description%version) + call read_uri( ids_description%uri) end subroutine @@ -40,6 +35,24 @@ subroutine readint(var) read(10,*) var end subroutine + !--------------------------------------------------- + subroutine read_uri(var) + implicit none + character(kind=c_char), dimension(:), intent(inout) :: var + integer :: i + integer :: line_size + character(AL_URI_SIZE) :: line + + var(:) = char(0) + read(10,"(a)") line + + line_size = min(len_trim(line), size(var) - 1, AL_URI_SIZE) + do i = 1, line_size + var(i) = line(i : i) + enddo + + end subroutine + !--------------------------------------------------- subroutine read_chars(var) implicit none @@ -154,14 +167,8 @@ subroutine writeids(ids_description) implicit none type(ids_description_t), intent(in) :: ids_description write(10,*) ids_description%ids_name - write(10,*) ids_description%pulse - write(10,*) ids_description%run write(10,*) ids_description%occurrence - write(10,*) ids_description%backend_id - write(10,*) ids_description%idx - write(10,*) ids_description%db_name - write(10,*) ids_description%user - write(10,*) ids_description%version + write(10,"(a)") convert_array2string(ids_description%uri) end subroutine !--------------------------------------------------- diff --git a/iwrap/generators/wrapper_generators/fortran_wrapper/resources/src/defs.f90 b/iwrap/generators/wrapper_generators/fortran_wrapper/resources/src/defs.f90 index 4268a070..a5db99d9 100644 --- a/iwrap/generators/wrapper_generators/fortran_wrapper/resources/src/defs.f90 +++ b/iwrap/generators/wrapper_generators/fortran_wrapper/resources/src/defs.f90 @@ -5,17 +5,12 @@ module iwrap_defs !-------------------------------------------------- integer, parameter :: AL_STRING_SIZE = ids_string_length + integer, parameter :: AL_URI_SIZE = 4096 type, BIND(C) :: ids_description_t - character(kind=c_char)::ids_name(AL_STRING_SIZE) - integer::pulse - integer::run - integer::occurrence - integer::backend_id - integer::idx - character(kind=c_char)::db_name(AL_STRING_SIZE) - character(kind=c_char)::user(AL_STRING_SIZE) - character(kind=c_char)::version(AL_STRING_SIZE) + character(kind=c_char) :: ids_name(AL_STRING_SIZE) + integer(c_int) :: occurrence + character(kind=c_char) :: uri(AL_URI_SIZE) end type ids_description_t !-------------------------------------------------- end module diff --git a/iwrap/generators/wrapper_generators/fortran_wrapper/resources/src/fortrantools.f90 b/iwrap/generators/wrapper_generators/fortran_wrapper/resources/src/fortrantools.f90 index 59395a41..de71afe9 100644 --- a/iwrap/generators/wrapper_generators/fortran_wrapper/resources/src/fortrantools.f90 +++ b/iwrap/generators/wrapper_generators/fortran_wrapper/resources/src/fortrantools.f90 @@ -121,46 +121,6 @@ SUBROUTINE write_output(file_name, status_code, status_message) END SUBROUTINE write_output -{% if build_info.al_version.startswith('4.') %} - - - SUBROUTINE open_db(db_entry_desc, idx, status) - use ual_low_level_wrap - - type(ids_description_t), intent(IN) :: db_entry_desc - INTEGER, INTENT(OUT) :: idx - INTEGER, INTENT(OUT) :: status - - if (db_entry_desc%backend_id == MEMORY_BACKEND) then - idx = db_entry_desc%idx - status = 0 - return - end if - - - CALL ual_begin_pulse_action(db_entry_desc%backend_id, & - db_entry_desc%pulse, & - db_entry_desc%run, & - convert_array2string(db_entry_desc%user), & - convert_array2string(db_entry_desc%db_name), & - convert_array2string(db_entry_desc%version), & - idx, & - status) - if (status .eq. 0) CALL ual_open_pulse(idx, OPEN_PULSE, '', status) - - if (status /= 0) then - write (*,*) "ERROR: Cannot open DB entry!", & - " BE: ", db_entry_desc%backend_id, & - " USER: ", convert_array2string(db_entry_desc%user), & - " DB: ", convert_array2string(db_entry_desc%db_name), & - " PULSE/RUN: ", db_entry_desc%pulse, "/", db_entry_desc%run - return - - end if - - END SUBROUTINE open_db -{% else %} - SUBROUTINE open_db(db_entry_desc, idx, status) use ids_routines @@ -170,49 +130,27 @@ SUBROUTINE open_db(db_entry_desc, idx, status) INTEGER, INTENT(OUT) :: status character (STRMAXLEN) :: uri - - if (db_entry_desc%backend_id == MEMORY_BACKEND) then - idx = db_entry_desc%idx - status = 0 - return - end if - - call al_build_uri_from_legacy_parameters(db_entry_desc%backend_id, & - db_entry_desc%pulse, & - db_entry_desc%run, & - convert_array2string(db_entry_desc%user), & - convert_array2string(db_entry_desc%db_name), & - convert_array2string(db_entry_desc%version), & - "", uri, status) - - if (status .eq. 0) call imas_open( uri, OPEN_PULSE, idx, status) + uri = convert_array2string(db_entry_desc%uri) + call imas_open(uri, OPEN_PULSE, idx, status) if (status /= 0) then - write (*,*) "ERROR: Cannot open DB entry!", & - " BE: ", db_entry_desc%backend_id, & - " USER: ", convert_array2string(db_entry_desc%user), & - " DB: ", convert_array2string(db_entry_desc%db_name), & - " PULSE/RUN: ", db_entry_desc%pulse, "/", db_entry_desc%run - return - + write (*,*) "ERROR: Cannot open DB entry! URI: ", trim(uri) + return end if END SUBROUTINE open_db -{% endif %} SUBROUTINE close_db(db_entry_desc, idx) use ids_routines type(ids_description_t), intent(IN) :: db_entry_desc INTEGER, INTENT(OUT) :: idx + character (STRMAXLEN) :: uri - if (db_entry_desc%backend_id == MEMORY_BACKEND) then - return - end if - + uri = convert_array2string(db_entry_desc%uri) + if (index(uri, "imas:memory?") == 1) return call imas_close(idx) END SUBROUTINE close_db end module iwrap_tools - diff --git a/iwrap/generators/wrapper_generators/fortran_wrapper/resources/src/iwrap_converters.f90 b/iwrap/generators/wrapper_generators/fortran_wrapper/resources/src/iwrap_converters.f90 index a771be15..bb0ec4cf 100644 --- a/iwrap/generators/wrapper_generators/fortran_wrapper/resources/src/iwrap_converters.f90 +++ b/iwrap/generators/wrapper_generators/fortran_wrapper/resources/src/iwrap_converters.f90 @@ -72,7 +72,11 @@ FUNCTION convert_array2string(in_array) RESULT (out_string) integer :: i integer(C_SIZE_T) :: str_length - str_length = SIZE(in_array) + str_length = 0 + DO i = 1, SIZE(in_array) + if (in_array(i) == C_NULL_CHAR) exit + str_length = str_length + 1 + END DO allocate(character(str_length)::out_string) DO i = 1, str_length @@ -204,4 +208,3 @@ END FUNCTION convert_array2al_str end module iwrap_converters - diff --git a/iwrap/generators/wrapper_generators/java_wrapper/resources/src/IDSDescription.java b/iwrap/generators/wrapper_generators/java_wrapper/resources/src/IDSDescription.java index 9e311c7b..24c5bbf5 100644 --- a/iwrap/generators/wrapper_generators/java_wrapper/resources/src/IDSDescription.java +++ b/iwrap/generators/wrapper_generators/java_wrapper/resources/src/IDSDescription.java @@ -1,91 +1,45 @@ import java.io.*; -import java.util.Arrays; -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; public class IDSDescription { public String ids_type; - public int pulse; - public int run; public int occurrence; - public int backend_id; - public int idx; - public String database; - public String user; - public String version; + public String uri; + + /** Runtime-only open handle — not serialized. Set by {@code iWrapTools.open_db}. */ + public int idx = -1; public IDSDescription() { } public String toString() { return "IDSDescription{ids_type='" + this.ids_type + '\'' - + ", pulse=" + this.pulse - + ", run=" + this.run + ", occurrence=" + this.occurrence - + ", backend_id=" + this.backend_id - + ", idx=" + this.idx - + ", database='" + this.database + '\'' - + ", user='" + this.user + '\'' - + ", version='" + this.version + '\'' + '}'; - } - - public boolean db_equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - IDSDescription that = (IDSDescription) o; - return pulse == that.pulse - && run == that.run && idx == that.idx && backend_id == that.backend_id - && database.equals(that.database) && user.equals(that.user) && version.equals(that.version); + + ", uri='" + this.uri + '\'' + '}'; } - @Override + @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; IDSDescription that = (IDSDescription) o; - return this.db_equals(that) - && occurrence == that.occurrence - && ids_type.equals(that.ids_type) ; + return occurrence == that.occurrence + && ids_type.equals(that.ids_type) + && uri.equals(that.uri); } - public void read(BufferedReader br) throws IOException { String line; line = br.readLine(); // skip line " === IDS ====" - line = br.readLine(); //IDS type + line = br.readLine(); // IDS type this.ids_type = line.trim(); + line = br.readLine(); // occurrence + this.occurrence = Integer.parseInt(line.trim()); - line = br.readLine(); // shot - this.pulse = Integer.parseInt(line); - - - line = br.readLine(); // run - this.run =Integer.parseInt(line); - - line = br.readLine(); //occurrence - this.occurrence = Integer.parseInt(line); - - line = br.readLine(); //backend - this.backend_id = Integer.parseInt(line); - - line = br.readLine(); //idx - this.idx = Integer.parseInt(line); - - - line = br.readLine(); // database - this.database = line.trim(); - - - line = br.readLine(); // user - this.user = line.trim(); - - - line = br.readLine(); // version - this.version = line.trim(); -} + line = br.readLine(); // URI + this.uri = line.trim(); + } } \ No newline at end of file diff --git a/iwrap/generators/wrapper_generators/java_wrapper/resources/src/iWrapTools.java b/iwrap/generators/wrapper_generators/java_wrapper/resources/src/iWrapTools.java index 52324262..66b4fbdb 100644 --- a/iwrap/generators/wrapper_generators/java_wrapper/resources/src/iWrapTools.java +++ b/iwrap/generators/wrapper_generators/java_wrapper/resources/src/iWrapTools.java @@ -103,24 +103,13 @@ static public void handle_status_info(int status_code, String status_message, St static public void open_db(IDSDescription idsDescription) throws Exception { - int idx = -1; - - if (idsDescription.backend_id == LowLevel.MEMORY_BACKEND) - return; - - idx = imas.openEnv(idsDescription.pulse, - idsDescription.run, - idsDescription.user, - idsDescription.database, - idsDescription.version, - idsDescription.backend_id); - + int idx = imas.open(idsDescription.uri, LowLevel.FORCE_OPEN_PULSE); idsDescription.idx = idx; } static public void close_db(IDSDescription idsDescription) { - if (idsDescription.backend_id == LowLevel.MEMORY_BACKEND) + if (idsDescription.uri != null && idsDescription.uri.startsWith("imas:memory?")) return; try{