Amspipe协议规范

AmSpipe协议是用于在同一计算机上的两个进程之间进行通信的远程过程呼叫协议。 这些过程之一是“管主”,提交几何和请求进行计算并接收结果。 另一个进程是“管道工作者”,它侦听来自主设备的呼叫,执行所请求的计算并返回其结果。

通信发生在一对管道上,是一个“呼叫管道”(掌握到工人)和“回复管道”(工人到掌握)。 每个管道携带一系列消息,这些消息是按顺序处理的。 每条消息都是包含单个项目的关联对象(如JSON对象或Python Dict)。 此项目的键表示消息的名称,而此项的值是包含有效载荷的另一个对象。

通过呼叫管道发送的每条消息都构成了方法调用。 消息的名称等于正在调用的方法的名称,而有效负载对象包含任何参数。 对于没有参数的方法,有效载荷是空对象。

一旦工作人员收到呼叫消息,它将执行指定的方法,并可能将零或多个消息的序列写入回复管道,包含计算结果。 执行方法完成后,工作人员将向回复管道写入“返回”消息,表示方法调用的成功或失败。

任何以“set”开头的方法都不会发送“返回”消息。 相反,下次生成“返回”消息时,将缓冲在执行SET方法期间遇到的错误。 虽然缓冲错误,但是工人忽略任何进一步的方法调用,并且未执行。 一旦工作人员看到非设定呼叫,也会在不被执行的情况下丢弃这样的呼叫,但是将立即使用缓冲的错误数据生成“返回”消息。 然后将清除缓冲的错误,并将呼叫恢复的正常处理。

作为一个特殊情况,可以随时调用“退出”方法,并且将由工作人员立即执行,终止协议会话。 “退出”方法永远不会返回“返回”消息,丢弃任何可能的缓冲错误。

所有值始终是原子单位:Hartree为能量,Bohr为距离,Hartree / Bohr为梯度等。

低级消息编码

所有消息都使用通用二进制JSON进行编码。 AmSpipe实现可以使用UBJSOSON优化的容器格式(具有显式长度和/或强类型)进行编码消息。 实现必须支持解码UBJSON容器是否使用优化格式编写。

邮件中的UBJSON数组不得包含其他数组或对象。 必须在编码上展平多维阵列(根据需要在解码时不完整)。 扁平化应保持内存中的元素的原始顺序。 所有阵列必须伴随额外的整数阵列,在平整之前持有原始尺寸。 The name of this auxiliary array is equal to the name of the main array with a _dim_ suffix. The dimensions are written in Fortran (column-major) order, so that the first value in the _dim_ array corresponds to the index that changes the fastests when iterating over consecutive elements of the flattened array.

阵列也不包含不兼容类型的元素。 数组的元素必须是全整数,所有实数,所有布尔值或所有字符串。 UBJSON类型“char”等效于长度1的Ubjson“字符串”(因此,“字符串”和“字符串”的元素可以在阵列中混合)。 空数组相当于根本不存在的数组。

在通过Stream传输机制(例如UNIX管道)上发送消息时,必须以32位本机ENDIAN整数长度为前缀。

返回消息和错误处理

“返回”消息由以下字段组成:

  • “状态”(整数):零成功或下面列出的错误代码。
  • “方法”(String,可选):发生错误的方法的名称。
  • “参数”(String,可选):错误中的参数名称。
  • “消息”(字符串,可选):人类可读错误消息。

“状态”字段可以具有以下值之一:

0:成功
没有错误,方法成功执行。
1:Decode_Error.
无法正确解码消息(无效的UBJSON编码或违反上述约束之一)。
2:logic_error.
程序员错误,例如以不正确的序列或无效的工作状态调用的方法。
3:runtime_error.
执行方法(在AmSpipe协议之外)期间发生错误。
4:Unknown_version.
(仅从“Hello”返回。)工作者不支持请求的协议版本。
5:Unknown_Method.
工作人员不支持请求名称的方法。
6:Unknown_argument.
“论证”中的论点是工人不知道的,无法处理。如果给定单个呼叫的多个参数未知,则将在最低嵌套深度(如果参数包含嵌套对象),将设置为“参数”。如果同一嵌套深度的多个字段未知,则将返回ASCII排序顺序的第一个。
7:Invalid_argument.
参数没有正确的类型或维度,或者它具有无效值。

方法

你好(版本)

  • “版本”(Integer):

尝试激活给定版本的AMSPIPE协议。目前只定义版本1。

