TensorFlow架構(gòu)與設(shè)計:圖模塊

計算圖是TensorFlow領(lǐng)域模型的核心丰嘉。本文通過對計算圖領(lǐng)域模型的梳理驼抹,講述計算圖構(gòu)造的基本原理。

Edge持有前驅(qū)節(jié)點與后驅(qū)節(jié)點丈甸,從而實現(xiàn)了計算圖的連接渔伯,也是計算圖前向遍歷顶霞,后向遍歷的銜接點。

邊上的數(shù)據(jù)以Tensor的形式傳遞咱旱,Tensor的標識由源節(jié)點的名稱确丢,及其所在邊的src_output唯一確定。也就是說吐限,tensor_id = op_name:src_output

src_output與dst_input

Edge持有兩個重要的屬性:

  • src_output:表示該邊為前驅(qū)節(jié)點的第src_output條輸出邊鲜侥;
  • dst_input:表示該邊為后驅(qū)節(jié)點的第dst_input條輸入邊。

例如诸典,存在兩個前驅(qū)節(jié)點s1, s2描函,都存在兩條輸出邊;存在兩個后驅(qū)節(jié)點d1, d2狐粱,都存在兩條輸入邊舀寓。

邊索引

控制依賴

計算圖中存在兩類邊,

  • 普通邊:用于承載Tensor肌蜻,常用實線表示互墓;
  • 控制依賴:控制節(jié)點的執(zhí)行順序,常用虛線表示蒋搜。

特殊地篡撵,控制依賴邊,其src_output, dst_input都為-1(Graph::kControlSlot)豆挽,暗喻控制依賴邊不承載任何數(shù)據(jù)育谬,僅僅表示計算的依賴關(guān)系。

bool Edge::IsControlEdge() const {
   return src_output_ == Graph::kControlSlot;
}

節(jié)點

Node(節(jié)點)持有零條或多條輸入/輸出的邊帮哈,分別使用in_edges, out_edges表示膛檀。另外,Node持有NodeDef, OpDef娘侍。其中咖刃,NodeDef持有設(shè)備分配信息,及其OP的屬性值集合私蕾;OpDef持有OP的元數(shù)據(jù)僵缺。

節(jié)點

輸入邊

在輸入邊的集合中按照索引線性查找,當節(jié)點輸入的邊比較多時踩叭,可能會成為性能的瓶頸磕潮。依次類推,按照索引查找輸出邊容贝,算法相同自脯。

Status Node::input_edge(int idx, const Edge** e) const {
  for (auto edge : in_edges()) {
    if (edge->dst_input() == idx) {
      *e = edge;
      return Status::OK();
    }
  }
  return errors::NotFound("not found input edge ", idx);
}

前驅(qū)節(jié)點

首先通過idx索引找到輸入邊,然后通過輸入邊找到前驅(qū)節(jié)點斤富。依次類推膏潮,按照索引查找后驅(qū)節(jié)點,算法相同满力。

Status Node::input_node(int idx, const Node** n) const {
  const Edge* e;
  TF_RETURN_IF_ERROR(input_edge(idx, &e));
  if (e == nullptr) {
    *n = nullptr;
  } else {
    *n = e->src();
  }
  return Status::OK();
}

Graph(計算圖)就是節(jié)點與邊的集合焕参,領(lǐng)域模型何其簡單轻纪。計算圖是一個DAG圖,計算圖的執(zhí)行過程將按照DAG的拓撲排序叠纷,依次啟動OP的運算刻帚。其中,如果存在多個入度為0的節(jié)點涩嚣,TensorFlow運行時可以實現(xiàn)并發(fā)崇众,同時執(zhí)行多個OP的運算,提高執(zhí)行效率航厚。

空圖

計算圖的初始狀態(tài)顷歌,并非是一個空圖。實現(xiàn)添加了兩個特殊的節(jié)點:Source與Sink節(jié)點幔睬,分別表示DAG圖的起始節(jié)點與終止節(jié)點眯漩。其中,Source的id為0溪窒,Sink的id為1坤塞;依次論斷,普通OP節(jié)點的id將大于1澈蚌。

另外摹芙,Source與Sink之間,通過連接「控制依賴」的邊宛瞄,保證計算圖的執(zhí)行始于Source節(jié)點浮禾,終于Sink節(jié)點。它們之前連接的控制依賴邊份汗,其src_output, dst_input值都為-1盈电。

