def run_experiment(experiment, roleouts, episodes, in_cloud=False,
                   dynProfile=None):
    def run():
        if dynProfile is None:
            maxsteps = len(experiment.profile)
        else:
            maxsteps = dynProfile.shape[1]
        na = len(experiment.agents)
        ni = roleouts * episodes * maxsteps
        all_action = zeros((na, 0))
        all_reward = zeros((na, 0))
        epsilon = zeros((na, ni))
        vmarkup = vectorize(get_markup)
        for roleout in range(roleouts):
            if dynProfile is not None:
                i = roleout * episodes
                experiment.profile = dynProfile[i:i + episodes, :]
            experiment.doEpisodes(episodes)
            nei = episodes * maxsteps
            epi_action = zeros((0, nei))
            epi_reward = zeros((0, nei))
            for i, (task, agent) in \
            enumerate(zip(experiment.tasks, experiment.agents)):
                action = copy(agent.history["action"])
                reward = copy(agent.history["reward"])
                for j in range(nei):
                    if isinstance(agent.learner, DirectSearchLearner):
                        action[j, :] = task.denormalize(action[j, :])
                        k = nei * roleout
                        epsilon[i, k:k + nei] = agent.learner.explorer.sigma[0]
                    elif isinstance(agent.learner, ValueBasedLearner):
                        action[j, :] = vmarkup(action[j, :], task)
                        k = nei * roleout
                        epsilon[i, k:k + nei] = agent.learner.explorer.epsilon
                    else:
                        action = vmarkup(action, task)
                epi_action = c_[epi_action.T, action[:, 0].flatten()].T
                epi_reward = c_[epi_reward.T, reward.flatten()].T
                if hasattr(agent, "module"):
                    print "PARAMS:", agent.module.params
                agent.learn()
                agent.reset()
            all_action = c_[all_action, epi_action]
            all_reward = c_[all_reward, epi_reward]
        return all_action, all_reward, epsilon
    if in_cloud:
        import cloud
        job_id = cloud.call(run, _high_cpu=False)
        result = cloud.result(job_id)
        all_action, all_reward, epsilon = result
    else:
        all_action, all_reward, epsilon = run()
    return all_action, all_reward, epsilon