Repository: Qiskit/qiskit

Issue:
Calculate Number of memoryslots required  based on input schedules if not set.
<!-- ⚠️ If you do not respect this template, your issue will be closed -->
<!-- ⚠️ Make sure to browse the opened and closed issues to confirm this idea does not exist. -->

### What is the expected enhancement?
At qobj assembly time the number of `memory_slots` required should be calculated from the input schedules if it is not set.




Discussion:

Resolving patch:
diff --git a/qiskit/assembler/assemble_schedules.py b/qiskit/assembler/assemble_schedules.py
--- a/qiskit/assembler/assemble_schedules.py
+++ b/qiskit/assembler/assemble_schedules.py
@@ -42,6 +42,9 @@ def assemble_schedules(schedules, qobj_id, qobj_header, run_config):
     qubit_lo_range = qobj_config.pop('qubit_lo_range')
     meas_lo_range = qobj_config.pop('meas_lo_range')
     meas_map = qobj_config.pop('meas_map', None)
+
+    max_memory_slot = 0
+
     instruction_converter = instruction_converter(PulseQobjInstruction, **qobj_config)
 
     lo_converter = LoConfigConverter(PulseQobjExperimentConfig, qubit_lo_range=qubit_lo_range,
@@ -70,6 +73,9 @@ def assemble_schedules(schedules, qobj_id, qobj_header, run_config):
                 if meas_map:
                     # verify all acquires satisfy meas_map
                     _validate_meas_map(instruction, meas_map)
+                    max_memory_slot = max(max_memory_slot,
+                                          *[slot.index for slot in instruction.mem_slots])
+
             qobj_instructions.append(instruction_converter(shift, instruction))
 
         # experiment header
@@ -82,6 +88,9 @@ def assemble_schedules(schedules, qobj_id, qobj_header, run_config):
             'instructions': qobj_instructions
         })
 
+    # set number of memoryslots
+    qobj_config['memory_slots'] = max_memory_slot
+
     # setup pulse_library
     qobj_config['pulse_library'] = [PulseLibraryItem(name=pulse.name, samples=pulse.samples)
                                     for pulse in user_pulselib.values()]
diff --git a/qiskit/compiler/assemble.py b/qiskit/compiler/assemble.py
--- a/qiskit/compiler/assemble.py
+++ b/qiskit/compiler/assemble.py
@@ -33,7 +33,7 @@ def assemble(experiments,
              qubit_lo_freq=None, meas_lo_freq=None,  # schedule run options
              qubit_lo_range=None, meas_lo_range=None,
              schedule_los=None, meas_level=2, meas_return='avg', meas_map=None,
-             memory_slots=None, memory_slot_size=100, rep_time=None, parameter_binds=None,
+             memory_slot_size=100, rep_time=None, parameter_binds=None,
              **run_config):
     """Assemble a list of circuits or pulse schedules into a Qobj.
 
@@ -102,9 +102,6 @@ def assemble(experiments,
         meas_map (list):
             List of lists, containing qubits that must be measured together.
 
-        memory_slots (int):
-            Number of classical memory slots used in this job.
-
         memory_slot_size (int):
             Size of each memory slot if the output is Level 0.
 
@@ -138,8 +135,7 @@ def assemble(experiments,
                                                        qubit_lo_freq, meas_lo_freq,
                                                        qubit_lo_range, meas_lo_range,
                                                        schedule_los, meas_level, meas_return,
-                                                       meas_map, memory_slots,
-                                                       memory_slot_size, rep_time,
+                                                       meas_map, memory_slot_size, rep_time,
                                                        parameter_binds, **run_config)
 
     # assemble either circuits or schedules
@@ -165,8 +161,7 @@ def _parse_run_args(backend, qobj_id, qobj_header,
                     qubit_lo_freq, meas_lo_freq,
                     qubit_lo_range, meas_lo_range,
                     schedule_los, meas_level, meas_return,
-                    meas_map, memory_slots,
-                    memory_slot_size, rep_time,
+                    meas_map, memory_slot_size, rep_time,
                     parameter_binds, **run_config):
     """Resolve the various types of args allowed to the assemble() function through
     duck typing, overriding args, etc. Refer to the assemble() docstring for details on
@@ -198,7 +193,7 @@ def _parse_run_args(backend, qobj_id, qobj_header,
             )
 
     meas_map = meas_map or getattr(backend_config, 'meas_map', None)
-    memory_slots = memory_slots or getattr(backend_config, 'memory_slots', None)
+
     rep_time = rep_time or getattr(backend_config, 'rep_times', None)
     if isinstance(rep_time, list):
         rep_time = rep_time[0]
@@ -246,7 +241,6 @@ def _parse_run_args(backend, qobj_id, qobj_header,
                            meas_level=meas_level,
                            meas_return=meas_return,
                            meas_map=meas_map,
-                           memory_slots=memory_slots,
                            memory_slot_size=memory_slot_size,
                            rep_time=rep_time,
                            parameter_binds=parameter_binds,


Test patch:
diff --git a/test/python/compiler/test_assembler.py b/test/python/compiler/test_assembler.py
--- a/test/python/compiler/test_assembler.py
+++ b/test/python/compiler/test_assembler.py
@@ -283,7 +283,6 @@ def setUp(self):
 
         self.config = {
             'meas_level': 1,
-            'memory_slots': 2,
             'memory_slot_size': 100,
             'meas_return': 'avg',
             'rep_time': 100
@@ -400,6 +399,15 @@ def test_assemble_meas_map(self):
         with self.assertRaises(QiskitError):
             assemble(schedule, meas_map=[[0, 1, 2]])
 
+    def test_assemble_memory_slots(self):
+        """Test assembling a schedule and inferring number of memoryslots."""
+        acquire = pulse.Acquire(5)
+        n_memoryslots = 10
+        schedule = acquire(self.device.acquires[0], mem_slots=pulse.MemorySlot(n_memoryslots))
+
+        qobj = assemble(schedule, meas_map=[[0], [1]])
+        self.assertEqual(qobj.config.memory_slots, n_memoryslots)
+
     def test_pulse_name_conflicts(self):
         """Test that pulse name conflicts can be resolved."""
         name_conflict_pulse = pulse.SamplePulse(