0

QuTiP 的函数parallel_map提供了并行计算给定函数的多个参数值的可能性。所有示例都显示了第一个位置参数不同的情况,如下所示:

def testFunc1(a, b):
    return a, b

from qutip import parallel_map
parallel_map(testFunc1, (1, 2, 3), task_args=(4,))

这返回[(1, 4), (2, 4), (3, 4)]。现在我想知道是否也可以有一个固定的值a和一个元组b。根据文档 task_args也可以是字典,所以我尝试了

parallel_map(testFunc1, (1, 2, 3), task_args={'a': 4})
parallel_map(testFunc1, (1, 2, 3), task_args={'a': 4, 'b': (1, 2, 3)})

但这会导致TypeError: can only concatenate tuple (not "dict") to tuple.
当我尝试

parallel_map(testFunc1, b=(1, 2, 3), task_args={'a': 4})

我明白了TypeError: parallel_map() missing 1 required positional argument: 'values'

有人知道如何使用parallel_mapn个位置参数(不为每个n编写函数包装器)吗?

4

2 回答 2

0

“如何使用parallel_mapn-th 位置参数(不为每个参数编写函数包装器n?”

避免在没有问题的地方产生问题,并将您的-th 放置在您的-ed 函数调用签名n中的外部填充迭代直接放入-expected (如文档所述)和迭代处理兼容:defparallel_map()tuple

#          (           )-------------------------- parallel_map() expected TUPLE
#your Fun( (  a    vv--)-------------------)----------------your FED-IN ITERABLE
testFunc1( ( 'a', 'b1' ), 'of-no-interest' ) --> (('a', 'b1'), 'of-no-interest')
testFunc1( ( 'a', 'b2' ), 'of-no-interest' ) --> (('a', 'b2'), 'of-no-interest')
testFunc1( ( 'a', 'b3' ), 'of-no-interest' ) --> (('a', 'b2'), 'of-no-interest')

“你的意思是这样的parallel_map(testFunc1, [(4, 1), (4, 2), (4, 3)], task_args=('of-no-interest',))吗?这里b总是有价值的'of-no-interest'。- AP 2 小时前

不,
该示例是卸载a和所有第n用户端代码 FED-IN可迭代( s)的清晰路径,正如上面所要求的那样。

def testFun2( a, b ):
    return [ item for item in tuple( a ) ], b

带路,打电话给:

testFun2( ( 'a', 'b', "c", None, 42, -3.14159, "The-N-th-ITERABLE" ),
          'not-important-one-(of-no-interest-HERE-in-solving-N-th-iterable-for-parallel_star()-calls)...'
           )

交付 -->

(['a', 'b', 'c', None, 42, -3.14159, "The-N-th-ITERABLE"], 'not-important-one-(of-no-interest-HERE-in-solving-N-th-iterable-for-parallel_star()-calls)...')

完全满足 a)您希望对任何第N个可迭代项有空闲的希望,而不仅仅是第一个位置,而且 b)parallel_map()正是期望的呼号签名并记录在案:

parallel_map( testFun2,                                        # TASK         Callable
              ( <_USER-SIDE_GENERATOR_FEED-IN_TUPLEsOfPARs_> ),# TASK VALUE(s)Array / List
              any_other_wished2have_call-signature_parameters, # TASK_ARGS    Dict
              ...,                                             # TASK_KWARGS  Dict
              ...                                              # call  KWARGS Dict
              )
于 2020-03-21T14:44:19.880 回答
0

查看源代码parallel_map揭示了为什么它只适用于函数的第一个参数:

async_res = [pool.apply_async(task, (value,) + task_args, task_kwargs, _update_progress_bar)
             for value in values]

在这一行中,创建了并行进程。该函数task获取一个表示所有位置参数的元组,该元组是从 the 的 1 个元素values和所有 other的元素创建的task_args。由于 的元素values位于组合元组 ( (value,) + task_args) 的第一个位置,因此它始终是函数的第一个参数,该参数在其并行实例之间变化。TypeError: can only concatenate tuple (not "dict") to tupleif 字典用于 for的task_args事实是 -+运算符仅重载 for (tuple, tuple),而不是 for (tuple, dict)

所以最终没有办法构建一个包装器。每个特定的n或通用的 n 之一,例如:

def wrapper(varyingArgument, moreArgs):
    n = moreArgs[0]
    orderedArgs = moreArgs[1:n] + (varyingArgument,) + moreArgs[n:]
    return testFunc1(*orderedArgs)

调用这个

parallel_map(wrapper, (1,2,3), task_args=((2, 4),))

返回

[(4, 1), (4, 2), (4, 3)]
于 2020-03-22T11:13:29.323 回答