人妻精品在线观看一区二区三区,蜜臀av精品一区二区三区网站,中文一区二区三区亚洲欧美,熟女人妇精品一区二区,人妻av在线观看视频,欧美日韩国产三级精品网站,黄色免费网站直接进入,超碰公开福利正在播放,国产毛片乡下农村妇女毛片

OneFlow源碼解析:靜態(tài)圖與運行時

來源:CSDN博客 | 2023-01-06 19:07:24 |

作者|鄭建華 更新|許嘯宇、張文驍、成誠OneFlow靜態(tài)圖的訓練效率遠高于動態(tài)圖(eager模式)。本文試圖通過一個簡單例子,結(jié)合v0.8.0版本的代碼,解讀一下靜態(tài)圖和運行時的實現(xiàn)機制。

在開始之前,建議先讀一下參考資料中《OneFlow框架的系統(tǒng)設計(https://zhuanlan.zhihu.com/p/337851255)》等系列文章。對靜態(tài)圖、運行時的基本概念和設計理念有基本的了解,會更容易理解代碼。


(相關資料圖)

1?

代碼示例

下面的示例代碼來自官方文檔(https://docs.oneflow.org/master/basics/08_nn_graph.html),是一個線性模型的前向計算。后續(xù)主要基于這段代碼進行分析。

import oneflow as flowimport oneflow.nn as nnclass ModuleMyLinear(nn.Module): def __init__(self, in_features, out_features): super().__init__() self.weight = nn.Parameter(flow.randn(in_features, out_features)) self.bias = nn.Parameter(flow.randn(out_features)) def forward(self, input): return flow.matmul(input, self.weight) + self.biaslinear_model = ModuleMyLinear(4, 3)class GraphMyLinear(nn.Graph): def __init__(self): super().__init__() # ModuleBlock self.model = linear_model def build(self, input): # ModuleBlock.__call__ return self.model(input)graph_mylinear = GraphMyLinear()input = flow.randn(1, 4)out = graph_mylinear(input)print(out)

2?

oneflow包的初始化

import oneflow在初始化包(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/__init__.py)時,與靜態(tài)圖相關的主要操作如下:

GetEnv(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/__init__.py#L228

EnvGlobalObjectsScope::Init(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/job/env_global_objects_scope.cpp#L126

啟動各個節(jié)點的控制面(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/job/env_global_objects_scope.cpp#L160-L162)網(wǎng)絡連接

初始化VM(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/job/env_global_objects_scope.cpp#L180

啟動各個節(jié)點的數(shù)據(jù)面網(wǎng)絡連接(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/job/env_global_objects_scope.cpp#L184-L188

初始化KernelObserver(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/job/env_global_objects_scope.cpp#L192-L203

NewDefaultSession(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/__init__.py#L229

RegsiterSession(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/framework/multi_client_session.py#L39)?創(chuàng)建 Session,并注冊為 default session(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/framework/session_util.cpp#L89

創(chuàng)建 Python MultiClientSession 并保存到dict(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/framework/session_context.py#L40),但并不 TryInit

創(chuàng)建 C++ MultiClientSessionContext(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/framework/multi_client_session.py#L41)?但并不 TryInit

EnvGlobalObjectsScope::Init中先創(chuàng)建一個全局的ProcessCtx(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/job/env_global_objects_scope.cpp#L132)對象。然后根據(jù)環(huán)境變量等配置,在各個進程間創(chuàng)建gRPC和CommNet的連接,分別負責控制面和數(shù)據(jù)面的數(shù)據(jù)傳輸。其中在Bootstrap過程中會初始化全局的ProcessCtx(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/rpc/lib/grpc.cpp#L42),給每個進程分配一個全局唯一的rank編號(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/rpc/lib/global_process_ctx.cpp#L28)(machine_id(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/rpc/lib/global_process_ctx.cpp#L24))。

本文不涉及網(wǎng)絡層面的操作,只討論同一進程內(nèi)各線程間的交互。

3?

Module類

雖然可以直接用op和tensor構(gòu)造模型,但是op的粒度太細了,直接用op構(gòu)造模型會比較繁瑣。

Module(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/module.py#L54)是由op和tensor構(gòu)成的、可復用的子模塊。利用Module可以更高效、更快捷的構(gòu)建復雜模型。oneflow.nn(https://github.com/Oneflow-Inc/oneflow/blob/d825243aa7aff5cba8bd3a901b4cc56c2b1a36af/python/oneflow/nn/__init__.py)模塊導出了很多預定義的Module。

Module定義了自己的屬性設置邏輯(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/module.py#L262),核心邏輯是

如果value是Parameter類型,就保存到Module._parameters中

如果value是Module類型,就保存到Module._modules中

如果value是Tensor類型,就保存到Module._buffers中

否則按常規(guī)屬性處理

Module可以包含子Module,形成樹結(jié)構(gòu)。因為Module通過setattr將子Module和Parameter都保存到字典結(jié)構(gòu)中,可以方便的遍歷所有Module及其參數(shù)tensor。

4?

Graph類

4.1 構(gòu)造函數(shù)

Graph的構(gòu)造函數(shù)中GetDefaultSession(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/graph.py#L145)得到的session,就是導入oneflow包時NewDefaultSession(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/__init__.py#L229)構(gòu)建的session。當時沒有初始化,而是在Graph構(gòu)造時進行初始化(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/graph.py#L147)。對應的C++函數(shù)是MultiClientSessionContext::TryInit(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/framework/multi_client_session_context.cpp#L67),執(zhí)行時會創(chuàng)建各種全局的資源管理器,比如: ?

LazyJobBuildAndInferCtxMgr

BufferMgr

RegstMgr

ActorMsgBus

ThreadMgr

4.2?__setattr__: 將Module和Tensor封裝為Block

Graph.__setattr__ 支持通過設置屬性的方式把一個 Module 添加到 Graph 中,之后改 Module 就可以被 Graph 調(diào)用了。添加到 Graph 中的 Module,會被包裝到 Block 里面,Block 起到了代理執(zhí)行的作用,它會給原 Eager 下的 Module 擴展出靜態(tài)執(zhí)行需要的一些特殊功能。

添加到 Graph 中的 Module 和原 Module 共享了狀態(tài)(Parameter、Buffer)和 forward 執(zhí)行邏輯。共享 forward 執(zhí)行邏輯使得靜態(tài)和動態(tài)執(zhí)行計算邏輯相同。共享狀態(tài)則可以使動態(tài)圖下的模型狀態(tài)被靜態(tài)圖復用?;诖耍瑑蓚€ Graph,一個用于訓練,一個用于預測,他們都復用統(tǒng)一模型 Module,這樣訓練和預測 Graph 也就實現(xiàn)了模型共享。

setattr最重要的動作就是對_add_block的調(diào)用(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/graph.py#L1332),_add_block中主要是調(diào)用get_block_cls并保存結(jié)果(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/graph.py#L1326)。get_block_cls(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/block.py#L39)的作用是將Module及其所有Tensor屬性都轉(zhuǎn)為對應的Block對象。為什么要做這個動作呢?主要是靜態(tài)圖編譯需要借助Block類型來實現(xiàn)代理執(zhí)行的功能,這些功能不適合直接寫到 eager 下的 Module 和 Tensor 上。

這個轉(zhuǎn)換是在ModuleBlock構(gòu)造時調(diào)用set_origin(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/block.py#L131)完成的。對于子Module,會遞歸調(diào)用get_block_cls函數(shù)(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/block.py#L145),這樣所有子Module及其Tensor屬性都會被轉(zhuǎn)換為對應的Block對象。

所以,上述示例代碼中,GraphMyLinear實際存儲的是ModuleBlock,Graph.build執(zhí)行時獲取的model屬性也是ModuleBlock對象,ModuleBlock.origin才是ModuleMyLinear。

Graph.__setattr__不允許將Tensor對象設置為屬性(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/graph.py#L1340)。Tensor只能存到Module中,因為 Module 是做狀態(tài)共享的基本單位,而 Graph 是不允許復用的。

4.3 針對不同任務,定義不同的計算圖

根據(jù)Oneflow Model Zoo的模型示例(https://github.com/Oneflow-Inc/models/blob/1b291f78d8f60e5f04ee0c5962e4611cc4bab40a/Vision/classification/image/alexnet/graph/train.py),train/eval等階段可以創(chuàng)建不同的Graph子類。動態(tài)圖下提供了 Module、Optimizer、Dataloader等模塊,這些模型都可以被添加到 Graph 中。不同的組合可以構(gòu)建不同類型的任務。

在這些不同階段,Graph構(gòu)造函數(shù)的行為、build函數(shù)的輸入輸出都有各自特點。了解這些,看后續(xù)代碼時會更容易理解各個參數(shù)的具體含義。

構(gòu)造函數(shù)

train階段,需要添加Module、損失函數(shù)、優(yōu)化器和dataloader

eval階段,只需要添加Module和dataloader

build函數(shù)

train

導入樣本和label

調(diào)用Module得到前向計算結(jié)果

計算損失

計算梯度

返回loss

eval

導入樣本和label

調(diào)用Module得到預估結(jié)果

返回預估結(jié)果和label

4.4 小結(jié)

上述幾個類型的關系如下:

下面描述了GraphMyLinear的構(gòu)造流程

* `__init__` * `Graph.__init__` * self.model = linear_model * `Graph.__setattr__` * _add_block * get_block_cls: 遞歸地把Module轉(zhuǎn)為ModuleBlock * `ModuleBlock.__init__` * ModuleBlock.set_origin * `ModuleBlock._origin = origin` (Module) * 對origin的sub modules, parameters, buffers遞歸調(diào)用get_block_cls * `ModuleBlock.__setattr__`

5?

邏輯圖的編譯

計算機語言的編譯,是將高級語言的語句編譯為匯編或機器指令。深度學習框架對計算任務的編譯,是將用戶的特定語句操作轉(zhuǎn)換為DAG圖。oneflow中用Job(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/job/job.proto#L30)描述邏輯的計算圖。

不同于eager模式的動態(tài)圖,靜態(tài)圖在開始執(zhí)行前可以得到整個計算任務的所有信息,可以對DAG進行多輪優(yōu)化。每輪優(yōu)化都是輸入一個Job、得到一個新Job。

最后,根據(jù)分布式環(huán)境配置,將邏輯圖Job轉(zhuǎn)換為物理執(zhí)行的計算圖Plan(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/job/plan.proto#L34)。在物理圖中,一個op可能分布在多個節(jié)點/進程。

啟動DAG計算需要調(diào)用Graph.__call__,這個函數(shù)的執(zhí)行主要分以下幾個步驟:

__call__

_compile(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/graph.py#L221)?if not _is_compiled

build_graph(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/graph.py#L741

__build_graph(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/graph.py#L759

finish_complie_and_init_runtime(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/graph.py#L742

__run(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/graph.py#L226

邏輯圖編譯主要在__build_graph中進行。finish_complie_and_init_runtime會繼續(xù)做一些優(yōu)化pass,然后構(gòu)建物理圖、初始化運行時Actor系統(tǒng)。__run會啟動一次DAG的運算。

5.1 graph_build_context: 為邏輯圖編譯設置基本環(huán)境

在 Graph 中,build 函數(shù)里面的代碼執(zhí)行都在 graph_build_context 的作用域下,這樣實現(xiàn)了動態(tài)轉(zhuǎn)靜態(tài)的功能。

__build_graph中的graph_build_context(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/graph.py#L851)雖然只有一行代碼,但卻做了幾件非常重要的事情。

首先在context作用域內(nèi)設置全局的lazy_mode為True(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/framework/graph_build_util.py#L46)。在這個context作用域內(nèi),所有op都由LazyInterpreter解釋執(zhí)行。

其次,在JobBuildAndInferCtx(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/framework/graph_build_util.py#L47)作用域內(nèi),JobBuildAndInferCtx_Open(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/framework/graph_build_util.py#L57)調(diào)用類似如下C++代碼

// oneflow/api/python/job_build/job_build_and_infer.h// oneflow/core/job/job_build_and_infer_ctx_mgr.cpp// 如前所述,LazyJobBuildAndInferCtxMgr 在 MultiClientSessionContext::TryInit 執(zhí)行時初始化。// LazyJobBuildAndInferCtxMgr mgr;mgr.OpenJobBuildAndInferCtx(job_name);

OpenJobBuildAndInferCtx會新建一個Job對象(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/job/job_build_and_infer_ctx_mgr.cpp#L32)、一個LazyJobBuildAndInferCtx對象(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/job/job_build_and_infer_ctx_mgr.cpp#L34)。LazyJobBuildAndInferCtx負責根據(jù)用戶定制的op等操作,修改Job,其中最主要的功能是添加新 Op。

5.2 __build_io:為計算圖添加input和output Op

self.__build_io("input",?graph_build_util.build_graph_input_arg,?*args,?**kwargs)

上面這行代碼(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/graph.py#L854-L856)的作用是,對于用戶傳遞給graph_mylinear(input)的input參數(shù),針對其中的每個tensor都在邏輯計算圖中插入一個FeedInputOp(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/framework/system_ops.h#L48)節(jié)點。也就是說,model的輸入(比如樣本tensor,具體參考4.3節(jié)),在靜態(tài)圖中也視為一個op操作。

__build_io內(nèi)會用args(即input)和kwargs構(gòu)造一個ArgsTree。ArgsTree 把 Python 下的輸入、輸出抽象成了一個樹,輸入、輸出可以是嵌套的 Tuple、List、Dict,元素是 Tensor,嵌套的結(jié)構(gòu)剛好可以表示為樹,而 Tensor 是樹中的葉子節(jié)點。示例代碼中kwargs是空的。

遍歷ArgsTree,對args和kwargs的每個tensor都調(diào)用傳入的build_func,對于input來說,就是build_graph_input_arg(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/framework/graph_build_util.py#L206)。后面會看到,model的output也會調(diào)用__build_io,所以這個函數(shù)名的意思應該就是對model的輸入、輸出進行靜態(tài)圖的構(gòu)圖工作。

build_graph_input_arg內(nèi)部會構(gòu)造一個FeedInputOpExpr(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/framework/graph_build_util.py#L213),提交給解釋器執(zhí)行。因為是在lazy作用域內(nèi),由LazyInterpreter解釋執(zhí)行(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/framework/op_interpreter/lazy_op_interpreter.cpp#L471),LazyInterpreter會將對應的op插入靜態(tài)圖。

附:build input時ArgsTree的內(nèi)部結(jié)構(gòu)

__build_io(input)?中 ArgsTree 的內(nèi)部數(shù)據(jù)組織示意

_named_io_args: NamedArg

_value: tuple

[0]: NamedArg

_value: tuple of NamedArg

[0]: NamedArg

_value: args tensor from?Graph.__call__

[1]: NamedArg

_value: empty kwargs from?Graph.__call__

通過pdb命令可以查看變量:?p args_tree._named_io_args._value[0]._value[0]._value.to_numpy()

5.2.1 將op添加到邏輯圖

LazyInterpreter::ApplyImpl(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/framework/op_interpreter/lazy_op_interpreter.cpp#L471)在執(zhí)行時,GetCurInferCtx()(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/framework/op_interpreter/lazy_op_interpreter.cpp#L500)返回的就是graph_build_context中OpenJobBuildAndInferCtx(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/framework/graph_build_util.py#L57)創(chuàng)建的那個LazyJobBuildAndInferCtx對象,這個對象負責邏輯圖的構(gòu)建。添加op的主要調(diào)用流程如下:

infer_ctx->AddAndInferConsistentOp(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/framework/op_interpreter/lazy_op_interpreter.cpp#L503

AddAndInferOp(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/job/job_build_and_infer_ctx.cpp#L563

ConstructOp(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/job/job_build_and_infer_ctx.cpp#L580

CheckAndConstructOp(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/operator/operator.cpp#L1216

NewObj(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/operator/operator.cpp#L51

OperatorConf中,多種op配置共享op_type字段(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/operator/op_conf.proto#L412),protobuf oneof的op_type_case常量作為注冊NewObj的key。

系統(tǒng)預定義的op在oneflow/core/operator(https://github.com/Oneflow-Inc/oneflow/tree/release/v0.8.0/oneflow/core/operator)下,例如UserOp(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/operator/user_op.h#L24)。

AddAndInferOp將返回的Operator保存到LazyJobBuildAndInferCtx的字典中。后續(xù)的函數(shù)調(diào)用,主要是進行推導并修改靜態(tài)圖Job,使得各個節(jié)點構(gòu)成一個DAG。

JobBuildAndInferCtx相關的類關系如下:

5.2.2 lazy tensor 和 eager tensor 的區(qū)別

LazyInterpreter::ApplyImpl的最后,會調(diào)用BuildTensor(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/framework/op_interpreter/lazy_op_interpreter.cpp#L518)構(gòu)造一個lazy tensor,作為build_graph_input_arg的返回值(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/framework/graph_build_util.py#L216)。所以__build_io返回的lazy_args(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/graph.py#L854)是lazy tensor,它將替代eager的args(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/graph.py#L828)(也就是用戶輸入的input)參與后續(xù)的計算圖構(gòu)建。

那么lazy tensor和eager tensor的區(qū)別是什么呢?eager tensor是要即時計算的,所以需要真實數(shù)據(jù);而lazy tensor僅在靜態(tài)圖編譯階段用于推導,只需要描述性質(zhì)的元信息。靜態(tài)圖編譯是在lazy模式下運行,只是使用lazy tensor 做計算機構(gòu)圖和校驗。

后面會看到,靜態(tài)圖的運行期已經(jīng)沒有tensor的概念。運行期看到的只是更廣義的Regst存儲,可能代表tensor/blob,也可能是其它控制信息。靜態(tài)圖運行時的輸入,是直接讀取外部 eager tensor的內(nèi)存數(shù)據(jù)到到regst;輸出應該是op寫到regst,通過blob構(gòu)造eager tensor。

5.3 build: 將UserOp和FeedVariableOp添加到邏輯圖

__build_graph中的self.build()(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/graph.py#L861)會調(diào)用GraphMyLinear.build(),以及ModuleMyLinear.forward()。因為是在lazy模式下運行,matmul和add都會調(diào)用UserOpExpr重載版本的LazyInterpreter::ApplyImpl(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/framework/op_interpreter/lazy_op_interpreter.cpp#L832),進而調(diào)用AddAndInferConsistentOp(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/framework/op_interpreter/lazy_op_interpreter.cpp#L940)進行構(gòu)圖操作。

需要說明的是,在引用Module的Parameter屬性時(如weight/bias),會觸發(fā)FeedVariableOp的構(gòu)圖操作(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/framework/graph_build_util.py#L226)、調(diào)用對應版本的LazyInterpreter::ApplyImpl(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/framework/op_interpreter/lazy_op_interpreter.cpp#L527)。這個是怎么執(zhí)行的呢?

__build_graph中,在進入lazy模式之前,先調(diào)用了_create_states_builder(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/graph.py#L843)。其中self._state()(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/graph.py#L667)返回所有Module的所有Parameter(包括子Module)。

state_block的類型是TensorBlock(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/block.py#L631)。所有的state_block的lazy_origin_builder().method(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/block.py#L647)都被設置為調(diào)用build_graph_state(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/graph.py#L683-L688)。

給build_graph_state(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/framework/graph_build_util.py#L220)設置個斷點能讓整個調(diào)用過程顯形,主要的調(diào)用棧如下:

-> out = graph_mylinear(input) /usr/local/lib64/python3.6/site-packages/oneflow/nn/graph/graph.py(221)__call__()-> self._compile(*args, **kwargs) /usr/local/lib64/python3.6/site-packages/oneflow/nn/graph/graph.py(741)_compile()-> _, eager_outputs = self.build_graph(*args, **kwargs) /usr/local/lib64/python3.6/site-packages/oneflow/nn/graph/graph.py(759)build_graph()-> outputs = self.__build_graph(*args, **kwargs) /usr/local/lib64/python3.6/site-packages/oneflow/nn/graph/graph.py(864)__build_graph()-> outputs = self.build(*lazy_args, **lazy_kwargs) /mnt/project/machine-learning/oneflow/oneflow/test.py(21)build()-> return self.model(input) /usr/local/lib64/python3.6/site-packages/oneflow/nn/graph/block.py(234)__call__()-> result = self.__block_forward(*args, **kwargs) /usr/local/lib64/python3.6/site-packages/oneflow/nn/graph/block.py(266)__block_forward()-> result = self._origin.__class__.forward(self, *args, **kwargs) /mnt/project/machine-learning/oneflow/oneflow/test.py(11)forward()-> return flow.matmul(input, self.weight) + self.bias /usr/local/lib64/python3.6/site-packages/oneflow/nn/graph/block.py(483)__getattr__()-> p_state = self._get_from_states(name, "_parameters") /usr/local/lib64/python3.6/site-packages/oneflow/nn/graph/block.py(521)_get_from_states()-> _s_block.try_build() /usr/local/lib64/python3.6/site-packages/oneflow/nn/graph/block.py(679)try_build()-> self._lazy_origin_builder.try_build(self) /usr/local/lib64/python3.6/site-packages/oneflow/nn/graph/block.py(627)try_build()-> self.result = self.method()> /usr/local/lib64/python3.6/site-packages/oneflow/framework/graph_build_util.py(227)build_graph_state()-> op_name, var_conf_str, ["in_0"], ["out_0"]

這個調(diào)用過程比較容易困擾的是,執(zhí)行對象會在Grpah、GraphMyLinear、ModuleMyLinear、ModuleBlock之間切換。

前面在討論Graph的構(gòu)造時已經(jīng)提過,執(zhí)行self.model(input)時,Graph.__getattr__返回的屬性model是ModuleBlock對象,所以實際調(diào)用的是ModuleBlock.__call__。

在這個函數(shù)內(nèi)調(diào)用__block_forward(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/block.py#L234),其中的_origin(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/block.py#L266)是ModuleMyLinear,進入到它的forward方法,執(zhí)行到flow.matmul(input, self.weight) + self.bias時,matmul 會被LazyOpInterpreter 所執(zhí)行,在 LazyOpInterpreter 中調(diào)用 AddAndInferConsistentOp(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/framework/op_interpreter/lazy_op_interpreter.cpp#L503

,在 Job 中添加一個 matmul operator。同理后面的加法會在 job 中添加一個 add operator。

self.weight 和 self.bias 會觸發(fā)調(diào)用ModuleBlock.__getattr__,進而調(diào)用_get_from_states(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/block.py#L483),調(diào)用TensorBlock.try_build()(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/block.py#L521)。這里執(zhí)行的就是進入lazy模式之前設置的build_graph_state(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/framework/graph_build_util.py#L220)。從而增加一個FeedVariableOp到計算圖(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/framework/op_interpreter/lazy_op_interpreter.cpp#L527)。為什么設置和調(diào)用會距離這么遠呢?主要是為了讓參數(shù)盡量和消費參數(shù)的 Operator 在一個作用域下,所以實現(xiàn)成了惰性求值來達到延遲計算的目的。

再后面的步驟就是調(diào)用__build_io(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/graph.py#L869-L875)插入FetchOutputOp(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/framework/op_interpreter/lazy_op_interpreter.cpp#L589)。也就是說,獲取model的output也是一個op。

到目前為止,前向計算圖就構(gòu)建完成了。它的json表示可以參考附錄。net.op是計算圖的節(jié)點,通過input等屬性可以看出節(jié)點之間的連接關系。

示例代碼的前向計算圖如下。從這個圖可以看到,input、output、weights等都是op。

5.4 邏輯圖優(yōu)化

在__build_graph中會調(diào)用CurJobBuildAndInferCtx_Complete對靜態(tài)圖進行多輪優(yōu)化(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/graph.py#L923),對應的C++函數(shù)是LazyJobBuildAndInferCtx::Complete()(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/job/job_build_and_infer_ctx.cpp#L975)。

這之后生成的Job是full_job。本文的示例代碼比較簡單,并不是典型的計算場景,其forwar和ful計算圖的拓撲是一樣的。實際大部的圖優(yōu)化都實現(xiàn)在這個階段,如 Op fusion、AMP、ZeRO、常量折疊等等。

到這里,邏輯圖構(gòu)建的主體部分就結(jié)束了。

隨后會構(gòu)建一個CNNGraph對象(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/graph.py#L947),對應的C++類型是NNGraph(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/framework/nn_graph.h#L33)。這個對象將負責構(gòu)建物理計算圖Plan。它也是整個運行時的擁有者和維護者。這個對象析構(gòu)時,整個運行時也會有序終止并釋放資源。

5.5 物理圖的編譯

接下來就是執(zhí)行finish_complie_and_init_runtime(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/graph.py#L742),其中的核心調(diào)用是self._c_nn_graph.complie_and_init_runtime()(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/python/oneflow/nn/graph/graph.py#L802),對應的C++函數(shù)是NNGraph::CompileAndInitRuntime(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/framework/nn_graph.cpp#L265)。

在這個函數(shù)中,JobCompleter().Complete()(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/framework/nn_graph.cpp#L280)會繼續(xù)對邏輯圖做幾輪修改優(yōu)化,補全 Runtime 執(zhí)行所需要的附加信息,Compiler().Compile()(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/framework/nn_graph.cpp#L285)將邏輯圖轉(zhuǎn)為分設備的物理圖,并繼續(xù)對Plan進行修改優(yōu)化。

Plan的編譯是在master節(jié)點進行的(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/framework/nn_graph.cpp#L282)。master節(jié)點會將Plan通過gRPC推送給各個worker節(jié)點(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/framework/nn_graph.cpp#L308),worker節(jié)點從master拉取物理計算圖(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/framework/nn_graph.cpp#L310)。

之后調(diào)用NewRuntimeBuffers創(chuàng)建Buffer對象(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/framework/nn_graph.cpp#L322),Buffer應該是主要用于進程內(nèi)的信息同步。

然后就準備初始化運行時了。

示例代碼生成的compiled_job和物理圖Plan的json參見附錄。

最終生成的compiled邏輯圖如下??蚣茏詣硬迦肓撕芏嘞到y(tǒng)控制節(jié)點。

5.6 Plan的結(jié)構(gòu)

示例代碼輸出的Plan json數(shù)據(jù)見附錄。

Plan在邏輯上和compiled_job是等價的。這里主要關注task/op之間的關系。

Plan.task中的每個元素是一個task,其中的exec_sequence.exec_node對應job中的op,通常只有一個op(數(shù)組可以支持sub graph)。

exec_node.kernel_conf.op_attribute描述了op信息。其中op_conf包含op name信息。

kernel_conf.op_attribute.op_conf就是Job中的OperatorConf。

kernel_conf.op_attribute.arg_signature.bn_in_op2lbi體現(xiàn)了task/op之間的連接關系。

bn_in_op就是blob name in op,即op輸入的blob name。

以System-AutoTick-DstSubsetTick_21為例

{ "out": { "op_name": "System-AutoTick-DstSubsetTick_21", "blob_name": "out" }, "in_0": { "op_name": "System-EagerCriticalSection-Interface-End-Tick-19", "blob_name": "out" }, "in_1": { "op_name": "System-AutoTick-SrcSubsetTick_20", "blob_name": "out" }}

exec_node.bn_in_op2regst_desc_id在task層面體現(xiàn)了連接關系。這個map中的key表示輸入輸出,value是register id。

{"out": "29","in_0": "27","in_1": "28"}

task.produced_regst_desc描述了對應task生產(chǎn)的register,consumer_task_id是消費者,

produced_regst_desc.out.regst_desc_type.data_regst_desc.lbi2blob_desc.lbi就是這個register的logic blob id。

task.consumed_regst_desc_id描述了對應task消費的register信息

6?

運行時的初始化

NNGraph::CompileAndInitRuntime中,new Runtime這行代碼會初始化運行時(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/framework/nn_graph.cpp#L331)。主要做的事情包括:

創(chuàng)建Thread

通知Thread創(chuàng)建Actor,Actor會創(chuàng)建Regst和Kernel

給沒有輸入的source_tasks發(fā)送啟動信號kStart

6.1 Runtime創(chuàng)建Thread

在Runtime的構(gòu)造函數(shù)中,DumpThreadIdsFromPlan(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/job/runtime.cpp#L65)會將Plan中屬于當前進程的task的thread id存入thread_ids_變量。AddThreads創(chuàng)建這些Thread對象(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/job/runtime.cpp#L69)。

Thread在構(gòu)造時會創(chuàng)建一個物理線程(?https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/thread/thread.cpp#L39),線程執(zhí)行的是PollMsgChannel方法(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/thread/thread.cpp#L44),Thread就是在這里持續(xù)等待需要處理的新消息。

Thread只處理兩類命令消息:線程終止消息,創(chuàng)建Actor的消息。其它消息交給Actor::ProcessMsg處理(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/thread/thread.cpp#L83)。

6.2 Runtime通知Thread創(chuàng)建Actor

在Runtime的構(gòu)造函數(shù)中,tasks被分為兩類:source_tasks和other_tasks。在示例代碼中,source_tasks(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/job/runtime.cpp#L84-L85)是沒有輸入邊的task。

從代碼邏輯看,在Plan proto中,task的consumed_regst_desc_id字段是一個map。如果這個map的所有key都是in_ctrl(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/job/runtime.cpp#L54),這個task就是source_tasks。

一些source_tasks的示例如下:

System-Src-WaitAndSendIds_16

System-AutoTick-AppendDeviceTick_9

System-EagerCriticalSection-Interface-End-Tick-19

System-EagerCriticalSection-Interface-End-Tick-25

Runtime調(diào)用HandoutTasks函數(shù)(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/job/runtime.cpp#L100-L101)會給ActorMsgBus發(fā)送構(gòu)建Actor的kConstructActor消息(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/job/runtime.cpp#L49)。

6.3 ActorMsgBus和Thread的消息處理

從接口看,ActorMsgBus?(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/lazy/actor/actor_message_bus.cpp#L24)負責消息的發(fā)送(Actor通過ActorMsgBus發(fā)送消息),Thread::PollMsgChannel(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.1/oneflow/core/thread/thread.cpp#L60) 負責消息的接收和處理。

相關實體的協(xié)作關系如下

Actor是自調(diào)度的基本單元,接受消息然后工作,工作完后再繼續(xù)發(fā)送消息。

actor_id就是task_id,是在編譯Plan時就確定的。task是編譯時概念,actor是對等的運行時概念。

task_id有特定的編碼格式(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/graph/task_id.cpp#L21-L29),從中可以解析出machine_id(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/graph/task_id.cpp#L73)和thread_id(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/graph/task_id.cpp#L77)。

在跨網(wǎng)絡的整個物理圖Plan中,actor id相當于地址,通過它可以定位唯一的actor實體。

Actor 通過 ActorMsgBus::SendMsg(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/lazy/actor/actor_message_bus.cpp#L24) 發(fā)送 ActorMsg(https://github.com/Oneflow-Inc/oneflow/blob/4856d691051accd72f13f4139d281e411977b297/oneflow/core/lazy/actor/actor_message.h#L34) 消息。

ActorMsg包含源和目的actor id(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/lazy/actor/actor_message.h#L84-L85)。

如果是進程內(nèi)通訊(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/lazy/actor/actor_message_bus.cpp#L26),將通過 ActorMsgBus::SendMsgWithoutCommNet?(https://github.com/Oneflow-Inc/oneflow/blob/4856d691051accd72f13f4139d281e411977b297/oneflow/core/lazy/actor/actor_message_bus.cpp#L49)把 ActorMsg 朝目的 actor 所在的 thread 入隊消息(https://github.com/Oneflow-Inc/oneflow/blob/4856d691051accd72f13f4139d281e411977b297/oneflow/core/thread/thread.h#L40)。

Thread::EnqueueActorMsg 會判斷當前 thread 是否是 actor thread,如果是則入本地隊列,否則則入 actor thead 的 channel 隊列。

如果ActorMsg是跨進程消息,ActorMsgBus通過CommNet發(fā)送消息(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/lazy/actor/actor_message_bus.cpp#L42-L44),接收方的CommNet應該會根據(jù)actor id獲得線程id,從ThreadMgr查到Thread,將消息交給Thread處理。

Thread::PollMsgChannel(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.1/oneflow/core/thread/thread.cpp#L60) 負責消息的接收和處理。

如果線程本地隊列l(wèi)ocal_msg_queue_為空,則從thread的channel隊列中取出全部ActorMsg放入本地隊列(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.1/oneflow/core/thread/thread.cpp#L63)。

從本地隊列中取出一個ActorMsg,然后開始處理。

處理一些特殊的kCmdMsg消息(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.1/oneflow/core/thread/thread.cpp#L67-L79),然后普通消息交給Actor自行處理(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.1/oneflow/core/thread/thread.cpp#L83)。

Actor收到消息后,會判斷是否滿足了Act的條件,如果滿足,則會執(zhí)行Act,從而調(diào)用LaunchKernel執(zhí)行計算,Act執(zhí)行結(jié)束后通過ActorMsgBus發(fā)消息通知上下游Actor。

這些對象之間的消息傳遞關系如下圖所示

6.4 激活source Actor

目前的實現(xiàn)中,Actor全部是自調(diào)度的,只能接受來自其他Actor的消息。Actor中有一類比較特殊的source actors,它們與source tasks對應。

source actors 沒有上游 actor,它們會朝下游actor發(fā)送消息從而激活所有的Actor運行。

source actors 本身是如何執(zhí)行的呢?它們在接受到 kStart 消息后就會一直 Act 直到進入退出流程。但是其 kernel 會阻塞在 Buffer(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.1/oneflow/core/common/buffer.h#L26) 處,一直等待其他線程往 buffer 中添加數(shù)據(jù)后,阻塞會被激活,然后 kernel 執(zhí)行讀取,kernel 完成后,actor 的 Act 結(jié)束,往下游發(fā)送消息。

source actors 由于會發(fā)生阻塞,所以其必須有單獨的 actor thread。

Runtime 初始化的的最后一步就是朝各 source actors 發(fā)送 kStart 消息用以激活它們,但 source actors 只有接受到 buffer 的數(shù)據(jù)后才會往下執(zhí)行,然后朝下游 actors 發(fā)送消息,使所有的 actors 都執(zhí)行起來。

7?

Actor

7.1 Actor的創(chuàng)建

Thread在創(chuàng)建Actor時,會先嘗試創(chuàng)建為LightActor(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/thread/thread.cpp#L104),如果不成功,再嘗試用預先注冊的工廠創(chuàng)建Actor。

有幾種TaskType可以用于LightActor(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/lazy/actor/light_actor.cpp#L677-L689):

kNormalForward,比如matmul、add等user op。

kCopyHd

kTick

kCollectiveBoxingGeneric

目前大約有20多種Actor的子類型。其它Actor類型根據(jù)TaskType(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/job/task.proto#L8)預先注冊。例如WaitAndSendIdsActor。

示例代碼的各個節(jié)點對應的actor類型參見附錄。

Actor相關的類關系如下(包含關系只是表示可以訪問到相關信息,并不意味著創(chuàng)建或著擁有該類型對象)

7.2 Actor的初始化

Actor的構(gòu)造函數(shù)一般都是空的,構(gòu)建之后需要執(zhí)行Init(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/lazy/actor/actor.cpp#L129)函數(shù)進行初始化。

LightActor繼承自ActorBase,不是Actor的子類,有自己的Init函數(shù)實現(xiàn)。這里只討論Actor的初始化。

在Actor::Init(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/lazy/actor/actor.cpp#L129)中,首先調(diào)用ConstructKernel(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/lazy/actor/actor.cpp#L138)創(chuàng)建kernel實例。和Operator類似,kernel也是以OpTypeCase作為注冊的key,例如WaitAndSendIdsKernel(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/kernel/wait_and_send_ids_kernel.cpp#L51)。一個Actor通常只有一個kernel。

之后調(diào)用NewRegsts創(chuàng)建Regst(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/lazy/actor/actor.cpp#L152)。Tensor是用戶側(cè)的概念。對應的運行時概念是Regst(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/register/register.h#L24),它持有Kernel需要讀寫的內(nèi)存。Regst的概念比Tensor更寬泛,比如框架自動添加的控制Op也會用到Regst。

Actor將自己創(chuàng)建的Regst保存到produced_regsts_(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/lazy/actor/actor.cpp#L153)。

TakeOverNaiveConsumed(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/lazy/actor/actor.cpp#L182)只記錄需要消費的regst id,但并不push到consumed_regsts_。

TakeOverNaiveProduced(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/lazy/actor/actor.cpp#L183)既記錄生產(chǎn)的regst id,也push到naive_produced_rs_(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/lazy/actor/actor.cpp#L249)。這種區(qū)別是為了首次執(zhí)行計算時,actor能順利執(zhí)行。后面分析Actor的消息處理時會再回過頭來討論一下。

調(diào)用InitBnInOp2BlobInfo會初始化BlobInfo(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/lazy/actor/actor.cpp#L184)。

之后就是調(diào)用VirtualActorInit(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/lazy/actor/actor.cpp#L185),這里允許各個Actor子類定制自己的初始化邏輯。通常會調(diào)用OF_SET_MSG_HANDLER宏(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.0/oneflow/core/lazy/actor/actor.h#L76-L80)設置Actor的消息處理函數(shù)。

7.3 Actor的消息處理

LightActor 首先會根據(jù)消息類型分別處理 kRegstMsg 和 kEordMsg 消息。HandleRegstMsg(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.1/oneflow/core/lazy/actor/light_actor.cpp#L424) 中根據(jù) RegstMsg 的 type (kProduced 或 kComsumed) 來分別處理各種讀寫狀態(tài)計數(shù)。

然后判斷讀寫計數(shù)是否達到了判斷條件,如果達到了意味著滿足了讀寫 regst 的條件,然后就 執(zhí)行 ActOnce(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.1/oneflow/core/lazy/actor/light_actor.cpp#L451)。

LightActor::ActOnce 會在第一次執(zhí)行時去 InitBnInOp2Blob 和 InitActMsg。InitBnInOp2Blob 初始化 resgt 中的 bn 與 Blob 的映射關系,為 kernel 提供通過 bn 訪問 Blob 的功能。InitActMsg 會初始化好所有需要發(fā)送的消息避免后繼發(fā)消息時重復的構(gòu)建消息。

然后就是 LaunchKernel,接著會 ResetState 重置 regst 狀態(tài)。

LaunchKernel 后就會把之前構(gòu)建好的消息發(fā)送出去,同步消息會直接入隊 thread 消息隊列,異步消息通過 callback 發(fā)送到 ActorMsgBus。

普通 Actor::ProcessMsg 會調(diào)用 msg handler 來處理消息,最常見的 msg handler 就是 Actor::HandlerNormal(https://github.com/Oneflow-Inc/oneflow/blob/release/v0.8.1/oneflow/core/lazy/actor/actor.cpp#L329)。

Actor::HandlerNormal 中流程跟 LightActor 中類似,會根據(jù)不同的 regst 類型來分別處理,Actor 中對 regst 的狀態(tài)管理方式與 LightActor 不同,LightActor 中的方式更加高效,Actor 中能處理一些特殊情況。

消息處理完畢后,就會調(diào)用 ActUntilFail,ActUntilFail 會判斷 IsReadReady 和 IsWriteReady 來決定是否可以進行 Act。

最常見的 NaiveActor::Act() 就是執(zhí)行 AsyncLaunchKernel。

Act 完成后,就開始朝上下游發(fā)送 regst 消息。

還有一些特殊的 Actor,我們以WaitAndSendIdsActor為例,觀察一下這類Actor的消息處理機制。

之所以選擇這個例子,一是這個Actor比較簡單;二是這是一個典型的source task,想看一下計算圖是怎么被觸發(fā)啟動計算的。

Thread收到的消息如果不是kStopThread或kConstructActor,就調(diào)用Actor::ProcessMsg(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/thread/thread.cpp#L83),將消息轉(zhuǎn)給Actor處理。

ProcessMsg函數(shù)只是簡單的將消息轉(zhuǎn)給handler處理(https://github.com/Oneflow-Inc/oneflow/blob/b6bf3f8843679111eb1edf79deefce814d250f4e/oneflow/core/lazy/actor/actor.h#L38)。

WaitAndSendIdsActor::VirtualActorInit中,handler被設置為HandlerWaitToStart(https://github.com/Oneflow-Inc/oneflow/blob/22f70a1719f371a54512633bb92086580d9c3c89/oneflow/core/lazy/actor/wait_and_send_ids_actor.cpp#L53)。

Runtime的構(gòu)造函數(shù)中,發(fā)送的第一批消息是給source_tasks的kStart消息,這個消息就由HandlerWaitToStart函數(shù)處理。

HandlerWaitToStart校驗消息類型后,將handler設置為HandlerNormal(https://github.com/Oneflow-Inc/oneflow/blob/b17a9cd6b930b5817c63623fb682bd708377a93b/oneflow/core/job/runtime.cpp#L109)(這也是大部分Actor的默認handler),然后調(diào)用ProcessMsg(https://github.com/Oneflow-Inc/oneflow/blob/22f70a1719f371a54512633bb92086580d9c3c89/oneflow/core/lazy/actor/wait_and_send_ids_actor.cpp#L74),實際就是調(diào)用新設置的handler HandlerNormal。

HandlerNormal中,如果是kCmdMsg,只允許是kStart(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L377)。通過消息類型校驗后,會直接調(diào)用ActUntilFail(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L378)。

7.4 Act執(zhí)行的條件

LightActor 和 Actor 判斷能否進行 Act 采用了不同的策略,LightActor 的效率更高,Actor 能處理一些特殊情況。

對于 LightActor,當在讀的register計數(shù) total_reading_cnt_ 歸 0,可消費的register計數(shù) ready_consumed_ 增加到 max_ready_consumed_,前者表示所有的消費者已經(jīng)讀取當前 LightActor 的 Regst,后者表示當前 LightActor 消費的所有 Regst 已經(jīng)到達(由上游發(fā)送的 Regst 消息)。

對于 Actor,Actor::ActUntilFail中,Act方法(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L424)是各個子類自己實現(xiàn)的,一般主要是啟動kernel計算。

但是在執(zhí)行Act之前,需要先確認:

Act執(zhí)行依賴的數(shù)據(jù)是否都已經(jīng)就緒?(IsReadReady)

Act生產(chǎn)出來的數(shù)據(jù),消費方是否已經(jīng)用完、并收到ack消息確認?(IsWriteReady)

Actor有4個與此相關的成員變量

RegstSlot naive_produced_rs_;

RegstSlot inplace_produced_rs_;

RegstSlot naive_consumed_rs_;

RegstSlot inplace_consumed_rs_;

xx_produced_rs_存儲的是當前Actor的下游consumer返回的、已經(jīng)使用完畢的ack regst信息。(當前Actor生產(chǎn)的Regst存儲在produced_regsts_中。)

運行時在初始化的過程中,所有Actor都沒有運行過,任何Actor都不可能收到ack消息,所以在Actor初始化時,要預先填充xx_produced_rs_,這樣才能保證Actor在首次運行前是WriteReady的,才能順利啟動執(zhí)行。

xx_consumed_rs_存儲的是上游依賴發(fā)來的數(shù)據(jù)。它不需要預先填充。因為source_tasks沒有輸入依賴,自然就是ReadReady的;而xx_produced_rs_在初始化時的預先填充又保證它是WriteReady的,所以source_tasks可以直接運行。source_tasks的輸出消息發(fā)給下游,下游也會變?yōu)镽eadReady,而下游在初始化后也保證是WriteReady的。整個Actor系統(tǒng)就可以這樣運轉(zhuǎn)起來了。

7.5 Actor上下游之間的通知機制

Act執(zhí)行完畢后,需要將結(jié)果數(shù)據(jù)發(fā)給下游consumer。以 WaitAndSendIds 的 Naive Produced 為例,ActUntilFail中的調(diào)用流程如下:

AsyncSendNaiveProducedRegstMsgToConsumer(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L427

VirtualAsyncSendNaiveProducedRegstMsgToConsumer(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L441

HandleProducedNaiveDataRegstToConsumer(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L446

HandleRegstToConsumer(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L577)

EnqueueAsyncMsg(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L523

如果目標線程是當前線程,ActorMsgBus::SendMsg(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L662

否則,將消息加入async_msg_queue_(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L664

增加 total_reading_cnt_(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L526)(這個變量表示已經(jīng)發(fā)消息給下游、但未收到的ack數(shù)量)

naive_produced_rs_.PopFrontRegsts(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L581

AsyncSendProducedCtrlRegstMsgToConsumer

注意naive_produced_rs_.PopFrontRegsts(https://github.com/Oneflow-Inc/oneflow/blob/06a6af1c7f760ba4b12d2dfb8f73d7fda5c7dbab/oneflow/core/lazy/actor/register_slot.cpp#L53)會將Regst指針從隊列中刪掉,相應的可用(https://github.com/Oneflow-Inc/oneflow/blob/06a6af1c7f760ba4b12d2dfb8f73d7fda5c7dbab/oneflow/core/lazy/actor/register_slot.cpp#L49)register計數(shù)減1(https://github.com/Oneflow-Inc/oneflow/blob/06a6af1c7f760ba4b12d2dfb8f73d7fda5c7dbab/oneflow/core/lazy/actor/register_slot.cpp#L49)。

而在Actor::HandlerNormal中處理收到的kRegstMsg消息(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L340)時,如果是consumer發(fā)來的ack消息,會調(diào)用TryUpdtStateAsProducedRegst(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L355),將Regst再添加到 naive_produced_rs_ 中(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L654),以保證當前Actor在收到所有ack后是WriteReady的;同時遞減在讀的 register 計數(shù)total_reading_cnt_。

Actor對依賴的上游消息的處理是類似的。通過以下函數(shù)調(diào)用給上游發(fā)送ack消息、通知 register 已經(jīng)用完,可以繼續(xù)更新了:

AsyncSendNaiveConsumedRegstMsgToProducer(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L431

AsyncRetInplaceConsumedRegstIfNoConsumer(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L432)在Actor::HandlerNormal中收到kRegstMsg消息后,將消息添加到consumed_rs_(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L344),以保證當前Actor在收到所有依賴數(shù)據(jù)后是ReadReady的。

LightActor有自己的消息處理機制(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/light_actor.cpp#L299),大致原理應該是差不多的。

7.6 Act執(zhí)行的動作

根據(jù)上述討論,Actor收到kRegstMsg后也會進入ActUntilFail執(zhí)行。如果讀寫都是Ready,就執(zhí)行Act(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L424)。以WaitAndSendIdsActor為例,主要調(diào)用鏈路如下:

AsyncLaunchKernel(https://github.com/Oneflow-Inc/oneflow/blob/22f70a1719f371a54512633bb92086580d9c3c89/oneflow/core/lazy/actor/wait_and_send_ids_actor.cpp#L58

ek.kernel->Launch(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L562),啟動Kernel計算

Forward(https://github.com/Oneflow-Inc/oneflow/blob/eae9ff38f074479d79ce24b0f6e0594f82126171/oneflow/core/kernel/kernel.cpp#L52

ForwardDataContent(https://github.com/Oneflow-Inc/oneflow/blob/eae9ff38f074479d79ce24b0f6e0594f82126171/oneflow/core/kernel/kernel.cpp#L65

buffer->Pull(https://github.com/Oneflow-Inc/oneflow/blob/b17a9cd6b930b5817c63623fb682bd708377a93b/oneflow/core/kernel/wait_and_send_ids_kernel.cpp#L40

給regst的存儲地址mut_dptr賦值(https://github.com/Oneflow-Inc/oneflow/blob/b17a9cd6b930b5817c63623fb682bd708377a93b/oneflow/core/kernel/wait_and_send_ids_kernel.cpp#L47

buffer->Pull會等待條件變量的通知(https://github.com/Oneflow-Inc/oneflow/blob/49f60e682518436dfeb37344a15902a959e0e4f2/oneflow/core/common/buffer.h#L60)。現(xiàn)在,看上去所有Actor都已準備就緒,只等發(fā)令槍一響就開跑了。

8?

啟動靜態(tài)圖的計算

Graph.__run(https://github.com/Oneflow-Inc/oneflow/blob/81edd938826a7ea903174d682348847658b64653/python/oneflow/nn/graph/graph.py#L226)會扣動發(fā)令槍的板機,啟動計算圖的一輪計算。

主要調(diào)用流程如下:

RunLazyNNGraph(https://github.com/Oneflow-Inc/oneflow/blob/81edd938826a7ea903174d682348847658b64653/python/oneflow/nn/graph/graph.py#L1076

builder->LaunchLazyJob(https://github.com/Oneflow-Inc/oneflow/blob/8f672eea116cae4a73bb7309e7496b08d7ec9a32/oneflow/core/framework/nn_graph.cpp#L568

LaunchLazyJobInstructionType(https://github.com/Oneflow-Inc/oneflow/blob/8f672eea116cae4a73bb7309e7496b08d7ec9a32/oneflow/core/framework/instructions_builder.cpp#L179

Buffer::Push(https://github.com/Oneflow-Inc/oneflow/blob/8f672eea116cae4a73bb7309e7496b08d7ec9a32/oneflow/core/framework/instructions_builder.cpp#L179

這里的Buffer::Push就是WaitAndSendIdsKernel在等待的起跑信號。

9?

運行時的退出機制

整個運行時包含很多對象和資源,安全有序的退出是龐雜而又細致的工作。這里僅以WaitAndSendIds為例,從一個側(cè)面觀察一下運行時的退出機制。

運行時的退出始于NNGraph對象的析構(gòu)(https://github.com/Oneflow-Inc/oneflow/blob/8f672eea116cae4a73bb7309e7496b08d7ec9a32/oneflow/core/framework/nn_graph.cpp#L76)。

9.1 Actor的退出

NNGraph在析構(gòu)時,會關閉所有的Buffer對象(https://github.com/Oneflow-Inc/oneflow/blob/8f672eea116cae4a73bb7309e7496b08d7ec9a32/oneflow/core/framework/nn_graph.cpp#L82)。

Buffer在關閉時,會設置is_closed_ = true并通知所有監(jiān)聽者(https://github.com/Oneflow-Inc/oneflow/blob/49f60e682518436dfeb37344a15902a959e0e4f2/oneflow/core/common/buffer.h#L81)。但是Pull會繼續(xù)處理完已經(jīng)提交的計算。

所以,Buffer應該是主要用于進程內(nèi)的通信和異步協(xié)調(diào)的一個類。

WaitAndSendIdsKernel這時候正在等待新一輪計算開始(https://github.com/Oneflow-Inc/oneflow/blob/b17a9cd6b930b5817c63623fb682bd708377a93b/oneflow/core/kernel/wait_and_send_ids_kernel.cpp#L40),結(jié)果收到Pull返回的kBufferStatusErrorClosed(https://github.com/Oneflow-Inc/oneflow/blob/49f60e682518436dfeb37344a15902a959e0e4f2/oneflow/core/common/buffer.h#L61)。

WaitAndSendIdsActor::IsCustomizedReadReady以后就一直返回false(https://github.com/Oneflow-Inc/oneflow/blob/22f70a1719f371a54512633bb92086580d9c3c89/oneflow/core/lazy/actor/wait_and_send_ids_actor.cpp#L68),IsReadReady也返回false(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L533)。

這之后,ActUntilFail只會執(zhí)行異步消息發(fā)送(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L437)(不再進入while循環(huán))

WaitAndSendIdsActor::HandlerNormal仍然會處理其它Actor發(fā)來的消息(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L340)。但因為IsCustomizedReadReady返回false,會進入AsyncSendEORDMsgForAllProducedRegstDesc(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L394)執(zhí)行。它會給每個下游發(fā)送kEordMsg消息(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L614)。

Actor在收到上游發(fā)來的kEordMsg消息后,遞減remaining_eord_cnt_(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L331)。

remaining_eord_cnt_被初始化為Actor的輸入regst的數(shù)量(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L171)。

total_reading_cnt_是當前Actor生產(chǎn)的、已經(jīng)發(fā)給consumer、但尚未收到ack的消息數(shù)量。

Actor目前仍可以正常接收consumer發(fā)來的ack消息。

當上述2個變量都為0時(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L395),意味著所有上游都發(fā)出了kEordMsg消息,也收到了所有下游的ack消息。Actor就給Thread返回1(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L397)。

如果上述兩個變量有不為0的,就修改handler,由HandlerZombie(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/lazy/actor/actor.cpp#L399)處理后續(xù)收到的消息。

Thread收到Actor返回的1后(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/thread/thread.cpp#L84),將它從自己的存儲中刪除(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/thread/thread.cpp#L89),并遞減運行Actor的數(shù)量。

9.2 Thread的退出

NNGraph重置runtime_導致運行時對象被析構(gòu)(https://github.com/Oneflow-Inc/oneflow/blob/8f672eea116cae4a73bb7309e7496b08d7ec9a32/oneflow/core/framework/nn_graph.cpp#L83)。

Runtime刪除所有Thread(https://github.com/Oneflow-Inc/oneflow/blob/b17a9cd6b930b5817c63623fb682bd708377a93b/oneflow/core/job/runtime.cpp#L117)。

ThreadMgr給所有Thread發(fā)送kStopThread消息(https://github.com/Oneflow-Inc/oneflow/blob/c8c6d351fa28c5ebce948d69c06670a783f83f74/oneflow/core/thread/thread_manager.cpp#L64)。同時,重置指針導致Thread析構(gòu)(https://github.com/Oneflow-Inc/oneflow/blob/c8c6d351fa28c5ebce948d69c06670a783f83f74/oneflow/core/thread/thread_manager.cpp#L66)。

Thread的物理線程退出PollMsgChannel循環(huán)(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/thread/thread.cpp#L68)。

Thread等待物理線程結(jié)束,關閉channel(https://github.com/Oneflow-Inc/oneflow/blob/55b822e4d3c88757d11077d7546981309125c73f/oneflow/core/thread/thread.cpp#L52)。

10?

分布式場景的靜態(tài)圖

分布式的compile_job、物理圖Plan和單機場景有明顯變化。

比如,每個進程都有一套WaitAndSendIds等控制節(jié)點。這也容易理解,因為每個節(jié)點都要執(zhí)行__run和Buffer::Push/Pull,都要啟動本進程的Actors執(zhí)行計算。

matmul和broadcast_add等user op也會在兩個節(jié)點進行計算。 ?

10.1 示例代碼

啟動方式參考Global Tensor的官方文檔。

import oneflow as flowimport oneflow.nn as nnP0 = flow.placement("cpu", ranks=[0, 1])a0_sbp = flow.sbp.split(0)class ModuleMyLinear(nn.Module): def __init__(self, in_features, out_features): super().__init__() self.weight = nn.Parameter(flow.randn(in_features, out_features, placement=P0, sbp=flow.sbp.broadcast)) self.bias = nn.Parameter(flow.randn(1, out_features, placement=P0, sbp=flow.sbp.broadcast)) def forward(self, input): return flow.matmul(input, self.weight) + self.biaslinear_model = ModuleMyLinear(4, 3)class GraphMyLinear(nn.Graph): def __init__(self): super().__init__() # ModuleBlock self.model = linear_model def build(self, input): # ModuleBlock.__call__ return self.model(input)graph_mylinear = GraphMyLinear()input = flow.randn(5, 4, placement=P0, sbp=flow.sbp.split(1))out = graph_mylinear(input)print(out)

11?

附錄

11.1 斷點

11.1.1 Python斷點示例

# python3 -m pdb test.pybreak test.py:25break oneflow/nn/graph/graph.py:221break oneflow/nn/graph/graph.py:741break oneflow/nn/graph/graph.py:745break oneflow/nn/graph/graph.py:759break oneflow/nn/graph/graph.py:828break oneflow/nn/graph/graph.py:777break oneflow/nn/graph/graph.py:1066break oneflow/nn/graph/graph.py:1133break oneflow/framework/graph_build_util.py:227

11.1.2 C++斷點示例

啟動命令

source /mnt/oneflow/build/source.shgdb --args python3 /mnt/oneflow/test.py# set breakpoints# run

斷點示例

set breakpoint pending onbreak oneflow::ActorMsg::BuildEordMsgbreak oneflow/core/common/buffer.h:80break oneflow::(anonymous namespace)::CheckAndConstructOpbreak oneflow::WaitAndSendIdsActor::Actbreak oneflow::WaitAndSendIdsActor::HandlerWaitToStartbreak oneflow/core/lazy/actor/light_actor.cpp:452break oneflow/core/lazy/actor/light_actor.cpp:485break oneflow::ForeignInputKernel::ForwardDataContentbreak oneflow::vm::LaunchLazyJobInstructionType::Compute

11.2 靜態(tài)圖的json表示

forward(https://quip.com/OMc4A0HOOr0C)

full(https://quip.com/JLaMAHGBLXmK)

compiled(https://quip.com/tXjuAiS3J0Ab)

plan(https://quip.com/a0DMAAIte6PQ)

11.3 actor type

naive_actor

System-AutoTick-AppendDeviceTick_9System-AutoTick-DstSubsetTick_12System-AutoTick-DstSubsetTick_21System-AutoTick-DstSubsetTick_27System-AutoTick-Prepend-DeviceTick_7System-AutoTick-SrcSubsetTick_20System-AutoTick-SrcSubsetTick_26System-AutoTick-SrcSubsetTick_8System-AutoTick-Tick_11System-AutoTick-Tick_13System-EagerCriticalSection-Callback-23System-EagerCriticalSection-Callback-29System-EagerCriticalSection-Interface-Begin-Tick-18System-EagerCriticalSection-Interface-Begin-Tick-24System-EagerCriticalSection-Interface-End-Tick-19System-EagerCriticalSection-Interface-End-Tick-25System-EagerCriticalSection-Wait-22System-EagerCriticalSection-Wait-28

light_actor

_GraphMyLinear_0_input.0.0_2_GraphMyLinear_0_output.0.0_2model.biasmodel-broadcast_add-1model-matmul-0model.weightSystem-AutoTick-SinkTick_15System-SyncAllRanksSinkTick_14

wait_and_send_ids_actor

???System-Src-WaitAndSendIds_16

call_back_notify_actor

???System-Sink-CallbackNotify_17

12?

參考資料

oneflow v0.8.0(https://github.com/Oneflow-Inc/oneflow/tree/release/v0.8.0)

OneFlow框架的系統(tǒng)設計(上篇)(https://zhuanlan.zhihu.com/p/337851255)

OneFlow框架的系統(tǒng)設計(中篇)(https://zhuanlan.zhihu.com/p/338699487)

OneFlow框架的系統(tǒng)設計(下篇)(https://zhuanlan.zhihu.com/p/339208452)

一個Job在OneFlow中的執(zhí)行過程—上篇(https://zhuanlan.zhihu.com/p/344531540)

一個Job在OneFlow中的執(zhí)行過程—中篇(https://zhuanlan.zhihu.com/p/355654002)

一個Job在OneFlow中的執(zhí)行過程—下篇(https://zhuanlan.zhihu.com/p/363689736)

靜態(tài)圖模塊 nn.Graph(https://docs.oneflow.org/master/basics/08_nn_graph.html)

OneFlow系統(tǒng)設計(https://docs.oneflow.org/v0.4.0/basics_topics/essentials_of_oneflow.html)

torch.nn.Module(https://pytorch.org/docs/1.10/generated/torch.nn.Module.html)

其他人都在看

OneFlow源碼解析:自動微分機制

ChatGPT的一小步,NLP范式轉(zhuǎn)變的一大步

李白:你的模型權(quán)重很不錯,可惜被我沒收了

OpenAI掌門Sam Altman:AI下一個發(fā)展階段

32篇年度最佳AI論文;Python編譯器Codon開源

比快更快,開源Stable Diffusion刷新作圖速度

OneEmbedding:單卡訓練TB級推薦模型不是夢

歡迎Star、試用OneFlow最新版本:GitHub - Oneflow-Inc/oneflow: OneFlow is a deep learning framework designed to be user-friendly, scalable and efficient.OneFlow is a deep learning framework designed to be user-friendly, scalable and efficient. - GitHub - Oneflow-Inc/oneflow: OneFlow is a deep learning framework designed to be user-friendly, scalable and efficient.https://github.com/Oneflow-Inc/oneflow/

關鍵詞:

日韩熟女少妇一区二区三区| 欧美一区二区国产一区| av在线中文字幕资源网| 亚洲人妻一区二区91| 中文字幕无码中文字幕有码在线| 熟女人妻专区中文字幕| 国产高清在线一区不卡极品| av在线不卡中文字幕宾馆| 亚洲真人丝袜av一区二区| 中文字幕人妻在线乱码搞| 在线播放一区二区三区三州| 少妇一区二区三区粉嫩av| 久久久久久人妻精品一区| 亚洲无码AV在线免费观| 国产性一交一乱―色―情人| 91在线视频网站总站| 免费的黄网站在线观看视频| 国产aV无码片毛片一级韩国| 欧美一区二区三区aa大片漫| 国产精品成人免费av| 精久久中文字幕人妻最新| av在线中文字幕播放| 精品成人一区二区三区在线观看| 在线观看的资源网97| 国产亚洲精品成人av丝袜| 欧美情色大片在线观看| 欧美中文字幕乱码在线播放| 精选国产精品视频在线| 日韩成人av在线二区| 欧美日韩激情午夜看片| 熟女五十路一区二区三区| 欧美日韩精品一级二级三级| 很黄很色的视频免费在线观看 | 中文字幕人妻欧美日韩熟女| 熟女系列丰满熟妇一区二区三区| 超污短视频网站在线观看| 国产男女淫片av免费观看| 人妻中出中文字幕在线| 日本一区二区三区人妻| 久草视频这里只有精品| 久久久久久久九九九b热| 青青青草原成人在线视频| 亚洲国产99精品国自产 | 日本一区二区三级在线观看| 国产免费无码午夜福利蜜臀| 国产精品自拍首页视频| 国产丝袜另类精品综合| 日本一卡视频在线观看免费| 95国产成人精品视频| 九九久久久久无限久久| 国产亚洲欧美日韩三级| 美女视频吃奶视频在线观看| 91在线国产视频观看| 日本一区二区不卡精品| 亚洲三级一区二区三区四区| 噜噜av在线免费观看| 精品视频在线观看91| 国产精品欧美一区二区久久久 | 欧美一区二区三区伦理国产| 一本92午夜免费不卡福利片 | 我的放荡丝袜美腿老师| 亚洲情色国产自拍偷拍| 亚洲熟女久久一区二区| 久久久久久人妻精品一区| 欧美一区二区三区色污| 猫咪av成人永久网站网址| 亚洲成人av免费在线播放| 成人午夜精品一区二区三区| 白乳房天天官网性插视频| 中文字幕精品久久久乱码乱码| av天堂午夜精品蜜臀| 久久久久久久九九九b热| 521a成v精品视频在线播放| 国产黄色片久久久久久久| 久久99精品久久久久蜜臀| 久久精品中文字幕乱码视频| 国产小视频在线观看你懂得| 香蕉免费一区二区三区在线观看 | 欧美三级精品三级在线| 人妻丝袜美腿中文字幕 | 97超碰人妻在线观看| 日韩精品乱码av在线播放| 男人靠女人靠厉害视频| av中文字幕每日更新| 欧美日韩国产三级在线| 污污黄色免费在线观看| 免费人成在线观看视频高潮| 国产性感丝袜美女av| 国产偷拍自拍在线免费| 97视频在线免费观看网站| 中文字幕中文av在线精品| 成人24小时免费视频| 精品熟妇人妻一区二区三区四区| 日本美女丝袜天天看人体| 啊啊啊啊插进去你好骚视频| 美女自拍偷拍亚洲一区| 精品国产久久三级av| 青青草原精品免费在线视频| 成人在线一区二区三区av| 国产精品成人自拍视频| 91偷拍老熟女露脸合集| 欧美一区二区在线观看网站| 亚洲熟妇色自偷自拍另类图片| 啊啊啊啊插进去你好骚视频| 日本美女丝袜天天看人体| 亚洲乱码精品中文字幕| 人妻少妇激情综合小视频| 在线观看免费黄小视频| 国产av 一区二区三区四区| 成人极品av免费观看| 青青草原免费体验视频| 男人添女人下边视频免费| 国产美女扒开粉嫩尿口网站| 男人操女人的逼免费网站| 国产精品久久久久精品日 | 精品视频在线观看91| 亚洲欧美视频在线观看网站| 色一情一乱一乱一区91Av| 99er在线免费视频| 欧美激情一区二区三区成人| 尤物欧美一区二区三区| 乱文丝袜乱文丝袜美腿视频| 国产高清亚洲精品视频| 久久久久久人妻精品一区| 午夜18在线观看视频| 久久久久久噜噜噜久久久精品| 国产自拍偷拍在线免费| 激情av一区av二区| 国产成人不卡在线视频| 99久久国产综合精品五月天| 中文字幕在线日韩第一精品| 国内精品人妻久久激情| 丰满美女一区二区三区| 香蕉免费一区二区三区在线观看| 国产高清亚洲精品视频| 美女自拍偷拍亚洲一区| 久草视频这里只有精品| 91最新精品视频在线观看| 黄色污染网站在线观看| 久久无语av中文字幕| 女人嫩水逼让大鸡巴操免费看| 国产白嫩在线观看视频| 精品欧美成人观看一级| 亚洲黄色av中文字幕| 老男人xx女人视频试看| 成人亚洲精品在线观看| 国产91情侣在线视频| 老师美女脱了内裤露屁股| 中文字幕乱码在线视频网站| 久久久久久久九九九b热| 午夜免费福利视频大全| 国产欧美一区二区精品性| 亚洲欧美另类视频一区蜜臀| 能效等级一级二级三级| 好吊色欧美一区二区三区四区| 青青热久免费精品视频| 三级国产精品久久久99| 国产97自拍视频在线观看| 午夜精彩视频网站免费观看 | 91性色福利在线视频| 综合久久国产中文人妻少妇在线| 自拍偷拍亚洲综合在线| 亚洲一区二区欧美激情| 高潮喷水波多野结衣在线观看 | 成年人黄视频免费观看网站| 午夜97视频在线观看| 欧美青青一区二区三区| 三级成人一区二区三区| 久久国产精品亚洲va麻豆| 91成人资源在线观看| 国产网红主播在线观看视频| 人妻系列少妇极品熟妇| 黄色在线观看不卡无广告| 人妻熟女欧美一区二区| 国产69精品久久久久久妇| 中文字幕人妻免费网站| 91成人精品亚洲国产| 欧美日韩一区二区三区性| 亚洲av乱码在线观看| 久久久亚洲裙底偷窥综合| 国产午夜高潮熟女精品| 日本熟日本熟妇中文在线观看| 大乳美女疯狂榨取精子视频| 国产精品久久久久久久久91| 欧美一区二区三区再线播放| 黄色的网站免费在线看| 蜜臀av入口一区二区三区| 日韩 国产 欧美 在线 一区| 你在线上av中文字幕| 精品国产乱码久久久久夂| 老熟女 一区二区三区| 91/日韩/精品/乱码| 97免费视频国产在线观看| 男人插女人逼免费视频| 色偷偷av一区二区三区| 成人啪精品视频网站午夜| 99热爱精品在线观看| 人妻又爱又澡人人添人人爽| 欧美日韩国产三级在线| 在线播放网站一区二区三区| 亚洲激情视频在线观看视频| 免费一区二区三区四区av| 日韩美女肥臀毛茸茸的阴穴| 色av蜜臀av粉嫩av| 青春草视频免费观看在线| 一级成人欧美一区在线观看| 亚洲黄色av中文字幕| 欧美激情视频免费观看| 亚洲欧美一级久久精品| 中文字幕人妻欧美日韩熟女| 鸿观全集在线观看视频| 欧美情色一区二区三区| 国内偷拍中文字幕蜜臀| 国产a久久观看免费视频| 亚洲美女乱1区2区3区| 免费女女同黄毛片av网站| 亚洲丝袜av在线观看| 成人极品av免费观看| 一本92午夜免费不卡福利片| av在线中文字幕资源网| 久久国产精品亚洲va麻豆| 中文字幕免费av在线| 九一精品人妻一区二区三区| 丰满人妻一区二区三区精品av| 日韩 国产 欧美 在线 一区| 中文字幕在线视频首页| xxx日韩欧美黄色a| 精品国产综合av蜜臀18| 在线国产视频精品视频| 少妇一区二区三区粉嫩av| 久久99久久久久久久久| 正在播放99精品视频在线播放| 日韩情色一区二区三区四区| 久久久99人妻一区二区三区| 粉嫩av蜜乳av蜜臀av| 青青青爽综合在线视频| 噜噜av在线免费观看| 亚洲 中文 字幕 人妻| 国产精品久久久午夜夜伦鲁鲁| 国产精品成人自产拍在线| 国产97色伦在线观看| 3p少妇欧美一区二区三区| 在线观看不卡一区二区三区| 成人在线观看免费视频播放| 在线国产视频精品视频| 久久无语av中文字幕| 男人靠女人靠厉害视频| av大全一区二区三区| 亚洲成人av免费在线播放| 精品熟妇人妻一区二区三区四区| 试婚99天视频免费完整版观看| 亚洲一区二区在线看看| 成人国产麻豆一区二区| 日韩熟女少妇一区二区三区| 国产亚洲av久久精品| 黄色的网站免费在线看| 中文字幕在线视频亚洲| 成人在线免费播放视频| 3p少妇欧美一区二区三区| 成人日韩av一区二区| 国产原创AV蜜芽尤物一区| 最近中文字幕免费观看av| 日韩人妻有码一区二区| 日韩欧美人妻激情一区| 带个大鸡巴臭逼的视频。| 麻豆av 无码精品一区二区| 日韩午夜在线视频不卡片| 抽搐高潮痉挛白浆无码av| 国产精品成人中文字幕| 国产女老师的诱惑在线播放观看 | 韩国性感美女热舞视频| 欧美成人一区二区三区视频| 国产午夜精品自拍视频| 中文字幕在线免费视频一区 | 国产亚洲欧美日韩中文在线蜜臀| jizz视频在线观看| 国产欧美日韩精品在线| 韩国三级一区二区在线观看| 青青热久免费精品视频| 欧美生活一区二区三区| 99九九久久国产精品| 国产乱码字幕精品高清人v| 制服 丝袜 欧美 国产精品| 人妻一区二区免费播放| 熟女少妇久久中文字幕| 亚洲黄色av中文字幕| 精品人妻一区二区三区综合部| 国产偷拍自拍熟女视频| 人妻精品在线观看视频| 一本92午夜免费不卡福利片| 免费在线观看亚州av| 在线成人免费观看视频网址| 美女伸开双腿让男人桶视频| 男人女人40分钟视频| 69人妻精品久久久久88| av激情韩国在线播放| 亚洲中文字幕乱码免费播放| 星宫一花av中文在线| 中文字幕亚洲熟女精品人妻| 97精品免费观看视频| 97视频在线观看免费播放| 国产极品粉嫩交性大片| 久久久久人妻精品一区二区三区| av一区二区三区看片| 欧洲美一区二区三区亚洲| 丰满美女一区二区三区| 日韩欧美一区二区专区在线观看| 黄色mv在线免费观看| 欧美生活一区二区三区| 亚洲精品自产拍在线观看动漫| 亚洲自拍偷拍 欧美激情| 美女午夜写真福利视频| 国产一区二区不卡视频在线| 国产精品99久久久精品| 欧美整片一区二区三区| 久久香蕉亚洲欧美av精品| 一级成人欧美一区在线观看| 草草视频免费在线观看| 国产 丝袜 欧美中文 另类| 国内揄拍国内精品人妻迷| 很黄很色国产精品免费视频| 巨乳人妻中文字幕精品在线| 亚洲最大黄色av网站| 久久久国产综合av天堂| 噜噜av在线免费观看| 久久精品国产v日韩v亚洲| 最近免费中文字幕大全高清3 | 精品人妻一区二区三区综合部| 97超频精品在线观看| 97超碰超碰在线观看| 欧美国产日韩另类系列| av在线中文字幕资源网| 日韩极品视频在线观看免费 | 青草青青青青青青操死你| 国产av日韩精品久久| 久久99久久久久久久久| japanese少妇av| 国产在线观看青青草视频| 狠狠久久亚洲美洲专区| 国产青青草在线观看视频| 精品人妻av中文字幕乱码男同| 青草视频中文字幕在线观看| 国产午夜精品自拍视频| 中文字幕综合av一区二区三区 | av在线中文字幕播放| 青青久久国内视频网站| 欧美在线免费激情视频| 这里都是国产视频精品| 青娱乐 青青青操 天天日| 性色av蜜臀av人妻无| 国产免费在线视频观看| 国产精品久久久久久av色| 亚洲成人日韩免费在线播放| 日韩一区二区三区人妻| 欧洲美一区二区三区亚洲| 欧美成人精品一级在线观看| 国产色图视频在线观看| 美女胸18下看禁止免费视频| 亚洲国产日韩另类丝袜| av在线亚洲国产精品婷婷| 99久久在线免费观看| 国内精品伊人久久久久av| 人妻精品在线观看视频| 自拍偷拍亚洲综合在线| 午夜mm1314视频| 星宫一花av中文在线| 欧美成人网另类套图超市| 欧美女同性恋一区二区三区| 蜜臀av入口一区二区三区| 亚洲免费成人精品视频| 黄色的网站免费在线看| 丰满熟女一区二区三区在线播放| 国内一区二区三区视频在线播放| 在线观看国产视频播放| 国产自拍偷拍在线免费| 欧美 日韩 一区二区三区 | 啊啊啊啊插进去你好骚视频| 日韩欧美成人精品视频在线| 人妻丝袜美腿中文字幕| 精色av中文字幕在线| 最大的黄色亚洲网站在线观看| 欧美专区一区二区在线| 国产白嫩在线观看视频| 亚洲精品国产av久久| 成人精品国产一级二级| 久久久久亚洲av一区二区三区| 一区二区三区 国产日韩欧美| 在线播放网站一区二区三区| 丰满熟女一区二区三区91| 94精品视频在线播放| 边摸边吃奶边做毛片视频| 91/日韩/精品/乱码| 亚洲熟女久久一区二区| 91/日韩/精品/乱码| 亚洲欧洲自拍拍偷第二页| 日韩性感美女在线观看| 亚洲精品沙发专享系列av| 26uuu亚洲综合色欧美 | 撒玛利亚女孩在线观看免费全集| 亚洲sm一区二区三区| 国产精品永久免费自在线观看| 亚洲欧美另类在线一区二区| 色一情一乱一乱一区91Av| 99精品人妻一区二区三蜜桃| 久久久久久噜噜噜久久久精品| 久久av成人中文字幕| 久久精品人妻一区二区| 凹凸在线视频免费观看| 国产自拍精品在线视频| 黄色av网站 亚洲精品| 欧美午夜精品免费视频app| 丝袜熟女av一区二区三区| 亚洲av色在线观看国产| 亚洲一区二区三区av网站| 一区二区三区 日韩 av| 午夜精品一区二区三区在视| 久久久久人妻精品一区二区三区| 国内自拍 都市激情 人妻| 日韩制服丝袜在线播放| 国产精品丝袜熟女一二三| 91超碰在线免费视频| 久久99只有这里有精品| 明日花绮罗人妻大乳av| 亚洲丝袜av在线观看| 丁香婷婷久久久久成人天堂国产| 久久久久国产AV成人网| 亚洲成人av免费在线播放| 我的放荡丝袜美腿老师| 久久国产麻豆免费播放| 黄色一级片久久久免费观看| 成人黄动漫在线观看网站| 在线观看的资源网97| 国产粉精品高潮呻吟久久av| 男人和女人的性生活视频 | 欧美在线免费在线视频| 成年人播放视频在线观看| 日韩国产中文字幕精品| 免费精品国偷自产在线洗澡| 成人A级毛片无码免费看| 星宫一花av中文在线| 亚洲精品乱码久久久久久久久| 超碰97国产在线免费观看| 精品日本一区二区三区四区| 成人av无码区二区三区| 亚洲中文字幕乱码在线| 欧美成人性做爰77777| 日本性感丝袜女秘书诱惑| 亚洲一区二区三区桃乃木香奈| 亚洲人妻一区二区91| 自拍人妻欧美亚洲第三| 人妻av在线中文字幕| av黄色资源中文字幕| 成人黄色精品视频网站| 久久久久久精品久久久久久| 97视频在线观看免费播放| 青娱乐 青青青操 天天日| 午夜18在线观看视频| 97超频精品在线观看| 中文字幕人妻少妇久久| 成人在线观看免费视频播放| 国产一级视频在线观看免费| 亚洲精品国产av久久| 97色老99久久九九爱精品| 亚洲情a成黄在线观看动漫尤物| 色综合久久88色综合天| 伊人视频在线免费观看| 国产成人av在线精品| 国产91精品入口人妻| 97精品日韩在线视频| 青青草原国产在线免费观看| 日韩人妻这里只有精品| 国产一区二区三区在线h| 黄色传媒在线免费观看| 亚洲欧美人妻最新网址| av性感美女免费在线观看| 欧美狠狠一区二区三区| av中文字幕一区在线| 大鸡巴操小嫩逼免费全裸| 快速播放国产精品视频| 国产哟av精品色哟哟| 97在线观看免费观看视频| 丰满人妻一区二区三区精品av| 伊人网站免费在线观看| 国产精品特级露脸AV毛片| 国产偷拍自拍在线免费| 男人靠女人靠厉害视频| 久久精品国产高潮av| 亚洲欧美另类在线一区二区| 成年人免费看国产黄色片| 高跟丝袜诱惑后入av| 午夜激情免费视频成人| 91丨九色丨韩国人妖| 狠狠色狠狠色综合日日92| 在线亚洲视频中文字幕| 美女自拍偷拍亚洲一区| 亚洲av日韩综合一区在线观看| 人妻巨乳中文字幕亚洲在线| 久久精品视频在线看24| 一道一本av精品久久毛片| 日韩熟女少妇一区二区三区| 91在线成人在线视频| 国产欧美久久久久久精品一 | 亚洲无av在线中文字幕男男| 人妻在线免费观看二区| 欧美激情一区二区三区成人| 久久精品人妻系列av| 国产高清av一区二区在线观看| 先锋视频资源在线播放| 欧美一区二区三区av| 亚洲av成人噜噜网站| 夜精品一区二区无码A片| 亚洲黄色av中文字幕| 神马不卡午夜在线观看| 国产精品成人免费av| 人妻精品系列一区二区三区| 日韩欧美人妻激情一区| 青青青青草免费视频看看| 蜜臀久久99精品久久宅男| 中文字幕一区人妻激情| 久久精品国产亚州av| 精色av中文字幕在线| 搬开女人下面使劲插视频| 日韩中文字幕在线av| 香蕉免费一区二区三区在线观看| 欧美不卡一区二区三区视频| 日韩 制服 丝袜 中文| 91人妻精品一区二区三区不| 青青草久久久久综合精品| 亚洲国产日韩精品欧美| 在线观看黄色播放网站| 国产自产拍午夜免费视频| 国产成人av午夜精品免费| 国内伦理视频在线观看| 日韩国产偷拍自拍在线| 天海翼一区二区三区免费| 午夜dj观看在线观看hd| 亚洲熟女一区二区三区观看| 很黄很色的视频免费在线观看| 日韩欧美国产精品综合| 91久久精品国产91性色| 美女国产高潮福利片在线看| 超污短视频网站在线观看| 黄视频免费看网站在线观看| 最近中文字幕免费观看av| 欧美久久久久久久久久久久久| 人妻一区二区免费播放| 国产成人黄色精品视频| 人妻视频资源在线观看| 国内精品视频免费播放| 5060午夜看片免费| 久久久久精品久久久久久| 色综合久久久久久久久8噜啦噜| 国产欧美日韩综合精品一区| 午夜精品久久久在线观看| 亚洲人妻一区二区91| 午夜激情免费视频成人| 深夜视频在线观看免费| 国产 欧美 日韩在线视频| 与女性一起行走男性应走| 中文字幕人妻在线乱码搞| 欧美性色欧美a在线视频| 日韩欧美国产精品综合| 免费激情视频在线观看| 中文字幕在线视频亚洲| 综合久久国产中文人妻少妇在线| 最新欧美69堂在线视频| 青青青青国产在线视频| 国产自拍免费精品视频| 人妻中文字幕免费av| 亚洲乱码国产一区网址| 欧美一区二区三区色污| 国产视频自拍在线观看| 国产福利在线播放视频| 国产成人乱码一区二区三区在线| 欧美激情视频一区二区三区| 美女黄网站永久观看网站不卡| 24小时在线免费观看高清视频| 欧洲一区二区三区在线播放| av岛国一区二区三区久久 | 18成人黄色在线观看| 美女黄a视频大全在线免费观看| 中文乱码字幕视频观看网站免费| 国产av中文字幕乱码| 国产高清一级视频在线观看| 人妻丝袜一区二区三区| 国产中文精品久高清在线不| 青青草日韩av在线播放| 男人和女人的性生活视频 | 久久人人妻人人做人人爽| 蜜臀av夜夜澡人人爽人人| 国产日产欧产精品精乱了派| 国模在线一区二区三区| 精品无人区一区二区三区av| 亚洲国产自产一区二区c| 免费播放黄色操逼乱操逼| 精品人妻一区二区三区成人网| av在线观看亚洲中文| 熟妇人妻av一区二区三| 成年网站在线视频免费| 国产精品入口蜜臀人妻| 97人妻免费在线视频| 激情视频 超黄 在线免费| 久久久99精品久久久久久久| 国产亚洲欧美日韩精品| 精品人妻一区二区三区综合部| 国产欧美日韩精品在线| 国产精品丝袜熟女一二三| 亚洲午夜av久久久精品| 色婷婷国产精品免费视频| 亚洲一级av对白刺激| 在线观看的资源网97| 粉嫩av一区在线观看| 精品一区二区三区四区在线播放| 久久成人在线视频播放| 精品一区二区三区四区在线播放| 掰开我的大黑逼快来操我| 欧美日韩午夜精品不卡综合| 美女午夜写真福利视频| 国产av 一区二区三区四区| 久久久久久狠狠亚洲综合| 欧美日韩精品成人在线| 视频一区二区三区日韩欧美| 日韩一级淫片蜜臀播放口| 涩播视频在线观看免费| 人妻系列av无码专区免费| 肉色丝袜久久精品国产av| 在线播放一区二区三区三州| 噜噜mm视频在线观看| 亚洲av色在线观看国产| 国产丝袜熟女人妻在线观看| 国产视频免费在线播放| 国产一区二区在线观播放| 亚洲成人日韩免费在线播放| 在线国产视频精品视频| 精品国产黄片一二三区| 国产有色视频在线网址| 日韩一区二区人妻9999| 久久精品视频在线看24| 国产亚洲免费在线视频| 精品国产乱码久久久久久男人| 91国产自拍在线视频| 94精品视频在线播放| 成人免费在线视频亚洲| 国产精品人妻中文字幕| 欧美性色欧美a在线视频| av在线观看亚洲中文| 欧美国产精品久久综合| 男人把女人捅到爽歪歪黄| 国产黄色片久久久久久久 | 老男人xx女人视频试看| 亚洲av专区在线观看国产| 在线观看免费黄小视频| 日韩激情中文字幕在线| 中文字幕在线视频亚洲| 欧美整片一区二区三区| 带个大鸡巴臭逼的视频。| 免费女女同黄毛片av网站| 中文字幕在线日韩第一精品| 欧美午夜精品免费视频app| 久久人妻日韩一二三区| av中文字幕一区在线| 99视频在线精品免费| av中文在线中文av| 国产欧美精品免费观看久| 亚洲乱码国产一区网址| 熟女少妇久久中文字幕| 视频一区二区三区日韩欧美| av在线不卡中文字幕宾馆| 熟女人妻专区中文字幕| 99热爱精品在线观看| 97色老99久久九九爱精品| 你在线上av中文字幕| 国产欧美亚洲日本网站| 亚洲无码AV在线免费观| 国产精品成人自拍视频| 国产精久久久久久一区二区三区 | 日本中文字幕乱码免费视频| 97 在线免费观看视频| av在线一区二区三区不卡| 熟女麻豆一区二区三区四区| 日韩熟女精品91中文字幕| 日韩av一区二区三区四| 日韩熟女精品91中文字幕| 污污污黄视频免费观看| 97人妻免费在线视频| 中文字幕在线日韩第一精品| 久久精品一区二区东京热| 国产午夜精品视频免费福利| av岛国一区二区三区久久| 亚洲精品 乱码久久久久久| 美女伸开双腿让男人桶视频| 成人免费av网址在线观看| 99热精品素人在线国产丝袜| 国内偷拍中文字幕蜜臀| 在线中文字幕有码视频| 夜夜骚av一区二区三区啊| 98久久久久久久久久| 一级一看免费完整版毛片| 韩国床震吃奶摸下的激烈视频| 亚洲精品乱码久久久久久久久 | 97成人在线视频免费观看| 伊人av超碰伊人久久久| 老熟女 一区二区三区| 久久久久久久综合精品| 国外成人免费激情在线视频| 巨乳人妻中文字幕精品在线| 亚洲日本韩国一级二级三级| 青青草原网址在线观看| 女生高潮喷水视频免费在线观看| 中文字幕乱码在线视频网站| 天天操天天日天天射天天爽| 男人插女人逼有声视频| 久久久久久精品一区二区三区| 免费激情视频在线观看| 日韩欧美少妇一区二区三区| 国产精品网站调教美女| 97国产视频在线免费观看| 97人妻免费在线视频| 欧洲美女一区二区三区| 国产高清亚洲精品视频| 国产精品成人免费av| 精色av中文字幕在线| 日韩乱码中文字幕有码视频| 久亚洲国产精品蜜臀尤物| 午夜秘密播放器在线观看视频| 中文字幕乱码人妻久久精品| 欧美三级精品三级在线| 911精品在线免费观看| 97人妻中文字幕精品一区在线| 最新在线一区二区三区| 国产一区二区三区在线h| 色婷婷av国产精品欧美| 国产在线观看青青草视频| 亚洲午夜av久久久精品| 97人妻中出中文字幕| 风间由美亚洲一区二区三区| 亚洲一区二区av在线| 色综合久久久久久久久8噜啦噜| 久久精品国产熟女亚洲av| 亚洲国产精品黑丝美女| 在线观看日韩三级视频| 老女人乱淫一区二区三区 | 大鸡巴操小嫩逼免费全裸| av中文字幕官网天堂| 中文字幕在线视频亚洲| 狠狠的干香蕉久久av| 一本92午夜免费不卡福利片| 朋友的妈妈在线免费观看中字| 亚洲一级av对白刺激| 丰满人妻熟妇又伦精品| 综合av一区二区三区| 午夜不卡在线免费视频| 亚洲国产自产一区二区c| 成人av无码区二区三区| 日韩国产在线不卡av| 青青草原网址在线观看| 美女胸18下看禁止免费视频| 人妻少妇亚洲自拍av| 在线播放网站一区二区三区| 精品 亚洲av 国产探花| 精品人妻少妇嫩草一区二区三区| 欧美午夜精品免费视频app| 97 在线免费观看视频| 亚洲 自拍 欧美 中文| 抽搐高潮痉挛白浆无码av| 免费观看成人午夜激情视频| 亚洲一区二区三区天海翼| 久久久免费一区二区三区| 少妇直播一区二区三区| 国产精品99久久啊免费黑人| 黄色av网站 亚洲精品| 欧美一区二区三区伦理国产| 日韩av在线日韩av日韩av| 国产日韩亚洲精品av| 亚洲一级av对白刺激| 美女精品一区二区三区免费观看| 国产亚洲欧洲在线成人| 噜噜av在线免费观看| 97人人爽人人爽人人人爽| 亚洲av色在线观看国产| 国内一区二区三区视频在线播放| 欧美激情在线播放一区| 国产AV无码专区AV麻豆| 成年av网站18不禁| 欧美熟妇一级二级三级a| 色婷婷av国产精品欧美| 午夜男女爽爽爽爽爽爽爽| 青青青青娱乐在线观看| 欧美成人网另类套图超市 | 直接免费观看黄色的网站| 亚洲成人日韩免费在线播放| 97精品国产高清自在线| 在线91华人精品国产片| 在线观看免费黄小视频| 一级一看免费完整版毛片| jizz视频在线观看| 熟女人妻专区中文字幕| 国产欧美日韩精品一区二区三区 | 亚洲精品国产av久久| 亚洲精品国产精品懂色av| 绝美人妻一区二区在线观看| 很黄很色的视频免费在线观看| 亚洲 一区 二区三区| 国产原创av在线免费播放| 久久久99精品久久久久久久| 最新在线一区二区三区| 中文字幕国产乱码视频| 老女人av一区二区三区| 在线观看不卡一区二区三区| 在线播放欧美A在线观看| 国产欧美精品日韩精品视频专区| japanese少妇av| 99爱在线精品视频免费看| 日韩欧美精品中文字幕富二代| 性色成人区人妻精品一区二区| 青青草原在线免费观看网址| 中文字幕中文av在线精品| 国内自拍视频在线观看h| 精品国产污污污的网站| 97超碰人妻福利在线| 国产午夜精品视频免费福利| 2023国产精品自拍视频| 白白色发布在线播放国产| 中文字慕人妻一区二区在线视频| 国产高清三级在线精品福利| 网站免费黄色在线播放| 亚洲国产成人精品久久久久| 日韩欧美精品中文字幕富二代| 国产午夜福利精品理论片久久| 丰满人妻熟妇又伦精品| av一区中文字幕在线| 高跟丝袜诱惑后入av| 久亚洲国产精品蜜臀尤物| 国产日韩欧美精品久久| 国产欧美亚洲日本网站| 精品在线观看视频一区| 欧美日韩在线精品激情| 两鸡巴日一个骚逼浪的视频| 欧美成人性做爰77777| 日韩人妻久久中文字幕| k到视频在线观看免费网站| 成人激情自拍图片视频| 国产原创av在线免费播放| 明日花绮罗人妻大乳av| 直接免费观看黄色的网站| 欧美激情一区二区三区成人| 欧美 亚洲一区二区在线| 久久国产精品99精国产| 国产成人高清一区二区三区免费视频| 福利国产在线观看永久免费| 色av色婷婷91人妻久久久| 亚洲一区视频免费在线观看| 午夜dj观看在线观看hd| 视频一区二区三区国产在线| 成人免费看片98欧美| 91国产自拍在线视频| 色一情一乱一乱一区91Av| 综合久久国产中文人妻少妇在线| 伊人精品久久久久中文字幕| 国产精品久久久久精品日| 91精品久久久久久五月| 福利国产在线观看永久免费| 最新中文在线乱码av| 巨乳人妻中文字幕精品在线| 亚洲一区二区在线视频播放| 青青青色视频在线观看| 成人24小时免费视频| 在线观看不卡一区二区三区| 97国产视频在线免费观看| 国产亚洲欧美日韩精品| 天天操天天日天天射天天爽| 与女性一起行走男性应走| 欧美日韩国产三级在线| 久久人人妻人人做人人爽| 国产乱码字幕精品高清人v| 青草成人在线观看视频| 国内自拍 都市激情 人妻| 一区二区在线观看免费不卡| 人妻视频资源在线观看| 午夜不卡在线免费视频| 先锋视频资源在线播放| 国产自拍视频在线免费| 亚州精品一区二区@v| 国产欧美精品日韩精品视频专区| 欧美日韩乱码视频在线免费观看 | 人妻一区二区在线免费播放| 国产视频免费在线播放| 白浆熟女精品国产91| 人妻少妇精品一区二区| 一本92午夜免费不卡福利片 | 蜜臀av夜夜澡人人爽人人| 欧美午夜精品免费视频app| 熟女少妇久久中文字幕| 97人妻免费在线视频| 欧美性欧美三级全透明时装秀| 国产精品丝袜熟女一二三| 中文字幕av网址在线| 中文字幕人妻在线乱码搞| 韩剧熔炉在线完整免费观看| 91精品视频最新入口| 超碰视频在线观看免费| 中文字幕日本在线观看视频| 国产美女学生在线观看| 中文字幕乱码亚洲三区| 一区二区三区在线网址| av天堂中文字幕精品| 人妻熟女一区二区91| 欧美一区二区三区四区在线观看| 97精品日韩在线视频| 91精品视频最新入口| 青青草原精品在线观看视频| 国产高清免费不卡av| 人妻中出中文字幕在线| 久久久久久久精品女人毛片| 一区二区三区欧美精选| 人妻系列av无码专区免费| 久久久久人妻精品一区二区三区| 国产成人麻豆精品视频| 人妻丝袜一区二区三区| 制服 丝袜 欧美 国产精品| 香蕉免费一区二区三区在线观看| 明星性感丝袜图片大全| 亚洲国产免费视频网站| 美女午夜写真福利视频| 亚洲美女乱1区2区3区| 欧美一区二区三区再线播放| 亚洲国产熟女一区二区三区胖妞| 久久久综合亚洲av家庭乱搞| 精品国产黄片一二三区| 97人人爽人人爽人人人爽| 成人黄动漫在线观看网站| 羞羞av一区二区三区| 亚洲三级一区二区三区四区| 欧美成年一区二区三区| 日本青草视频在线观看| 国产一区二区三区伦理片一级| 国产精久久久久久一区二区三区| 久久婷婷亚洲国产综合蜜臀| 污污污网址免费在线观看| 日韩中文字幕人妻诱惑| 亚洲av日韩综合一区在线观看| 人妻丝袜美腿中文字幕| 风间由美亚洲一区二区三区| 亚洲欧美一区二区福利| 久久香蕉国产熟女线看| 黄色av在线免费播放| 人妻系列少妇极品熟妇| 少妇的玉足让我爽翻天| 国产97自拍视频在线观看| 欧美日韩激情一区二区在线观看| av在线中文字幕播放| 美女制服丝袜高跟诱惑| 久久老熟女一区二区福利蜜臀| 亚洲不卡码一区二区三区| 日韩欧美一区二区专区在线观看 | 69久久久久久人妻白浆| 91精品视频最新入口| 久久福利视频在线播放| 日韩欧美国产一区二区三区在线 | 岛国av丝袜在线播放| 综合久久国产中文人妻少妇在线| 青青青视频自偷自拍视频1| 好吊色欧美一区二区三区四区| 成人国产麻豆一区二区| 国产日韩欧美精品久久| 激情视频网站在线观看| 中文字幕人妻熟女人妻av| 国产亚洲成人精品视频| 欧美一级内射视频在线播放| 中文字幕无码中文字幕有码在线| 免费一区二区三区四区av| 99九九99久久精品| 大奶少妇白虎高潮流视频| 亚洲免费成人精品视频| 亚洲中文字幕日韩av| 欧美整片一区二区三区| 久久久久久狠狠亚洲综合| 国产高清在线一区不卡极品| 俄罗斯大鸡吧操骚逼水多舒服 | 久久91丨国产人妻熟女| 欧美日韩激情一区二区在线观看| 国产成人自拍视频在线| 国产又粗又黄在线播放| 日日摸夜夜添夜夜添破第一次 | 想神马有神马舞蹈视频| 国内网友自拍9色视频| 亚洲欧美一区二区福利| 丰满人妻一区二区三区精品av| 国产精品自拍首页视频| 在线 av 中文字幕| 亚洲性色成人av天堂| 爆操欧美牛仔裤肥臀大屁股| 国产成人黄色在线观看| 77成人在线免费视频| 97人妻中出中文字幕| 久久精品中文字幕乱码视频| 国产欧美精品免费观看久| 精品成人一区二区三区在线观看| 成人24小时免费视频| 日韩 制服 丝袜 中文| 91麻豆精品在线播放| 日韩 制服 丝袜 中文| 欧美一区二区三区黄片| 日韩国产制服丝袜专区| av天堂中文字幕精品| 国产不卡亚洲免费av| 中文字幕国产乱码视频| 欧美激情一区二区二区| 激情福利视频在线观看| 国产爱爱视频在线播放| 精品国产乱码久久久久久男人| 亚洲熟女一区2区三区| 国产中文精品久高清在线不| 欧洲美女一区二区三区| 久久香蕉亚洲欧美av精品| 尤物欧美一区二区三区| 久久久久久精品一区二区三区| 国产精品色图在线观看| 风间由美亚洲一区二区三区| 国产免费三级三级三级| 91福利国产成人精品播放| 久久久久亚洲精品乱码按摩| 97人妻免费公开视频| 在线观看不卡一区二区三区| 中文字幕av在线观看网址| 国产熟女熟妇一区二区三区av| 色婷婷av一区二区三区网| 老女人乱淫一区二区三区| 国产福利精品久久av| 国产精品中文字幕av在线| 久久99av无色码人妻蜜柚 | 国产高清在线免费观看不卡av| 中文字幕在线乱码观看| 69人妻精品久久久久88| VA乱伦无码视频免费播放| 熟女五十路一区二区三区| 成年人播放视频在线观看| 国产精品入口蜜臀人妻| 99热精品素人在线国产丝袜| 风间由美亚洲一区二区三区| 日韩 国产 欧美 在线 一区| 少妇极品一区二区三区| 国产精品国产三级国产普通话一 | 国产性一交一乱―色―情人| 99re这里只有精品在线| 在线观看资源青青国产视频| 亚洲综合国产乱码成人| 视频一区二区三区 在线| 国产 丝袜 欧美中文 另类| 国产精品短视频在线观看| 欧美少妇一区二区三区| 性感美女肉色丝袜诱惑| 成年网站在线视频免费| av中文字幕一区在线 | 97在线观看免费观看视频| 99爱精品视频在线视频| 久久国产精品av大全| 国产粉精品高潮呻吟久久av| 欧美精品免费在线播放| 欧美激情视频免费观看| 亚洲中文字幕日韩av| 青青久久国内视频网站| 中文一区二区三区在线播放| 国产一区二区不卡视频在线| 色综合久久久久久久久8噜啦噜| 亚洲国产精品黑丝美女| 91/日韩/精品/乱码| 黄色mv在线免费观看| 蜜臀av在线观看免费| 美女精品一区二区三区免费观看| 污污污网址免费在线观看| 欧美网址一区二区三区| 欧美日韩一区二区三区性| 久久老熟女一区二区福利蜜臀| 亚洲精品中文字幕午夜| 欧美熟妇一级二级三级a| 日韩欧美精品中文字幕富二代| 99国产小视频在线播放| 日韩人妻久久中文字幕| 欧美日韩亚洲在线另类| 日韩成人av在线二区| 亚洲精品中文字幕午夜| 国产精品亚洲av三区色| 激情伦理一区二区三区| 午夜精彩视频网站免费观看| 久久人人妻人人做人人爽| 97超频精品在线观看| 日本美女丝袜天天看人体| 国产欧美精品日韩精品视频专区| 肉色丝袜久久精品国产av| 1024日韩人妻区二区| 最新中文字幕av网站| 日本午夜免费在线视频| 青青草原亚洲视频在线观看| 国产sese在线播放| 掰开我的大黑逼快来操我| 人妻中文字幕免费av| 欧美一区2区三区在线播放| av天堂免费在线播放| 亚洲欧美日韩精品麻豆| 久久国产麻豆免费播放| 激情视频网站在线观看| 99精品人妻一区二区三蜜桃 | 日韩中文字幕人妻一区| 日本性感丝袜女秘书诱惑| 成人av综合网中文字幕| 老男人xx女人视频试看| 国产女人叫床高潮大片免费| 色婷婷一区二区三区四区在线| 女人日男人30分钟视频| 大岛优香中文字幕av人妻| 丝袜制服诱惑人妻av| 国产91情侣在线视频| 午夜精彩视频网站免费观看| 亚洲av日韩综合一区在线观看 | 久久香蕉国产熟女线看| 在线视频免费观看久久| 成年人黄色片视频网站| 在线成人免费观看视频网址| 久久福利视频在线播放| 亚洲无av在线中文字幕男男| 91性色福利在线视频| 好想被狂操在线无码视频| 亚洲一区二区三区av网站| 久久久久亚洲精品乱码按摩| 黄色av网站手机在线播放| 亚洲午夜免费在线观看| 黄色在线观看不卡无广告| 亚洲av日韩精品久久| 日韩欧美中文字幕人妻| 亚洲国产精品免费线观看视频| 午夜免费在线视频国产| 人妻av蜜臀一区二不卡| 欧美网址一区二区三区| 99爱精品视频在线视频| 欧美狠狠一区二区三区| 内射中文字幕在线观看| 国产免费九九久久精品a级| 精品熟妇人妻一区二区三区四区| 久久综合久久狠狠综合| 男人插女人逼有声视频| 美女扒开胸罩露出奶头免费| 中文字幕在线乱码观看| 国产成人精品欧美日韩网站| 成人刺激视频免费观看| 99re成人精品免费视频| 自拍偷自拍亚洲精品10p| av在线亚洲国产精品婷婷| 国产亚洲精品线视频在线| 99视频一区在线观看| 国产一区二区三区伦理片一级| 欧美在线免费在线视频| 最新在线一区二区三区| 精品99在线免费视频| 青青操新免费观看视频| 国产18精品乱码在线看| 超碰在线公开内射日韩版| 久久国产精品9999p| 国产精品丝袜熟女一二三 | 羞羞av一区二区三区| 日本免费一区二区三区中文字幕| 精品日韩欧美人妻系列| 国产精品色哟哟在线观看视频| 在线亚洲视频中文字幕| 亚洲黄色av中文字幕| 麻豆国产成人av在线| 精品久久久中文字幕人妻 | 超级碰碰碰视频免费观看| 3p少妇欧美一区二区三区| 91成人精品亚洲国产| 国产人妻一区二区免费播放| 欧美午夜精品免费视频app| 欧美国产日韩另类系列| 韩剧熔炉在线完整免费观看| 中文字幕人妻免费网站| 九九久久久久无限久久| 我的放荡丝袜美腿老师| 蜜臀国产在线观看播放免费| 人妻互换精品一区二区| 久久国产精品av大全| 久久人妻日韩一二三区| 高跟丝袜诱惑后入av| 精品久久久中文字幕人妻| 撒玛利亚女孩在线观看免费全集| 成年人免费看国产黄色片| 制服 丝袜 欧美 国产精品| 亚洲免费成人精品视频| 国产福利在线播放视频| 久久久久久狠狠亚洲综合| xxx日韩欧美黄色a| 亚洲美女乱1区2区3区| 精品熟女一区二区三区免费视频| 女生高潮喷水视频免费在线观看| 成人免费看片98欧美| 免费成人三级在线观看| 亚洲乱女色熟一区二区三区 | 青青艹视频在线免费观看| 超视在线免费观看视频| 亚洲一区二区三区天海翼 | 国产97视频免费在线观看| 国产高清三级在线精品福利| 美女黄a视频大全在线免费观看| 黑丝美女的骚逼尖叫高潮声| 97精品日韩在线视频| 国产又粗又猛又爽又色视频| 国产揄拍视频在线观看| 国产偷拍自拍熟女视频| 久久久99精品久久久久久久| 老男人xx女人视频试看| 1024日韩人妻区二区| 精品国产专区91精品| 一区二区在线播放三区| 人妻av蜜臀一区二不卡| 日韩一区二区三区在线看片| 中文字幕在线日韩第一精品| av中文字幕一区在线| 国产成人av在线精品| 97人妻免费在线视频| 99久久国产综合精品五月天| 自拍亚洲一区欧美另类| 成人av综合网中文字幕| 污污污网址免费在线观看| 一区二区三区看国产片在线| 黄黄的小视频免费在线播放| 亚洲乱码在线免费观看| 青青青草青在线视频免费观看了| 深夜在线视频在线观看| 欧美成年一区二区三区| 国产欧美精品日韩精品视频专区| 青青青国产免费观看视频| 亚洲激情av一区二区三区| 精品人妻一区二区三区成人网| 久草视频这里只有精品| 青青青青免费观看视频| 亚洲精品午夜免费视频| 国产粉精品高潮呻吟久久av| 超长假大鸡巴从肛门捅到胃视频 | 亚洲欧美精品丝袜中文字幕| 成人在线免费播放视频| 青青草原网址在线观看| 亚洲精品自产拍在线观看动漫| 白白色发布在线播放国产| 亚洲激情视频在线观看视频| 国产精品欧美一区二区久久久| 中文字幕亚洲久久爽一区| 青青青草原成人在线视频| 五十路熟女人妻在线网观看| 亚洲国产成人不卡av| 欧美生活一区二区三区| 超碰人妻免费一区二区| 国产小视频在线观看你懂得| 欧美中文字幕乱码在线播放| 午夜激情免费视频成人| 黄视频免费看网站在线观看 | 久久久久久4久久久8| 人妻中文字幕永久在线| 可以看手机在线黄色视频网| 91福利国产成人精品播放| 日本人妇十八禁在线观看| 91精品久久久久久久久| 色94色一区二区三区| 99re成人精品免费视频| 少妇直播一区二区三区| 青草视频在线观看亚洲| 欧美日韩制服丝袜第一页| 色一情一区二区三区精品 | 成人区人妻精品一区二| 黄色一级片久久久免费观看| 自拍 偷拍 亚洲 欧美| 日韩精品乱码av在线播放| 亚洲激情av一区二区三区| 亚洲少妇av一区二区三区| 欧美不卡一区二区三区视频| 午夜激情免费视频成人| 四川熟女a一区二区三区| 91在线视频网站总站| 97人妻中文字幕精品一区在线| 日韩一区二区三区人妻| 人妻丝袜一区二区三区四区av| 欧美激情1区2区3区4区| 超碰人妻免费一区二区| 91自拍免费在线视频| 我想听大香蕉大家大香蕉| 黄黄的小视频免费在线播放| 国产欧美日韩精品一区二区三区| 成人国产精品av在线| 国产精品色图在线观看| 精品久久久人妻中文字幕| 青青草原国产视频在线观看| 人妻少妇偷人一区二区三区 | 国产一区二区在线观播放| 国内欧美一区一区三区| 日韩成人av在线二区| 中文字幕视频免费在线| 99久久麻豆99久久免费| 成人激情自拍图片视频| 国产麻豆精品福利在线观看| 免费播放黄色操逼乱操逼 | 中文字幕日韩在线久久| 麻豆国产成人av在线| 中文字幕乱码亚洲三区| 亚洲一区视频免费在线观看| 亚洲欧美另类视频一区蜜臀| 国产精品中文字幕av在线 | 三级成人一区二区三区| 我的女人呻吟噢噢噢哦哦哦哦| 久久人人妻人人做人人爽| 97人妻在线公开视频| 好想被狂操在线无码视频| 亚洲高跟丝袜在线观看| 丁香婷婷久久久久成人天堂国产| 日韩欧美久久一区二区 | 日韩国产制服丝袜专区| 国产人妻一区二区免费播放| 深夜视频在线观看免费| 日本丝袜美腿在线观看| 国产中文精品久高清在线不| 久久人人妻人人做人人爽| 日本免费精品一二三区| 天海翼一区二区三区免费| 99久久精品婷婷久久久久久| 久久综合中文字幕日韩精品| 国产原创AV蜜芽尤物一区 | 国产高清av一区二区在线观看| 日韩人妻有码一区二区| 成人av日本在线观看| 91精品国产人妻国产在线| 中文字幕在线免费视频一区 | 青草视频在线观看亚洲| 男人插女人逼有声视频| 日韩 制服 丝袜 中文| 人人综合亚洲无线码另类会员 | 欧美熟妇一级二级三级a| 性做久久久久久久毛片| 久久99久久精品免观看吃奶 | 男人插女人逼免费视频| 乱文丝袜乱文丝袜美腿视频| 大香国产视频中文字幕| 激情av一区av二区| 成人黄色精品视频网站| 日韩丝袜诱惑网站大全| 人妻一区二区三区精品免费| 一级一看免费完整版毛片| 国产亚洲精品线视频在线| 人妻一区二区免费播放| 黄色av网站手机在线播放| 久久久久亚洲av一区二区三区 | 久久精品人妻免费观看| 色综合久久久久久久久8噜啦噜| 日韩国产在线不卡av| 色av色婷婷91人妻久久久| 性色成人区人妻精品一区二区| 中文字幕人妻少妇久久| 亚洲av乱码在线观看| 日韩中文字幕avsex| 麻豆国产成人av在线| 99久久久精品免费看国产| 亚洲精品国产精品懂色av| 国产人妻一区二区免费播放| 欧美一区二区三区四区免费| 99久久无码精品区二区毛片| 亚洲性色成人av天堂| 国产女人叫床高潮大片免费| 精品国产一区二区三区不卡免费 | 国产免费在线视频观看| 鸿观全集在线观看视频| 激情福利视频在线观看| 欧美日韩午夜精品不卡综合| 国产精品丝袜制服在线| 天天操天天日天天射天天爽| 欧美成人天天综合在线视色| 18免费在线观看av| 亚洲中文自拍另类av| 欧美成人一区二区三区视频| 亚洲丝袜在线播放一区| 羞羞av一区二区三区| 青青青草原成人在线视频| 日韩国产制服丝袜专区| 国产亚洲欧美日韩精品| 无码国模大尺度自拍视频在线看| 翔田千里精品久久一区二| 亚洲 欧美 日韩成人| 女人是为抠逼男人的鸡巴操逼| 94精品视频在线播放| 亚洲欧美自拍偷拍另类| 亚洲一区视频免费在线观看| 国产 欧美 日韩在线视频| 亚洲欧美日韩精品麻豆| 国产成人黄色精品视频| 国产精品久久综合亚洲av| 青青青青在线播放视频| 欧美情色大片在线观看| 国产免费av国片精品| 国产免费九九久久精品a级| 爆乳美女粉嫩阴蒂被插视频| 高潮毛片遮挡免费高清| jizz视频在线观看| 欧美激情视频免费观看| 亚洲欧美精品丝袜中文字幕| 无码国模大尺度自拍视频在线看 | 可以免费看的黄色的网站| 最新成人精品视频在线| 美女胸18下看禁止免费视频| 久久精品人妻系列av| 国产1区2区3区在线播放| AV午夜福利一片免费看久久| 正在播放99精品视频在线播放| 97精品免费观看视频| 亚洲中文字幕乱码免费视频| 蜜臀av在线观看免费| 肉色丝袜久久精品国产av| 精品无人区一区二区三区av| 在线 av 中文字幕| 人妻一区二区在线免费播放| 中文字幕乱码在线精品| 在线观看国产视频播放| 在线看片免费人成视久网| 国产又粗又猛又爽又色视频| 亚洲欧美日韩一级免费| 国产日韩av大片快播| 黄色福利视频网址大全| 97人妻中出中文字幕| 亚洲一区二区av在线| 国产亚洲欧洲在线成人| 91在线国产视频播放| 国产精品丝袜制服在线| 亚洲一区二区三区18| 91草草视频在线观看| 欧美日韩乱码视频在线免费观看 | 深夜视频在线观看免费| 韩国性感美女直播热舞| 九一精品人妻一区二区三区| 国产偷拍自拍熟女视频| 国产精品色哟哟在线观看视频| 内射中文字幕在线观看| 高潮毛片遮挡免费高清| 人妻精品在线观看一区二区三区| 亚洲制服丝袜美腿在线| 亚洲熟女一区二区av| 97国产视频在线免费观看| 人妻一区二区在线免费播放| 99视频精品视频观看| 视频一区二区三区日韩欧美| 精品国产乱码久久久久久男人| 少妇性生活久久久久久| 亚洲欧美日韩精品麻豆| 欧美黄色一级一区二区三区| 国产欧美精品免费观看久| 人人妻人人做人人妻av| 日本丝袜美腿在线观看| 国产欧美精选自拍视频| 亚洲一区二区在线看看| 中文字幕乱码视频播放| 精品久久久中文字幕人妻| 大象焦伊人久久综合网色视| 国产剧情午夜在线观看| 国产亚洲欧洲在线成人| 黄色美女在线观看日韩| 久久乐国产精品亚洲综合| 狠狠久久亚洲美洲专区| 久久久免费久久久精品| 欧美特级特黄a大片免费| 最新在线一区二区三区| 很黄很色的视频免费在线观看| 日本午夜免费在线视频| 99热精品素人在线国产丝袜| 亚洲国产免费视频网站| 3p少妇欧美一区二区三区| 国产一区二区成人av| 欧美在线观看亚洲精品| 亚洲国产欧美精品在线| 成人国产精品视频在线| 色婷婷av国产精品欧美| 国产sese在线播放| 国产自拍偷拍在线一区| 中文字幕在线亚洲视频| 轻轻插青青草视频在线播放| 中文字幕人妻A片免费看| 蜜臀成人av在线观看| 午夜免费福利视频大全| 白浆熟女精品国产91| 伊人视频在线免费观看| 97人人爽人人爽人人人爽| 99re这里有精品免费视频| 国产AV躁一二三区免费播放| 精品熟妇人妻一区二区三区四区| 中文字幕乱码在线视频网站| 免费亚洲一区二区三区| 九九激综合五月天国产| 女人嫩水逼让大鸡巴操免费看| 精品99在线免费视频| 国产精品久久人妻互换| 亚洲人妻中文字幕网站| 中文字幕视频观看在线中文| 亚洲乱码在线免费观看| 国产盗摄一区二区三区在线| 国产中文精品久高清在线不| 3p少妇欧美一区二区三区| 午夜性生大片免费在线观看| 青草视频在线观看亚洲| av中文在线中文av| 97成人在线视频免费观看| 区一区二区三在线播放| 啊啊啊啊插进去你好骚视频| 国产亚洲精品成人av丝袜| 人妻巨乳中文字幕亚洲在线| 国内偷拍中文字幕蜜臀| 熟女人妻中文字幕免费观看| av在线中文字幕播放| 一区二区在线观看免费不卡| 久久久久久人妻精品一区| av中文字幕人妻丝袜| 国产精品中文av在线播放| 肉色丝袜久久精品国产av| 成人黄色免费观看网址| 亚洲中文字幕乱码在线| 人妻夜夜爽天天爽欧美色院| 自拍偷拍色亚洲欧美色| 国产一区二区在线97| 国产va欧美va精品va综| 国产成人自拍视频在线| 国产福利精品久久av| 懂色av密臀av粉嫩av | 边摸边吃奶边做毛片视频| 亚洲国产精品视频免费看| 黄色av在线观看网址| 中文字幕人妻熟女人妻av| 小视频在线观看你懂的| 男人添女人下边视频免费| 得得的爱在线视频免费观看 | 亚洲真人丝袜av一区二区| 中文字幕人妻少妇久久| 中文字幕在线亚洲视频| 国产91av精品在线观看| 女人日男人30分钟视频| 五十路熟女人妻在线网观看| 国产精品久久久久精品| 免费a站网址在线观看| 国产在线观看青青草视频| 国产三级视频在线18播放线观看| 91自拍免费在线视频| 精品国产久久三级av| 97超碰人妻福利在线| 一区二区在线观看免费不卡| 久久99亚洲精品久久频| 大岛优香中文字幕av人妻| 少妇一区二区三区97少妇| 国产精品自在在线午夜| 带个大鸡巴臭逼的视频。| 91/日韩/精品/乱码| 国产精品丝袜制服在线| 国产熟女人妻在线观看| 成人国产麻豆一区二区| 人妻熟女欧美一区二区| 国产欧美在线视频观看| 超碰人人爱人人爽人人av| 亚洲一区视频免费在线观看| 青草视频在线观看亚洲| 最近中文字幕免费观看av| 中文字幕久久人妻综合| 国产深夜视频在线观看| 中文字幕人妻熟女人妻av| 91性色福利在线视频| 久久av成人中文字幕| 国产麻豆精品在线视频| 97超碰人妻在线观看| 国产在线日韩精品av| 亚洲 综合 欧美 日韩| 超污短视频网站在线观看|