你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

专用化声明

可调用声明一节中所述,目前没有理由显式声明函数的专用化。 本主题适用于作,并详细说明了如何声明必要的专用化以支持某些 functor。

在量子计算中,需要给定转换的相邻性是一个相当常见的问题。 许多量子算法都需要一个运算及其相邻来执行计算。 Q# 采用符号计算,可以自动生成特定正文实现的相应相邻实现。 即使对于自由混合经典计算和量子计算的实现,这一代也是可能的。 但是,在这种情况下,存在一些限制。 例如,如果实现使用可变变量,则出于性能原因不支持自动生成。 此外,在正文中调用的每个作都生成相应的相邻需要支持 Adjoint 函数本身。

尽管在多量子比特情况下无法轻松撤消度量,但可以合并度量,以便应用的转换是统一的。 在这种情况下,这意味着,尽管正文实现包含的度量值本身不支持 Adjoint 函数,但整个主体是相邻的。 尽管如此,在这种情况下,自动生成相邻实现会失败。 因此,可以手动指定实现。 编译器会自动为常见模式(如 串联)生成优化的实现。 尽管如此,可能需要显式专用化来手动定义更优化的实现。 可以显式指定任意一个实现和任意数量的实现。

注释

编译器不会验证此类手动指定的实现的正确性。

在以下示例中,作的声明 SWAP(交换两个量子比特的状态 q1q2)声明了其相邻版本及其受控版本的显式专用化。 因此,尽管 Adjoint SWAPControlled SWAP 的实现是用户定义的,但编译器仍需要为这两个函数(Controlled Adjoint SWAP(与 Adjoint Controlled SWAP相同)的组合生成实现。

    operation SWAP (q1 : Qubit, q2 : Qubit) : Unit
    is Adj + Ctl { 

        body ... {
            CNOT(q1, q2);
            CNOT(q2, q1);
            CNOT(q1, q2);
        }

        adjoint ... { 
            SWAP(q1, q2);
        }

        controlled (cs, ...) { 
            CNOT(q1, q2);
            Controlled CNOT(cs, (q2, q1));
            CNOT(q1, q2);            
        } 
    }

自动生成指令

确定如何生成特定专用化时,编译器优先处理用户定义的实现。 这意味着,如果相邻专用化是用户定义的,并且自动生成受控专用化,则基于用户定义的相邻化生成受控的相邻专用化,反之亦然。 在这种情况下,这两个专用化都是用户定义的。 由于相邻实现的自动生成受到更多限制,因此受控相邻专用化默认生成相邻专用化显式定义的显式实现的受控专用化。

对于 SWAP 实现,更好的选择是将受控专用化与控制专用化相接,以避免对控制量子比特的状态和最后一个 CNOT 进行不必要的调理。 为受控相邻版本添加显式声明,该声明指定适当的 生成指令 强制编译器基于受控版本的手动指定实现生成受控相邻专用化。 编译器生成的专用化的此类显式声明采用格式

    controlled adjoint invert;

并插入 SWAP声明。 另一方面,插入行

    controlled adjoint distribute;

强制编译器基于定义的(或生成的)相邻专用化生成专用化。 有关详细信息,请参阅此 部分专用化推理 建议以获取更多详细信息。

对于作 SWAP,有更好的选择。 SWAP自我相邻的,也就是说,它是它自己的反转:相邻的已定义实现只是调用 SWAP 正文,并用指令表示

    adjoint self;

以这种方式声明相邻专用化可确保编译器自动插入的受控相邻专用化仅调用受控专用化。

以下生成指令存在并且有效:

专业化 指令
body 专用化: -
adjoint 专用化: selfinvert
controlled 专用化: distribute
controlled adjoint 专用化: selfinvertdistribute

所有生成指令都对受控相邻专用化有效不是巧合:只要 functor 通勤,用于实现 functor 组合专用化的有效生成指令集始终是每个函数的有效生成器集的并集。

除了前面列出的指令,该指令 auto 对所有专用化都有效,body除外;它指示编译器应自动选取合适的生成指令。 声明

    operation DoNothing() : Unit {
        body ... { }
        adjoint auto;
        controlled auto;
        controlled adjoint auto;
    }

等效于

    operation DoNothing() : Unit 
    is Adj + Ctl { }

此示例中的批注 is Adj + Ctl 指定 作特征,其中包含特定作支持哪些 functor 的信息。

出于可读性的目的,我们建议使用其特征的完整说明对每个作进行批注,编译器将根据显式声明的特殊化自动插入或完成批注。 相反,编译器还会生成未显式声明但需要基于批注特征存在的专用化。 假设给定批注 隐式声明这些专用化。 如果可以,编译器将自动生成必要的专用化,并选取合适的指令。 因此,Q# 支持根据(部分)注释和显式定义的专用化来推断作特征和现有专用化。

从某种意义上说,专用化类似于同一可调用的单个重载,需要注意某些限制适用于可声明的重载。