在ExecutorPy的run方法中可以看到這個(gè)邏輯:

即把phase_s這個(gè)字符串作為key可以獲得一個(gè)VmEval這樣一個(gè)函數(shù), Vm指的是mindspore的一種執(zhí)行計(jì)算的后端這里暫時(shí)不管, Eval指的是Evaluate, 即獲取計(jì)算值的意思. 從字面意思上看就是根據(jù)phase的名稱來(lái)獲取相應(yīng)的執(zhí)行函數(shù). 看一下這個(gè)GetVmEvalFunc的具體邏輯:

可以看到是根據(jù)phase_s獲取了一個(gè)Resource, 然后把這個(gè)Resource中的output轉(zhuǎn)成了一個(gè)function返回, 而這個(gè)resource又是從info這個(gè)鍵值對(duì)中拿出來(lái)的:

那么這個(gè)function是什么呢?從什么時(shí)候被放進(jìn)去的呢?只需要看一下這個(gè)info是何處何時(shí)被賦值的即可.
經(jīng)過(guò)一番探索, 可以找到這里:

可以看到, 這個(gè)info中以phase為key的value是在這里被存起來(lái)的, 這個(gè)resource就是我們?cè)贓xecutorPy的run方法中獲取的resource. 這個(gè)resource的result的賦值是在704行這個(gè)pip對(duì)象的Run方法中. 這個(gè)pip對(duì)象是一個(gè)PipeLine, 在686行被初始化出來(lái), 這個(gè)PipeLine中有很多的actions, 704行這個(gè)run就是在順次的執(zhí)行這些action. 那么一共有哪些actions呢?我們繼續(xù)看:
首先看run方法, 可以看到這里只是把一個(gè)一個(gè)的actions拿出來(lái), 順次執(zhí)行, 外加一些特殊的判斷和操作, 這里不是我們要找的東西.

那關(guān)鍵就在于actions被初始化的地方了, 回到ExecutorPy::CompileInner這個(gè)方法, 看到685行創(chuàng)建actions

進(jìn)入GetPipeline這個(gè)函數(shù):

可以看到有多種不同的選項(xiàng)會(huì)返回不同的actions, 我們看其中一個(gè)就好. 那就VmPipeline吧:

可以看到有許多actions, 每個(gè)action都會(huì)對(duì)resource所綁定的func_graph進(jìn)行處理, 這個(gè)流程很長(zhǎng), 所謂的"源到源"就是在這些actions中的某一個(gè)體現(xiàn)的, 具體我們后續(xù)的文章再講. 那么我們需要的result一定是在最后一個(gè)action的, 也就是execute這個(gè)action.

可以看到, 655行的這個(gè)
res->results()[kOutput] = run;
就對(duì)應(yīng)我們文章開(kāi)頭提到的GetVmEvalFunc函數(shù)中的那個(gè)回調(diào)函數(shù). Good ! 這下整個(gè)流程就清楚了, 在靜態(tài)圖模式下, mindspore的Cell會(huì)先進(jìn)行計(jì)算圖的圖編譯, 最終在execute那個(gè)action那里把編譯好的計(jì)算圖準(zhǔn)備好, 并給一個(gè)回調(diào)函數(shù)傳到output中回到python前端, 再由python前端來(lái)啟動(dòng)整個(gè)計(jì)算流程!
不過(guò)說(shuō)起來(lái), mindspore\ccsrc\pipeline\jit\pipeline.cc這個(gè)文件中ExecutorPy這個(gè)類的CompileInner方法, 這個(gè)方法在哪兒被調(diào)用過(guò)呢?
哈哈 這個(gè)就是在夢(mèng)開(kāi)始的地方, Cell的compile_and_run

之前只關(guān)注了run, 它會(huì)在run之前先compile的嘛, 這個(gè)compile又調(diào)用了executor的compile

跟上篇一樣, 又是一路調(diào)用到c_expression的executor的compile

這里經(jīng)過(guò)pybind從python走到c++的ExecutorPy::Compile

在這里會(huì)調(diào)用compileInner, 再之后就是各種actions的選擇和執(zhí)行了.

所以總結(jié)一下就是:
Cell對(duì)象被調(diào)用后, 會(huì)先通過(guò)python的各種封裝一路調(diào)到c++側(cè)的構(gòu)圖, 初始化各種各樣的action, action執(zhí)行結(jié)束之后, resource的results中就會(huì)被放入一個(gè)回調(diào)函數(shù), 這個(gè)回調(diào)函數(shù)可以把之前的actions所構(gòu)造好的graph拿到, 開(kāi)啟真正的計(jì)算操作.
后面會(huì)詳細(xì)的看一看, 各種各樣的action分別作了什么事情, 為什么這些事情可以讓mindspore做到自動(dòng)微分, 可以做到計(jì)算圖的化簡(jiǎn)等等.