The timing feature for QBSolv

Hi All,

How can I get to know the timing of the QBSolv using Tabu algorithm locally? Is there a feature that returns the overall time for the Solver to process a problem QUBO matrix?

 Up till now, I used time.time() before and after the Solver call to compute the timing, is that accurate?

Thanks.

1

Comments

9 comments
  • Hello,

    So it depends what timing information you are trying to obtain. 
    If you are looking at software run time, then what you are doing should work alright.

    For the QPU we have timing information to let you know how much of the QPU time was actually used and how long it took the algorithm to run.
    Sometimes the network overhead, etc. can add quite a bit of time to the runtime that you would obtain from time.time().

    Running algorithms locally, it makes sense to use the time.time() method.

    Another thing about the Tabu Sampler is that you can set a time limit on how long it runs by setting the timeout parameter.
    This way you decide how long you want it to run.

    Unlike the DWaveSampler, the info variable in the returned SampleSet does not have any timing information for TabuSampler.

    What is the use case for obtaining the timing information?
    There might be other libraries that are good for determining process runtimes.

    You might want to add timing functions into the code, rather than just wrap around the highest level depending on your use case.

    I hope this was helpful!
    Please let us know if you have any more questions.

    0
    Comment actions Permalink
  • Thanks David,

    We are running use case on network using QPU and would like to compare it with a classical solver (QBSolver using Tabu algorithm, for example) in terms of speed.

    As the QBSolver does not have timing info and is running locally, I am using time.time() to record the processing time...The value turns out to be more than 10 times larger than the overall QPU time running the DWaveSampler as shown in the timing info feature. That's huge. Sounds too good to be true within my shallow knowledge in the field.

    Henceforth, I am checking to make sure whether the measurement approach is correct.

    Please let me have your insights.

    0
    Comment actions Permalink
  • Hello,

    This documentation walks through how the QPU access time fits into the overall request to sample a problem:
    https://docs.dwavesys.com/docs/latest/doc_timing.html

    In subsequent pages the QPU access time is broken down further into the time spent on each subtask, such as writing a problem to the QPU, annealing (running) a problem, and reading back the solution.

    As you can see from the documentation, there is network latency and other costs associated with sending the problem to the QPU.
    The time that the algorithm runs on the QPU, however is really very short.

    The Tabu/QBSolv implementation is all run classically on your local machine, so there is not the same overhead in sending the problem over the network to another machine.

    In general it is very difficult to make a direct comparison between classical computing and quantum annealing, so time comparisons will inherently be a little strange.

    I hope this helps to answer your question.

    Please feel free to reach out with more questions!

    0
    Comment actions Permalink
  • Hi David, thanks for your explanation.

    I am encountering another problem. I have J and H matrix sized over 50....I used both QBSolver and 2000Q/Advantage_Sys1 to solve it. It turned out the solutions returned by the QPU is always less optimal than those returned by the QBSolver. I set the num_reads to be as large as 9999, the solutions returned by QPU is not as low as that returned by the QBSolver.

    Please kindly advise whether it is the usual case.(I doubt so)..and henceforth why it happened. Supposedly the QPU return solutions as good as those returned by the classic processor in a faster speed, is not it?

     

     

    0
    Comment actions Permalink
  • Hi Jie,

    There are various factors that might be responsible for the poor results and these are problem specific. Can you please provide a minimal code example?

    In the meantime, here are a few resources that might help you tune your problem and improve the results:

    0
    Comment actions Permalink
  • Thanks Tanvi,

    I suspect it is something to do with the problem itself. My J and H matrixes are below:

    [0 0 -143525 90814.8 -1 -3 0 1 -1 0 0 2 -1 0 0 1 -1 0 0 2 -1 0 0 2]=H_prob

    J_prob, H_core and J_core have all the coefficients either -1,1,0,2,-2,3,-3.....

    So my results are always very close to the ground truth like below:

    QBSolverEne:-3712608.7

    2000QEne:-3712604.7

    Adv-SysEne:-3712602.7

    For this result, I set both the chainStrength and the constraint value to 143252*1.5. I decreased the chainStrength value to 15...the results do not change.

    My short codes are below:

    response=QBSolv().sample_ising(Hdict,Jdict)
    timeinst2=time.time()
    timelap=timeinst2-timeinst1
    print('QBSolvertime is:'+str(timelap))
    A=list(response.samples())
    sol1=A[0]
    bqm=dimod.BinaryQuadraticModel.from_ising(Hdict,Jdict,offset=0.0)
    solver_type='DW_2000Q_6'
    expt_sampler = EmbeddingComposite(DWaveSampler(endpoint='https://cloud.dwavesys.com/sapi/',token='DEV-XXX',solver='DW_2000Q_6'))
    timeinst1=time.time()
    response=expt_sampler.sample(bqm,chain_strength=chainVal,num_reads=nreads) # make call to D-Wave solver
    A=response.info["timing"]
    val1=A[u'total_real_time']/1000000.0
    print('2000Qtime is:'+str(val1))
    sol2=next(response.data(['sample']))[0]
     
    solver_type='Advatange_system1.1'
    #solver_type='hybrid_discrete_quadratic_model_version1'
    timeinst1=time.time()
    response=expt_sampler.sample(bqm,num_reads=nreads) # make call to D-Wave solver
    timeinst2=time.time()
    A=response.info["timing"] 
    val2=A[u'total_real_time']/1000000.0
    print('Advtime is:'+str(val2))
     
    sol3=next(response.data(['sample']))[0]
     
    a=list(sol1.values())
    SOL1=numpy.array(a)
    b=list(sol2.values())
    SOL2=numpy.array(b)
    c=list(sol3.values())
    SOL3=numpy.array(c)
     
    a=SOL1.dot(J)
    ans1=a.dot(numpy.transpose(SOL1))+SOL1.dot(numpy.transpose(H))
     
    b=SOL2.dot(J)
    ans2=b.dot(numpy.transpose(SOL2))+SOL2.dot(numpy.transpose(H))
     
    c=SOL3.dot(J)
    ans3=c.dot(numpy.transpose(SOL3))+SOL3.dot(numpy.transpose(H))
     
    print('QBSolverEne:'+str(ans1))
    print('2000QEne:'+str(ans2))
    print('Adv-SysEne:'+str(ans3))
     
    Please kindly advise.

    Thanks.

    0
    Comment actions Permalink
  • Hi Jie,

    Thank you for patience.

    I am still looking into the issue. I did not see Hdict or Jdict in the code you provided. I would like to try running it, as that will help me make suggestions for what else you can try. Would you mind posting your Hdict and JDict?

    I agree that the issue might be related to the problem formulation as the energy states are clustered. Due to this QPU might have a hard time finding the ground/lowest energy state.

    Getting more information about the problem might help me understand the issue better.

    0
    Comment actions Permalink
  • Hi Jie,

    Thank you for sharing the information. I figured that you are using h_core, j_core, h_prob and j_prob to formulate Hdict and Jdict. Please correct me if I am wrong.

    After trying your problem, I noticed that the energy gap is very small. The energy gap is the energy between the ground state and the first excited state. A small gap makes it easier to jump into an excited state during the anneal

    The best way to address this behavior is to reformulate your problem. Here are some resources on how to do that: https://docs.dwavesys.com/docs/latest/handbook_reformulating.html

    In your example, tuning chain strength did not reflect any change in performance because for this trivial problem no chains are needed to embed the problem onto the QPU. Usually, having a high chain_break_fraction is indicative of the need for chain_strength tuning.

    Please note that the problem is scaled to [-1, 1] so it can be run on the QPU. So, due to the huge bias range [-99541, 10971.9], auto-scaling squeezes the rest of the problem into basically round-off error.

    As your problem has sparse connectivity(sparse J matrix) and large h biases, you can use roof duality to fix_variables. Roof duality is a polynomial-time preprocessing step that finds the variables that have an obvious optimal value.  It then sets these values; the variables are converted to constants and the problem is reduced.

    Please let me know if you have further questions.

    0
    Comment actions Permalink

Please sign in to leave a comment.

Didn't find what you were looking for?

New post