其他方法(除了“Hello”和“退出”)之前不得调用,直到Hello成功完成。 如果返回Unknown_version错误,请使用最高支持的协议版本并将其迭代,从而尝试Hello。 一旦你好成功了,在管道会话的生命周期中,不得再次调用它。

出口()

终止工人并断开两个管道。 此方法永远不会返回。

工作人员也可能丢弃任何记忆的计算。

setcoords(Coords)

  • “Coords”(真实(3,:)):

更换当前化学系统中的笛卡尔坐标。原子数必须匹配。

setLattice(矢量)

  • “vectors”(真实(:, :)):

更换当前化学体系的晶格矩阵。如果“vectors”不存在或尺寸(0,0),则使系统不定期。

SerioSystem(Atomsymbols,Coords,TotalCharge)

  • “atomsymbols”(String(:)):
  • “Coords”(真实(3,:)):
  • “税收”(真实):

定义新的化学系统。

解决(请求,keepresults,prevtitle)

  • “请求”(对象):
    • “标题”(字符串):识别此计算的唯一字符串键。
    • “安静”(BOOL):如果是真,则应该将任何标准输出保留到最小值。
    • “梯度”(BOOL):计算原子的梯度。
    • “胁迫镜”(BOOL):计算压力张量。
    • “弹性囊”(BOOL):
    • “黑森州”(BOOL):
    • “二极管”(BOOL):
    • “Dipolegradients”(BOOL):
  • “keepresults”(bool,默认为false):记住工人州以备将来重启。
  • “prevtitle”(String,可选):以前存储的计算标题以重新启动。

在当前化学系统上运行单点计算,如果成功,则返回“结果”对象。如果计算失败了运行时错误,则仍可能返回“结果”对象(可能只有一些请求的属性)。

如果不存在,“请求”默认为“请求”默认为false。 除“标题”之外的“请求”中的所有非布尔字段都是可选的,其默认值是依赖于工人。 Master不应明确将“请求”中的任何布尔字段设置为false。 如果未知的布尔设置为false,工作者可能会提高一个未知的参数错误。 如果将未知的布尔设置为true或者如果设置了未知的非布尔值,则工作人员应该像往常一样提高未知的参数错误。 工人应在执行任何耗时的计算之前提高这些错误,以便主站可以有效地重试呼叫。

如果未指定或设置为false“keepresults”,则在返回“结果”对象后,工作人员将从计算中丢弃所有数据。 如果“keepresults”设置为true,则工作人员将记住与计算相关的内部状态。 稍后可以通过将存储的计算的“标题”传递为“prevtitle”来重新启动此内部状态。 管道主人应尽快呼叫DeleterSults以丢弃所存储状态。

“结果”对象由以下字段组成。 工人可能包括此处未列出的其他字段。 由于它不期望或理解的任何字段,主人不得发出错误。

  • “结果”(对象):
    • “消息”(String(:)):计算由计算生成的运行时错误或警告消息。
    • “能量”(真实):
    • “渐变”(真实(3,:)):
    • “rangertentensor”(真实的(:, :)):
    • “弹性囊”(真实(:, :)):
    • “黑森州”(真实的(:,:)):
    • “Dipolemoment”(真实(:, :)):
    • “Dipolegradients”(Real(:, :)):
    • “收费”(真实(:)):

DeleterEsults(标题)

  • “标题”(字符串):先前记住的计算标题。

丢弃与先前记住的计算相对应的任何工人状态。

前向和向后兼容性考虑

AmSpipe协议旨在支持与旧工人的新主人相结合,反之亦然。 通过增加协议版本号来处理协议的主要更改。 然后在管道会话开始时通过呼叫来处理合适的协议版本。

解决以下要求以确保协议在单个协议版本中保持可扩展:

  • 工作人员必须在任何对其不实现的方法的呼叫上提高一个未知的_Method错误。如果方法名称以SET开头,则会缓冲这样的错误以稍后返回。如果方法名称未以SET开头,则将立即生成“返回”消息。
  • 随时遇到一个已知方法的任何时候,工人必须提高未知的_argument错误,他们不知道如何处理。然后,主人应在没有这样的参数的情况下重试呼叫,或者如果可能,请选择替代呼叫序列。
  • 主机应忽略回复管道上不受支持类型的意外消息。

即,在不增加协议版本号的情况下允许以下更改:

  • 向协议添加新方法。
  • 向现有方法添加新的可选参数。
  • 添加新字段以返回对象。
  • 添加新的回复消息类型。