習慣上,僅包含Source與Sink節(jié)點的計算圖也常常稱為空圖杯活。

空圖
Node* Graph::AddEndpoint(const char* name, int id) {
  NodeDef def;
  def.set_name(name);
  def.set_op("NoOp");

  Status status;
  Node* node = AddNode(def, &status);
  TF_CHECK_OK(status);
  CHECK_EQ(node->id(), node_id);
  return node;
}

Graph::Graph(const OpRegistryInterface* ops)
    : ops_(ops), arena_(8 << 10 /* 8kB */) {
  auto src  = AddEndpoint("_SOURCE", kSourceId);
  auto sink = AddEndpoint("_SINK",   kSinkId);
  AddControlEdge(src, sink);
}

非空圖

在前端匆帚,用戶使用OP構(gòu)造器,將構(gòu)造任意復雜度的計算圖旁钧。對于運行時吸重,無非就是將用戶構(gòu)造的計算圖通過控制依賴的邊與Source/Sink節(jié)點連接,保證計算圖執(zhí)行始于Source節(jié)點歪今,終于Sink節(jié)點嚎幸。

非空圖

添加邊

計算圖的構(gòu)造過程非常簡單,首先通過Graph::AddNode在圖中放置節(jié)點寄猩,然后再通過Graph::AddEdge在圖中放置邊嫉晶,實現(xiàn)節(jié)點之間的連接。

const Edge* Graph::AllocEdge() const {
  Edge* e = nullptr;
  if (free_edges_.empty()) {
    e = new (arena_.Alloc(sizeof(Edge))) Edge;
  } else {
    e = free_edges_.back();
    free_edges_.pop_back();
  }
  e->id_ = edges_.size();
  return e;
}

const Edge* Graph::AddEdge(Node* source, int x, Node* dest, int y) {
  auto e = AllocEdge();
  e->src_ = source;
  e->dst_ = dest;
  e->src_output_ = x;
  e->dst_input_ = y;

  CHECK(source->out_edges_.insert(e).second);
  CHECK(dest->in_edges_.insert(e).second);

  edges_.push_back(e);
  edge_set_.insert(e);
  return e;
}

添加控制依賴邊,則可以轉(zhuǎn)發(fā)調(diào)用Graph::AddEdge實現(xiàn)替废。

const Edge* Graph::AddControlEdge(Node* src, Node* dst) {
  return AddEdge(src, kControlSlot, dst, kControlSlot);
}

開源技術(shù)書

https://github.com/horance-liu/tensorflow-internals
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末箍铭,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子椎镣,更是在濱河造成了極大的恐慌坡疼,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件衣陶,死亡現(xiàn)場離奇詭異,居然都是意外死亡闸氮,警方通過查閱死者的電腦和手機剪况,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蒲跨,“玉大人译断,你說我怎么就攤上這事』虮” “怎么了孙咪?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵,是天一觀的道長巡语。 經(jīng)常有香客問我翎蹈,道長,這世上最難降的妖魔是什么男公? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任荤堪,我火速辦了婚禮,結(jié)果婚禮上枢赔,老公的妹妹穿的比我還像新娘澄阳。我一直安慰自己,他們只是感情好踏拜,可當我...
    茶點故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布碎赢。 她就那樣靜靜地躺著,像睡著了一般速梗。 火紅的嫁衣襯著肌膚如雪肮塞。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天镀琉,我揣著相機與錄音峦嗤,去河邊找鬼。 笑死屋摔,一個胖子當著我的面吹牛烁设,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼装黑,長吁一口氣:“原來是場噩夢啊……” “哼副瀑!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起恋谭,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤糠睡,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后疚颊,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體狈孔,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年材义,在試婚紗的時候發(fā)現(xiàn)自己被綠了均抽。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡其掂,死狀恐怖油挥,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情款熬,我是刑警寧澤深寥,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站贤牛,受9級特大地震影響惋鹅,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜殉簸,卻給世界環(huán)境...
    茶點故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一负饲、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧喂链,春花似錦返十、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蝇率,卻和暖如春迟杂,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背本慕。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工排拷, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人锅尘。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓监氢,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子浪腐,可洞房花燭夜當晚...
    茶點故事閱讀 43,472評論 2 348

推薦閱讀更多精彩內(nèi)容