Create a graph that is 'depth' deep. At each level, fan-in and fan-out a maximum of 'width' nodes. All nodes are no-ops and all dependencies are control dependencies.
| 425 | // maximum of 'width' nodes. All nodes are no-ops and all dependencies are |
| 426 | // control dependencies. |
| 427 | static void BM_executor(int iters, int width, int depth) { |
| 428 | #ifdef PLATFORM_GOOGLE |
| 429 | BenchmarkUseRealTime(); |
| 430 | #endif // PLATFORM_GOOGLE |
| 431 | Graph* g = new Graph(OpRegistry::Global()); |
| 432 | random::PhiloxRandom philox(1729, 17); |
| 433 | random::SimplePhilox rand(&philox); |
| 434 | uint64 cur = 0; |
| 435 | uint32 r = 1 + rand.Rand32() % width; |
| 436 | std::vector<Node*> ready_nodes; |
| 437 | for (int i = 0; i < r; ++i) { |
| 438 | ready_nodes.push_back(test::graph::NoOp(g, {})); |
| 439 | ++cur; |
| 440 | } |
| 441 | std::random_device random_device; |
| 442 | std::mt19937 rng(random_device()); |
| 443 | for (int i = 0; i < depth; ++i) { |
| 444 | std::shuffle(ready_nodes.begin(), ready_nodes.end(), rng); |
| 445 | r = 1 + rand.Rand32() % (ready_nodes.size()); |
| 446 | std::vector<Node*> control_inputs; |
| 447 | for (int j = 0; j < r; ++j) { |
| 448 | control_inputs.push_back(ready_nodes.back()); |
| 449 | ready_nodes.pop_back(); |
| 450 | } |
| 451 | Node* n = test::graph::NoOp(g, control_inputs); |
| 452 | ++cur; |
| 453 | r = 1 + rand.Rand32() % width; |
| 454 | for (int j = 0; j < r; ++j) { |
| 455 | ready_nodes.push_back(test::graph::NoOp(g, {n})); |
| 456 | ++cur; |
| 457 | } |
| 458 | } |
| 459 | #ifdef PLATFORM_GOOGLE |
| 460 | SetBenchmarkLabel(strings::StrCat("Nodes = ", cur)); |
| 461 | SetBenchmarkItemsProcessed(cur * static_cast<int64>(iters)); |
| 462 | #endif // PLATFORM_GOOGLE |
| 463 | test::Benchmark("cpu", g).Run(iters); |
| 464 | } |
| 465 | |
| 466 | // Tall skinny graphs |
| 467 | BENCHMARK(BM_executor)->ArgPair(16, 1024); |