defget(self, name, hint): """Get the canonical name for a symbol. This is the default implementation. If the user specifies a name, the user-specified name will be used. When user does not specify a name, we automatically generate a name based on the hint string. Parameters ---------- name : str or None The name specified by the user. hint : str A hint string, which can be used to generate name. Returns ------- full_name : str A canonical name for the symbol. """ if name: return name if hint notin self._counter: self._counter[hint] = 0 name = '%s%d' % (hint, self._counter[hint]) self._counter[hint] += 1 return name
CHECK(!outputs[0].node->is_variable()) << "Variable cannot be composed"; // parameter check. for (size_t i = 0; i < args.size(); ++i) { CHECK_EQ(args[i]->outputs.size(), 1U) << "Argument " << i << " is a tuple, single value is required"; } for (constauto& kv : kwargs) { CHECK_EQ(kv.second->outputs.size(), 1U) << "Keyword Argument " << kv.first << " is a tuple, single value is required"; } // assign new name outputs[0].node->attrs.name = name;
// Atomic functor composition. if (IsAtomic(outputs)) { // n 是本 symbol 的输出 Node Node* n = outputs[0].node.get(); uint32_t n_req = n->num_inputs();
if (n_req != kVarg) { n->inputs.resize(n_req); CHECK_LE(args.size(), n_req) << "Incorrect number of arguments, requires " << n_req << ", provided " << args.size(); for (size_t i = 0; i < args.size(); ++i) { // 本 symbol 的 input 来自 下层的 symbol 即 args 的outputs // 十分注意一点, 这里使用的是 outputs[0], 所以, 使用的是下层输出的第 0 的位置 // 的内容, 这点在写具体 operator 的时候回有用 n->inputs[i] = args[i]->outputs[0]; }