// Copyright 2021 DeepMind Technologies Limited // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include #include #include #include #include #include #include "test/fixture.h" namespace mujoco { namespace { // number of steps to roll out before benchmarking static const int kNumWarmupSteps = 500; // number of steps to benchmark (before resetting state) static const int kBatchSize = 50; // number of threads to test static const int kNumThreads = 6; void BM_StepHumanoid200(benchmark::State& state) { int nthread = state.range(0); std::string label = std::to_string(nthread) + " thread(s)"; auto model_path = GetTestDataFilePath("benchmark/testdata/humanoid200.xml"); std::array error; mjModel* model = mj_loadXML(model_path.c_str(), nullptr, error.data(), error.size()); model->opt.solver = mjSOL_CG; // use CG solver model->opt.disableflags &= ~mjDSBL_ISLAND; // enable islands mjData* data = mj_makeData(model); if (nthread) { mju_threadpool(data, nthread); } // warm-up rollout to get a steady state for (int i = 0; i < kNumWarmupSteps; i++) { mj_step(model, data); } // save the initial state and step int spec = mjSTATE_INTEGRATION; int size = mj_stateSize(model, spec); std::vector initial_state(size); mj_getState(model, data, initial_state.data(), spec); while (state.KeepRunningBatch(kBatchSize)) { // reset to the saved state mj_setState(model, data, initial_state.data(), spec); // run a batch of steps for (int i = 0; i < kBatchSize; i++) { mj_step(model, data); } } state.SetLabel(label); state.SetItemsProcessed(state.iterations()); mj_deleteData(data); } void BM_Step22Humanoids(benchmark::State& state) { int nthread = state.range(0); std::string label = std::to_string(nthread) + " thread(s)"; auto model_path = GetModelPath("humanoid/22_humanoids.xml"); std::array error; mjModel* model = mj_loadXML(model_path.c_str(), nullptr, error.data(), error.size()); model->opt.solver = mjSOL_CG; // use CG solver model->opt.disableflags &= ~mjDSBL_ISLAND; // enable islands mjData* data = mj_makeData(model); if (nthread) { mju_threadpool(data, nthread); } // warm-up rollout to get a steady state for (int i = 0; i < kNumWarmupSteps; i++) { mj_step(model, data); } // save the initial state and step int spec = mjSTATE_INTEGRATION; int size = mj_stateSize(model, spec); std::vector initial_state(size); mj_getState(model, data, initial_state.data(), spec); std::vector ctrl = GetCtrlNoise(model, kBatchSize); while (state.KeepRunningBatch(kBatchSize)) { // reset to the saved state mj_setState(model, data, initial_state.data(), spec); // run a batch of steps for (int i = 0; i < kBatchSize; i++) { mju_copy(data->ctrl, ctrl.data()+model->nu*i, model->nu); mj_step(model, data); } } state.SetLabel(label); state.SetItemsProcessed(state.iterations()); mj_deleteData(data); } BENCHMARK(BM_StepHumanoid200)->Arg(0)->Arg(kNumThreads); BENCHMARK(BM_Step22Humanoids)->Arg(0)->Arg(kNumThreads); } // namespace } // namespace mujoco