未验证 提交 462ee101 编写于 作者: A Aurelius84 提交者: GitHub

[CustomOp]Add RWLock to protect loading module under multi-thread and...

[CustomOp]Add RWLock to protect loading module under multi-thread and multi-process (#38128) (#38271)

[Cherry-pick][CustomOp]Add RWLock to protect loading module under multi-thread and multi-process (#38128)
上级 92f86a35
...@@ -17,16 +17,24 @@ import re ...@@ -17,16 +17,24 @@ import re
import sys import sys
import json import json
import glob import glob
import atexit
import hashlib import hashlib
import logging import logging
import collections import collections
import textwrap import textwrap
import warnings import warnings
import subprocess import subprocess
import threading
from importlib import machinery
from contextlib import contextmanager from contextlib import contextmanager
from setuptools.command import bdist_egg from setuptools.command import bdist_egg
try:
from subprocess import DEVNULL # py3
except ImportError:
DEVNULL = open(os.devnull, 'wb')
from ...fluid import core from ...fluid import core
from ...fluid.framework import OpProtoHolder from ...fluid.framework import OpProtoHolder
from ...sysconfig import get_include, get_lib from ...sysconfig import get_include, get_lib
...@@ -777,7 +785,6 @@ def parse_op_info(op_name): ...@@ -777,7 +785,6 @@ def parse_op_info(op_name):
Parse input names and outpus detail information from registered custom op Parse input names and outpus detail information from registered custom op
from OpInfoMap. from OpInfoMap.
""" """
from paddle.fluid.framework import OpProtoHolder
if op_name not in OpProtoHolder.instance().op_proto_map: if op_name not in OpProtoHolder.instance().op_proto_map:
raise ValueError( raise ValueError(
"Please load {} shared library file firstly by `paddle.utils.cpp_extension.load_op_meta_info_and_register_op(...)`". "Please load {} shared library file firstly by `paddle.utils.cpp_extension.load_op_meta_info_and_register_op(...)`".
...@@ -824,16 +831,28 @@ def _generate_python_module(module_name, ...@@ -824,16 +831,28 @@ def _generate_python_module(module_name,
""" """
Automatically generate python file to allow import or load into as module Automatically generate python file to allow import or load into as module
""" """
api_file = os.path.join(build_directory, module_name + '.py')
def remove_if_exit(filepath):
if os.path.exists(filepath):
os.remove(filepath)
# NOTE: Use unique id as suffix to avoid write same file at same time in
# both multi-thread and multi-process.
thread_id = str(threading.currentThread().ident)
api_file = os.path.join(build_directory,
module_name + '_' + thread_id + '.py')
log_v("generate api file: {}".format(api_file), verbose) log_v("generate api file: {}".format(api_file), verbose)
# write into .py file # delete the temp file before exit python process
atexit.register(lambda: remove_if_exit(api_file))
# write into .py file with RWLock
api_content = [_custom_api_content(op_name) for op_name in op_names] api_content = [_custom_api_content(op_name) for op_name in op_names]
with open(api_file, 'w') as f: with open(api_file, 'w') as f:
f.write('\n\n'.join(api_content)) f.write('\n\n'.join(api_content))
# load module # load module
custom_module = _load_module_from_file(api_file, verbose) custom_module = _load_module_from_file(api_file, module_name, verbose)
return custom_module return custom_module
...@@ -881,7 +900,7 @@ def _custom_api_content(op_name): ...@@ -881,7 +900,7 @@ def _custom_api_content(op_name):
return api_content return api_content
def _load_module_from_file(api_file_path, verbose=False): def _load_module_from_file(api_file_path, module_name, verbose=False):
""" """
Load module from python file. Load module from python file.
""" """
...@@ -891,8 +910,9 @@ def _load_module_from_file(api_file_path, verbose=False): ...@@ -891,8 +910,9 @@ def _load_module_from_file(api_file_path, verbose=False):
# Unique readable module name to place custom api. # Unique readable module name to place custom api.
log_v('import module from file: {}'.format(api_file_path), verbose) log_v('import module from file: {}'.format(api_file_path), verbose)
ext_name = "_paddle_cpp_extension_" ext_name = "_paddle_cpp_extension_" + module_name
from importlib import machinery
# load module with RWLock
loader = machinery.SourceFileLoader(ext_name, api_file_path) loader = machinery.SourceFileLoader(ext_name, api_file_path)
module = loader.load_module() module = loader.load_module()
...@@ -1046,10 +1066,6 @@ def run_cmd(command, verbose=False): ...@@ -1046,10 +1066,6 @@ def run_cmd(command, verbose=False):
""" """
# logging # logging
log_v("execute command: {}".format(command), verbose) log_v("execute command: {}".format(command), verbose)
try:
from subprocess import DEVNULL # py3
except ImportError:
DEVNULL = open(os.devnull, 'wb')
# execute command # execute command
try: try:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册