r""" An observer has exclusive access to its own environment. Each observer captures the state from its environment, and send the state to the agent to select an action. Then, the observer applies the action to its environment and reports the reward to the agent. It is true that
| 59 | |
| 60 | |
| 61 | class Observer: |
| 62 | r""" |
| 63 | An observer has exclusive access to its own environment. Each observer |
| 64 | captures the state from its environment, and send the state to the agent to |
| 65 | select an action. Then, the observer applies the action to its environment |
| 66 | and reports the reward to the agent. |
| 67 | |
| 68 | It is true that CartPole-v1 is a relatively inexpensive environment, and it |
| 69 | might be an overkill to use RPC to connect observers and trainers in this |
| 70 | specific use case. However, the main goal of this tutorial to how to build |
| 71 | an application using the RPC API. Developers can extend the similar idea to |
| 72 | other applications with much more expensive environment. |
| 73 | """ |
| 74 | def __init__(self, batch=True): |
| 75 | self.id = rpc.get_worker_info().id - 1 |
| 76 | self.env = gym.make('CartPole-v1') |
| 77 | self.env.reset(seed=args.seed) |
| 78 | self.select_action = Agent.select_action_batch if batch else Agent.select_action |
| 79 | |
| 80 | def run_episode(self, agent_rref, n_steps): |
| 81 | r""" |
| 82 | Run one episode of n_steps. |
| 83 | |
| 84 | Args: |
| 85 | agent_rref (RRef): an RRef referencing the agent object. |
| 86 | n_steps (int): number of steps in this episode |
| 87 | """ |
| 88 | state, _ = self.env.reset() |
| 89 | ep_reward = NUM_STEPS |
| 90 | rewards = torch.zeros(n_steps) |
| 91 | start_step = 0 |
| 92 | for step in range(n_steps): |
| 93 | state = torch.from_numpy(state).float().unsqueeze(0) |
| 94 | # send the state to the agent to get an action |
| 95 | action = rpc.rpc_sync( |
| 96 | agent_rref.owner(), |
| 97 | self.select_action, |
| 98 | args=(agent_rref, self.id, state) |
| 99 | ) |
| 100 | |
| 101 | # apply the action to the environment, and get the reward |
| 102 | state, reward, terminated, truncated, _ = self.env.step(action) |
| 103 | rewards[step] = reward |
| 104 | |
| 105 | if terminated or truncated or step + 1 >= n_steps: |
| 106 | curr_rewards = rewards[start_step:(step + 1)] |
| 107 | R = 0 |
| 108 | for i in range(curr_rewards.numel() -1, -1, -1): |
| 109 | R = curr_rewards[i] + args.gamma * R |
| 110 | curr_rewards[i] = R |
| 111 | state, _ = self.env.reset() |
| 112 | if start_step == 0: |
| 113 | ep_reward = min(ep_reward, step - start_step + 1) |
| 114 | start_step = step + 1 |
| 115 | |
| 116 | return [rewards, ep_reward] |
| 117 | |
| 118 |
nothing calls this directly
no outgoing calls
no test coverage detected