* @brief Determine and allocate all resources for the solver * @param _graph graph * @param _optimizer optimizer or learning rate * @param _num_partition number of partitions * @param _num_negative number of negative samples per positive sample * @param _batch_size batch size of samples in CPU-GPU transfer * @param _episode_size number of batches in a partition block
| 285 | * @param _episode_size number of batches in a partition block |
| 286 | */ |
| 287 | void build(Graph &_graph, const Optimizer &_optimizer = kAuto, int _num_partition = kAuto, int _num_negative = 1, |
| 288 | int _batch_size = 100000, int _episode_size = kAuto) { |
| 289 | graph = &_graph; |
| 290 | optimizer = _optimizer; |
| 291 | if (optimizer.type == "Default") { |
| 292 | Optimizer default_optimizer = get_default_optimizer(); |
| 293 | if (optimizer.init_lr > 0) |
| 294 | default_optimizer.init_lr = optimizer.init_lr; |
| 295 | optimizer = default_optimizer; |
| 296 | } |
| 297 | num_vertex = graph->num_vertex; |
| 298 | num_edge = graph->num_edge; |
| 299 | num_moment = optimizer.num_moment; |
| 300 | num_partition = _num_partition; |
| 301 | num_negative = _num_negative; |
| 302 | batch_size = _batch_size; |
| 303 | LOG_IF(WARNING, batch_size < kMinBatchSize) |
| 304 | << "It is recommended to a minimum batch size of " << kMinBatchSize |
| 305 | << ", but " << batch_size << " is specified"; |
| 306 | episode_size = _episode_size; |
| 307 | available_models = get_available_models(); |
| 308 | batch_id = 0; |
| 309 | |
| 310 | // build embeddings & moments |
| 311 | protocols = get_protocols(); |
| 312 | sampler_protocol = get_sampler_protocol(); |
| 313 | num_embedding = protocols.size(); |
| 314 | embeddings.resize(num_embedding); |
| 315 | moments.resize(num_embedding); |
| 316 | |
| 317 | auto shapes = get_shapes(); |
| 318 | CHECK(shapes.size() == num_embedding) << "The number of shapes must equal to the number of embedding matrices"; |
| 319 | Protocol all = 0; |
| 320 | tied_weights = false; |
| 321 | for (int i = 0; i < num_embedding; i++) { |
| 322 | Protocol protocol = protocols[i]; |
| 323 | CHECK(bool(protocol & kGlobal) + bool(protocol & kHeadPartition) + bool(protocol & kTailPartition) == 1) |
| 324 | << "The embedding matrix can be only binded to either global range, head partition " |
| 325 | << "or tail partition"; |
| 326 | if (protocol & (kHeadPartition | kTailPartition)) { |
| 327 | if (shapes[i] == kAuto) |
| 328 | shapes[i] = num_vertex; |
| 329 | else |
| 330 | CHECK(shapes[i] == num_vertex) |
| 331 | << "The shape for a partitioned embedding matrix must be `graph->num_vertex`"; |
| 332 | } else |
| 333 | CHECK(!(protocol & kInPlace)) << "Global embedding matrix can't take in-place update"; |
| 334 | CHECK(shapes[i] != kAuto) << "Can't deduce shape for the " << i << "-th embedding matrix"; |
| 335 | |
| 336 | if (protocol & kSharedWithPredecessor) { |
| 337 | CHECK(i > 0) << "The first embedding matrix can't be shared"; |
| 338 | CHECK(shapes[i] == shapes[i - 1]) |
| 339 | << "The " << i - 1 << "-th and the " << i << "-th matrices are shared, " |
| 340 | << "but different shapes are specified"; |
| 341 | tied_weights = tied_weights || ((protocols[i] | protocols[i - 1]) & |
| 342 | (kHeadPartition | kTailPartition)) == (kHeadPartition | kTailPartition); |
| 343 | embeddings[i] = embeddings[i - 1]; |
| 344 | moments[i] = moments[i - 1]; |
no test coverage detected