Annealing schedule! Need example.

Hey there

Is there any example to show how one can create annealing schedule? After searching the documentation and also reading the post below (see link below), I still can't find any clear description for how we can put 'annealing_schedule' to work?

Here an example I tried:

----------------------------------

bqm = dimod.BinaryQuadraticModel.from_ising(h, J)
anneal_schedule = [[0.0, 0.0], [2.0, 1.0]]
solver.validate_anneal_schedule(anneal_schedule) --> [this worked!]
response = dimod.ExactSolver().sample(bqm, anneal_schedule) --->[this gave an error!]

-----------------------------------

Error:

response = dimod.ExactSolver().sample(bqm, anneal_schedule)
TypeError: _index_label() takes 2 positional arguments but 3 were given

I understand the error meaning but how can we pass the annealing schedule to 'sample'? Can you please provide a simple example?

 

 This post is related to the discussion of this post (https://support.dwavesys.com/hc/en-us/community/posts/360014009713-Controlling-the-global-annealing-schedule)

 

Thank you

3

Comments

7 comments
  • OK, I did some reading and here is my solution, hope it will help someone else too:

     

    You can setup the annealing schedule as follow:

    ---------------------------------------------------------------------------------------- 

       anneal_schedule = [(0.0,0.0),(10.0,0.5),(110.0,0.5),(120.0,1.0)]
        #---- The above annealing gives:
        # Mid-anneal pause at s=0.5. The quadratic growth of B(t) is interrupted by a 100-μs pause halfway through.
        #Check the max_anneal_schedule_points solver property to obtain the max annealing value.
        # Read the doc at: https://docs.dwavesys.com/docs/latest/c_qpu_annealing.html

        bqm = dimod.BinaryQuadraticModel.from_ising(h, J)
        solution = solver.sample(bqm, anneal_schedule = anneal_schedule, num_reads = 1000)
        #--- This also works:
        #solution = solver.sample_ising(h, J, anneal_schedule = anneal_schedule, num_reads = 1000)

    ---------------------------------------------------------------------------------------

    The 'solver' here is: solver = DWaveSampler()

     

    Good luck.

    1
    Comment actions Permalink
  • Hello Ahmed,

    Thank you for posting your example here - this is a great reference for other users. We're glad you were able to sort out the procedure.

    1
    Comment actions Permalink
  • Hi Ahmed,

    A custom anneal schedule is not appropriate for the exact solver (dimod.ExactSolver). The exact solver gives every possible answer and performs its calculations in your client. A custom anneal schedule controls the rates at which annealing is performed on the actual D-Wave chip.

    (A word of caution - most people probably will never need a custom annealing schedule.)

    The code listed below is an example that uses custom annealing.

    from dwave.system.samplers import DWaveSampler

    # Example code that uses different annealing schedules.

    # Default 20us anneal
    def anneal_sched_custom_20():
        return (
            (0.0, 0.0), # Start the anneal (time 0.0) at 0.0 (min)
            (20.0, 1.0) # After 20us, set the anneal setting to 1.0 (max)
        )

    # Quench the anneal after 10us
    def anneal_sched_custom_10():
        return (
            (0.0, 0.0), # Start the anneal (time 0.0) at 0.0 (min)
            (10.0, 1.0) # After 10us, set the anneal setting to 1.0 (max)
        )

    # Quench the anneal after 5us
    def anneal_sched_custom_5():
        return (
            (0.0, 0.0), # Start the anneal (time 0.0) at 0.0 (min)
            (5.0, 1.0)  # After 5us, set the anneal setting to 1.0 (max)
        )

    # Quench the anneal after 1us
    def anneal_sched_custom_1():
        return (
            (0.0, 0.0), # Start the anneal (time 0.0) at 0.0 (min)
            (1.0, 1.0)  # After 1us, set the anneal setting to 1.0 (max)
        )

    # An anneal schedule can have up to four points.

    def anneal_sched_custom_special():
        return (
            (0.0, 0.0),   # Start everything at 0
            (1.0, 0.25),  # Quickly ramp up to 0.25 anneal at 1us
            (19.0, 0.75), # Hold the anneal at 0.25 until 19us, then go up to 0.75
            (20.0, 1.0)   # End the full anneal at 20us
        )

    print('Boolean NOT Gate with Default Annealing Schedule')
    sampler = DWaveSampler()
    Q = {(0, 0): -1, (0, 4): 0, (4, 0): 2, (4, 4): -1}

    response_20 = sampler.sample_qubo(Q, anneal_schedule=anneal_sched_custom_20(), num_reads=50)
    response_10 = sampler.sample_qubo(Q, anneal_schedule=anneal_sched_custom_10(), num_reads=50)
    response_5 = sampler.sample_qubo(Q, anneal_schedule=anneal_sched_custom_5(), num_reads=50)
    response_1 = sampler.sample_qubo(Q, anneal_schedule=anneal_sched_custom_1(), num_reads=50)
    response_special = sampler.sample_qubo(Q, anneal_schedule=anneal_sched_custom_special(), num_reads=50)

    print('With 20us anneal schedule:')
    for sample, energy, num_occurrences in response_20.data():
        print(sample, "Energy: ", energy, "Occurrences: ", num_occurrences)

    print('With 10us anneal schedule:')
    for sample, energy, num_occurrences in response_10.data():
        print(sample, "Energy: ", energy, "Occurrences: ", num_occurrences)

    print('With 5us anneal schedule:')
    for sample, energy, num_occurrences in response_5.data():
        print(sample, "Energy: ", energy, "Occurrences: ", num_occurrences)

    print('With 1us anneal schedule:')
    for sample, energy, num_occurrences in response_1.data():
        print(sample, "Energy: ", energy, "Occurrences: ", num_occurrences)

    print('With a 4-point special anneal schedule:')
    for sample, energy, num_occurrences in response_special.data():
        print(sample, "Energy: ", energy, "Occurrences: ", num_occurrences)

     

    And here is output after running the code once:

     

    Boolean NOT Gate with Default Annealing Schedule
    With 20us anneal schedule:
    {0: 0, 4: 1} Energy:  -1.0 Occurrences:  21
    {0: 1, 4: 0} Energy:  -1.0 Occurrences:  29
    With 10us anneal schedule:
    {0: 0, 4: 1} Energy:  -1.0 Occurrences:  22
    {0: 1, 4: 0} Energy:  -1.0 Occurrences:  28
    With 5us anneal schedule:
    {0: 0, 4: 1} Energy:  -1.0 Occurrences:  32
    {0: 1, 4: 0} Energy:  -1.0 Occurrences:  18
    With 1us anneal schedule:
    {0: 0, 4: 1} Energy:  -1.0 Occurrences:  16
    {0: 1, 4: 0} Energy:  -1.0 Occurrences:  34
    With a 4-point special anneal schedule:
    {0: 0, 4: 1} Energy:  -1.0 Occurrences:  22
    {0: 1, 4: 0} Energy:  -1.0 Occurrences:  28

     

    Let me know if this helps.

     

    2
    Comment actions Permalink
  • Thanks to Thomas for the great answer, and also to Ahmed for answering his own question. The main takeaway here is that the ExactSolver does not take this parameter.

    1
    Comment actions Permalink
  • There is a lack of detailed information in the docs about the 4 tuples meaning in the "anneal_schedule" parameter. I found this on the forum and I wonder if it is correct:

    ```

    anneal_schedule = (
    (0.0, 0.0), # Start the anneal (time 0.0) at 0.0 (min)
    (1.0, 0.25), # Quickly ramp up to 0.25 anneal at 1us
    (19.0, 0.75), # Hold the anneal at 0.25 until 19us, then go up to 0.75
    (20.0, 1.0) # End the full anneal at 20us
    )

    response = sampler.sample_qubo(Q, anneal_schedule=anneal_schedule, num_reads)

    ```

    Seems that the 2nd tuple is about the "quench", in this case, if I want to avoid the "quickly ramp", should I set up "(4, 0.25)" or (10, 0.5) ?

    Thank you very much.

    0
    Comment actions Permalink
  • About my previous question, that setup will run just 2us of the entire 20us anneal time? Just from 0 to 1us and from 19us to 20us?

    I thought the "pause" will hold the anneal for some microseconds, but after that the remain anneal time (19us) will run.

    e.: in a 20us anneal, if I want to pause it at 50% for 100us, it's possible?! (run first 10us, pause 100us, run last 10us)

    "(0.0, 0.0), (10.0, 0.50), (110.0, 0.50), (120.0, 1.0)" - is this considered a 20us annealing process with 100us pause, or is this a 120us annealing (QPU execution) process?

    Thank you.

    0
    Comment actions Permalink
  • Hello,

    Apologies for the prolonged delay!

    Where is this information from the first post in the documentation? 
    Could you possibly share a link so we have a little more context?

    Have you had a chance to look at the Jupyter Notebook for anneal schedules?

    You can go to the Jupyter Hub here:
    https://cloud.dwavesys.com/leap/learning/

    This is the Jupyter Notebook I am talking about:
    leap/techniques/anneal_schedule/01-anneal-schedule.ipynb

    Part way through it gives a great example of an anneal schedule visualization:

    Hopefully this answers your first question.
    I think the schedule you had mentioned looks a little different.

    As for your second question, the entire time in the anneal schedule is part of the anneal.
    This is all time running on the QPU.

    I hope this helps clarify things.

    Please let us know if you have any additional questions.
    Thank you for your patience and understanding! 

    0
    Comment actions Permalink

Please sign in to leave a comment.

Didn't find what you were looking for?

New post