Bengali
Languages
English
Bengali
French
German
Japanese
Korean
Portuguese
Spanish
Tamil

নোট

এই পৃষ্ঠাটি tutorials/circuits_advanced/1_advanced_circuits.ipynb থেকে উৎপন্ন হয়েছে।

পালস সময়সূচী তৈরির পদ্ধতি

তড়িৎস্পন্দন বা পালস একটি বর্তনী (সার্কিট) যুক্তিবর্তনী (গেইট) জন্য একটি মৌলিক স্তরের, সঠিক উপস্থাপনা সংজ্ঞায়িত করে | একটি একক ক্রিয়াকলাপ (অপারেশন) একটি তড়িৎস্পন্দন বা তড়িৎস্পন্দন বা পালস নির্দেশমালার সাথে বাস্তবায়ন করা যেতে পারে, যা একাধিক মৌলিক স্তরের নির্দেশাবলী নিয়ে গঠিত। তড়িৎস্পন্দন বা তড়িৎস্পন্দন বা পালস গেট সম্পর্কে আরও জানতে, প্রদর্শক (ডকুমেন্টেশন) ফিরে যান এখানে <05_pulse_gates.ipynb> __। এই পৃষ্ঠাটি কীভাবে তড়িৎস্পন্দন বা পালস নির্দেশমালা তৈরি করতে হয় তা বিশদ করে।

টীকা: আই. বি. এম এর যন্ত্রের জন্য, তড়িৎস্পন্দন বা পালস নির্দেশমালা গেট বর্ণনা করার জন্য সাবরুটিন হিসাবে ব্যবহৃত হয়। পূর্বে, কিছু যন্ত্রের এই বিন্যাসে সম্পূর্ণ প্রোগ্রামগুলো গ্রহণ করাছিল, কিন্তু এটি 2021 সালের ডিসেম্বরে বন্ধ হচ্ছে। অন্যান্য প্রোভাইডার এখনও এই বিন্যাসে সম্পূর্ণ প্রোগ্রাম গ্রহণ করতে পারে। প্রোগ্রামটি যেভাবেই ব্যবহার করা হোক না কেন, প্রোগ্রাম তৈরির গঠন (সিনট্যাক্স) একই। কিভাবে জানতে পড়ুন!

Pulse programs, which are called Schedules, describe instruction sequences for the control electronics. We build Schedules using the Pulse Builder. It’s easy to initialize a schedule:

[20]:
from qiskit import pulse

with pulse.build(name='my_example') as my_program:
    # Add instructions here
    pass

my_program
[20]:
ScheduleBlock(, name="my_example", transform=AlignLeft())

আপনি দেখতে পারেন যে এখনও কোন নির্দেশনা নেই। এই পৃষ্ঠার পরবর্তী অংশটি আপনি যে সময়সূচীতে যোগ করতে পারেন তার প্রতিটি নির্দেশাবলী ব্যাখ্যা করবে এবং শেষ অংশটি বিভিন্ন alignment contexts বর্ণনা করবে, যা নির্দেশ করে কিভাবে একে অপরের আপেক্ষিক সময়ে নির্দেশাবলী স্থাপন করা হয়।

Schedule নির্দেশনা

প্রতিটি নির্দেশনা ধরনের নিজস্ব অপারেন্ড গুচ্ছ আছে। আপনি উপরে দেখতে পাচ্ছেন, নির্দেশাবলী কোথায় প্রয়োগ করা হবে তা নির্দিষ্ট করার জন্য তাদের প্রতিটিতে কমপক্ষে একটি Channel অন্তর্ভুক্ত রয়েছে।

চ্যানেল হল নিয়ন্ত্রণ যন্ত্র থেকে কোয়ান্টাম চিপ পর্যন্ত সিগন্যাল লাইনের নাম (লেবেল)।

  • DriveChannelগুলি সাধারণত একক কিউবিট ঘূর্ণনের * ড্রাইভিং * এর জন্য ব্যবহৃত হয়,

  • ControlChannelগুলি সাধারণত মাল্টি-কিউবিট গেট বা টিউনেবল (tunable)কিউবিটগুলির অতিরিক্ত ড্রাইভ লাইনের জন্য ব্যবহৃত হয়,

  • MeasureChannelগুলি পালস প্রেরণের জন্য নির্দিষ্ট যা রিড-আউটকে উদ্দীপিত করে, এবং

  • ডিজিটাইজারগুলিকে ট্রিগার করতে AcquireChannelগুলি ব্যবহার করা হয় যা রিড-আউট সিগন্যাল সংগ্রহ করে।

DriveChannel, ControlChannel, এবং MeasureChannelগুলি সব PulseChannel; এর মানে হল যে তারা * পালস প্রেরণ * সমর্থন করে, যেখানে AcquireChannel শুধুমাত্র একটি রিসিভ চ্যানেল এবং তরঙ্গরূপ চালাতে পারে না।

নিম্নলিখিত উদাহরণগুলির জন্য, আমরা প্রতিটি Instruction এর জন্য একটি DriveChannel উদাহরণ তৈরি করব যা একটি PulseChannel গ্রহণ করে। চ্যানেলগুলি একটি পূর্ণসংখ্যা index আর্গুমেন্ট নেয়। ControlChannelগুলি ছাড়া, সূচকটি ট্রিভিয়ালি কিউবিট লেবেলে ম্যাপ করে।

[21]:
from qiskit.pulse import DriveChannel

channel = DriveChannel(0)

পালস Schedule যে ব্যাকএন্ড এর উপর চলে তার থেকে স্বাধীন। যাইহোক, আমরা একটি প্রেক্ষাপটে আমাদের প্রোগ্রাম তৈরি করতে পারি যা pulse.build এ সরবরাহ করার দ্বারা টার্গেট ব্যাকএন্ড সম্বন্ধে অবগত হয়। সম্ভব হলে আপনার একটি ব্যাকএন্ড সরবরাহ করা উচিত। চ্যানেল অ্যাক্সেসর pulse.<type>_channel(<idx>) ব্যবহার করে আমরা নিশ্চিত করতে পারি যে আমরা কেবল উপলব্ধ ডিভাইস রিসোর্স ব্যবহার করছি।

[22]:
from qiskit.providers.fake_provider import FakeValencia

backend = FakeValencia()

with pulse.build(backend=backend, name='backend_aware') as backend_aware_program:
    channel = pulse.drive_channel(0)
    print(pulse.num_qubits())
    # Raises an error as backend only has 5 qubits
    #pulse.drive_channel(100)
5

delay

অন্যতম সহজ একটি নির্দেশনা আমরা তৈরী করতে পারি যা হলো delay। এটি একটি ব্লকিং নির্দেশ যা নির্দিষ্ট ইলেকট্রনিক্সকে নির্দিষ্ট সময়ের জন্য প্রদত্ত চ্যানেলে কোন সংকেত আউটপুট করতে বলে না। এটি অন্যান্য নির্দেশাবলীর সময় নিয়ন্ত্রণের জন্য দরকারী।

The duration here and elsewhere is in terms of the backend’s cycle time (1 / sample rate), dt. It must take an integer value.

একটি delay নির্দেশ যোগ করার জন্য, আমরা একটি সময়কাল এবং একটি চ্যানেল পাস করি, যেখানে channel, AcquireChannel সহ যেকোনো ধরনের চ্যানেল হতে পারে। আমরা একটি পালস বিল্ডার প্রসঙ্গ শুরু করতে pulse.build ব্যবহার করি। যা স্বয়ংক্রিয়ভাবে আমাদের বিলম্বকে সময়সূচী delay_5dt তে নির্ধারণ করে।

[23]:
with pulse.build(backend) as delay_5dt:
    pulse.delay(5, channel)

That’s all there is to it. Any instruction added after this delay on the same channel will execute five timesteps later than it would have without this delay.

play

The play instruction is responsible for executing pulses. It’s straightforward to add a play instruction:

with pulse.build() as sched:
    pulse.play(pulse, channel)

Let’s clarify what the pulse argument is and explore a few different ways to build one.

তড়িৎস্পন্দন বা পালস

একটি Pulse একটি ইচ্ছাধীন পালস envelope নির্দিষ্ট করে। আউটপুট ওয়েভফর্মের ফেজ এবং মড্যুলেশন ফ্রিকোয়েন্সি যথাক্রমে set_frequency এবং shift_phase নির্দেশাবলী দ্বারা নিয়ন্ত্রিত হয়, যা আমরা পরবর্তীতে কভার করবো।

The image below may provide some intuition for why they are specified separately. Think of the pulses which describe their envelopes as input to an arbitrary waveform generator (AWG), a common lab instrument – this is depicted in the left image. Notice the limited sample rate discritizes the signal. The signal produced by the AWG may be mixed with a continuous sine wave generator. The frequency of its output is controlled by instructions to the sine wave generator; see the middle image. Finally, the signal sent to the qubit is demonstrated by the right side of the image below.

** দ্রষ্টব্য **: হার্ডওয়্যার অন্যান্য উপায়েও প্রয়োগ করা যেতে পারে, কিন্তু যদি আমরা নির্দেশাবলী গুলি আলাদা রাখি, তাহলে আমরা স্পষ্ট তথ্য হারানো এড়াতে পারি , যেমন মড্যুলেশন ফ্রিকোয়েন্সিটির মান।

alt text

There are many methods available to us for building up pulses. Our library within Qiskit Pulse contains helpful methods for building Pulses. Let’s take for example a simple Gaussian pulse – a pulse with its envelope described by a sampled Gaussian function. We arbitrarily choose an amplitude of 1, standard deviation \(\sigma\) of 10, and 128 sample points.

Note: The amplitude norm is arbitrarily limited to 1.0. Each backend system may also impose further constraints – for instance, a minimum pulse size of 64. These additional constraints, if available, would be provided through the BackendConfiguration which is described here.

[24]:
from qiskit.pulse import library

amp = 1
sigma = 10
num_samples = 128

পরামিতিক তড়িৎস্পন্দন বা পালস

Let’s build our Gaussian pulse using the Gaussian parametric pulse. A parametric pulse sends the name of the function and its parameters to the backend, rather than every individual sample. Using parametric pulses makes the jobs you send to the backend much smaller. IBM Quantum backends limit the maximum job size that they accept, so parametric pulses may allow you to run larger programs.

library এর অন্যান্য প্যারামেট্রিক পালসগুলির মধ্যে রয়েছে GaussianSquare, Drag এবং Constant

** দ্রষ্টব্য **: প্যারামেট্রিক তড়িৎস্পন্দন বা পালসের নমুনা ঠিক কিভাবে নিতে হবে তা নির্ধারণের জন্য ব্যাকএন্ড দায়ী। প্যারামেট্রিক তড়িৎস্পন্দন বা পালস আঁকা সম্ভব, কিন্তু প্রদর্শিত নমুনাগুলি ব্যাকএন্ডে কার্যকর হওয়াগুলির সমান হওয়ার নিশ্চয়তা দেয় না।

[25]:
gaus = pulse.library.Gaussian(num_samples, amp, sigma,
                              name="Parametric Gaus")
gaus.draw()
[25]:
../../_images/tutorials_circuits_advanced_06_building_pulse_schedules_12_0.png

নমুনা দ্বারা বর্ণিত পালস ওভেফর্মস

একটি ওয়েভফর্ম হল একটি পালস সিগন্যাল যা সময়-নির্দেশিত জটিল পরিবর্ধন বা *নমুনা * এর একটি অ্যারে হিসাবে নির্দিষ্ট করা হয়। প্রতিটি নমুনা একটি চক্রের জন্য বাজানো হয়, একটি টাইমস্টেপ dt, ব্যাকএন্ড দ্বারা নির্ধারিত। যদি আমরা আমাদের প্রোগ্রামের রিয়েল-টাইম গতিবিদ্যা জানতে চাই, তাহলে আমাদের dt এর মান জানতে হবে। (শূন্য-সূচীকৃত) \(i^{th}\) নমুনাটি i*dt সময় থেকে (i + 1)*dt পর্যন্ত চলবে, যা কিউবিট ফ্রিকোয়েন্সি দ্বারা সংশোধন করা হবে।

[26]:
import numpy as np

times = np.arange(num_samples)
gaussian_samples = np.exp(-1/2 *((times - num_samples / 2) ** 2 / sigma**2))

gaus = library.Waveform(gaussian_samples, name="WF Gaus")
gaus.draw()
[26]:
../../_images/tutorials_circuits_advanced_06_building_pulse_schedules_14_0.png

তড়িৎস্পন্দন বা পালস লাইব্রেরি ফাংশন

আমাদের নিজস্ব পালস লাইব্রেরিতে সাধারণ ফাংশন থেকে Waveform তৈরির নমুনা পদ্ধতি রয়েছে।

[27]:
gaus = library.gaussian(duration=num_samples, amp=amp, sigma=sigma, name="Lib Gaus")
gaus.draw()
[27]:
../../_images/tutorials_circuits_advanced_06_building_pulse_schedules_16_0.png

আপনার pulse নির্দিষ্ট করার জন্য আপনি যে পদ্ধতিটি ব্যবহার করেন না কেন, play আপনার সময়সূচীতে একইভাবে যোগ করা হয়:

[28]:
with pulse.build() as schedule:
    pulse.play(gaus, channel)
schedule.draw()
[28]:
../../_images/tutorials_circuits_advanced_06_building_pulse_schedules_18_0.png

আপনি একটি জটিল তালিকা বা অ্যারে সরাসরি play তে সরবরাহ করতে পারেন

[29]:
with pulse.build() as schedule:
    pulse.play([0.001*i for i in range(160)], channel)
schedule.draw()
[29]:
../../_images/tutorials_circuits_advanced_06_building_pulse_schedules_20_0.png

প্লে নির্দেশটি তার পালস থেকে এর সময়কাল পায়: একটি প্যারামেট্রাইজড পালসের সময়কাল একটি স্পষ্ট আর্গুমেন্ট, এবং একটি ওয়েভফর্ম এর সময়কাল ইনপুট নমুনার সংখ্যা।

set_frequency

পূর্বে ব্যাখ্যা করা হয়েছে, আউটপুট পালস তরঙ্গাকৃতি আচ্ছাদন এছাড়াও একটি ফ্রিকোয়েন্সি এবং ফেজ দ্বারা সংশোধন করা হয়। প্রতিটি চ্যানেলের একটি default frequency listed in the backend.defaults() আছে।

একটি চ্যানেলের ফ্রিকোয়েন্সি set_frequency নির্দেশ দ্বারা একটি সময়সূচী এর মধ্যে যে কোন সময় আপডেট করা যেতে পারে। এটি একটি float ফ্রিকোয়েন্সি এবং একটি PulseChannel চ্যানেল ইনপুট হিসাবে নেয়। একটি set_frequency নির্দেশ অনুসরণ করে একটি চ্যানেলে সমস্ত তড়িৎস্পন্দন বা পালস প্রদত্ত ফ্রিকোয়েন্সি দ্বারা মড্যুলেট করা হবে যতক্ষণ না অন্য একটি set_frequency নির্দেশনা আসে অথবা প্রোগ্রাম শেষ না হওয়া পর্যন্ত।

নির্দেশটির 0 এর একটি অন্তর্নিহিত সময়কাল রয়েছে।

দ্রষ্টব্য: যে ফ্রিকোয়েন্সিগুলি অনুরোধ করা যেতে পারে তা মোট ব্যান্ডউইথ এবং প্রতিটি হার্ডওয়্যার চ্যানেলের তাৎক্ষণিক ব্যান্ডউইথ দ্বারা সীমাবদ্ধ। ভবিষ্যতে, এগুলি ব্যাকএন্ড দ্বারা রিপোর্ট করা হবে।

[30]:
with pulse.build(backend) as schedule:
    pulse.set_frequency(4.5e9, channel)

shift_phase

Shift_phase নির্দেশ ফ্রিকোয়েন্সি মড্যুলেশন এর ফেজ phase দ্বারা বৃদ্ধি করবে। Set_frequency এর মত, এই ফেজ শিফট প্রোগ্রাম শেষ না হওয়া পর্যন্ত একই চ্যানেলে নিম্নলিখিত সমস্ত নির্দেশাবলীকে প্রভাবিত করবে। একটি shift_phase এর প্রভাব পূর্বাবস্থায় ফেরানোর জন্য, negative ফেজ একটি নতুন নির্দেশে প্রেরণ করা যেতে পারে।

Set_frequency এর মত, নির্দেশের 0 এর অন্তর্নিহিত সময়কাল রয়েছে।

[31]:
with pulse.build(backend) as schedule:
    pulse.shift_phase(np.pi, channel)

acquire

acquire নির্দেশনাটি রিডআউট এর জন্য ডেটা অধিগ্রহণকে ট্রিগার করে। এটি একটি সময় নেয়, একটি AcquireChannel যা পরিমাপকৃত কিউবিট, এবং একটি MemorySlot বা RegisterSlot কে ম্যাপ করে। MemorySlot হল ক্লাসিক্যাল মেমরি যেখানে রিডআউট ফলাফল সংরক্ষণ করা হবে। RegisterSlot কন্ট্রোল ইলেকট্রনিক্সের একটি রেজিস্টারে ম্যাপ করে যা দ্রুত প্রতিক্রিয়া জানার জন্য রিডআউট ফলাফল সংরক্ষণ করে।

acquire নির্দেশাবলী কাস্টম Discriminators এবং Kernels গুলিকে কীওয়ার্ড আর্গুমেন্ট হিসাবে গ্রহণ করতে পারে।

[32]:
from qiskit.pulse import Acquire, AcquireChannel, MemorySlot

with pulse.build(backend) as schedule:
    pulse.acquire(1200, pulse.acquire_channel(0), MemorySlot(0))

Now that we know how to add Schedule instructions, let’s learn how to control exactly when they’re played.

পালস বিল্ডার

এখানে, আমরা কিভাবে সময়সূচী তৈরি করতে হয় তা শেখার জন্য সর্বাধিক গুরুত্বপূর্ণ পালস বিল্ডার এর বৈশিষ্ট্যগুলি পুনরালোচনা করবো। এটি সম্পূর্ণ নয়; পালস বিল্ডার ব্যবহার করে আপনি কি করতে পারেন সে সম্পর্কে আরো বিস্তারিত জানার জন্য, Pulse API reference <https://qiskit.org/documentation/apidoc/pulse.html> দেখুন।

প্রান্তিককরণ প্রসঙ্গ

বিল্ডার এর সারিবদ্ধকরণ প্রসঙ্গ রয়েছে যা একটি সময়সূচী কীভাবে তৈরি হয় তা প্রভাবিত করে। প্রসঙ্গগুলিও বাসা বাঁধতে পারে। তাদের চেষ্টা করে দেখুন, এবং pulse গুলি কিভাবে একত্রিত হয় তা দেখতে ".draw ()" ব্যবহার করুন।

Regardless of the alignment context, the duration of the resulting schedule is as short as it can be while including every instruction and following the alignment rules. This still allows some degrees of freedom for scheduling instructions off the "longest path". The examples below illuminate this.

align_left

বিল্ডার এর সারিবদ্ধকরণ প্রসঙ্গ রয়েছে যা একটি সময়সূচী কীভাবে তৈরি হয় তা প্রভাবিত করে। ডিফল্ট হল "align_left"।

[33]:
with pulse.build(backend, name='Left align example') as program:
    with pulse.align_left():
        gaussian_pulse = library.gaussian(100, 0.5, 20)
        pulse.play(gaussian_pulse, pulse.drive_channel(0))
        pulse.play(gaussian_pulse, pulse.drive_channel(1))
        pulse.play(gaussian_pulse, pulse.drive_channel(1))

program.draw()
[33]:
../../_images/tutorials_circuits_advanced_06_building_pulse_schedules_28_0.png

লক্ষ্য করুন কিভাবে "D1" এ পালস গুলির জন্য কোন নির্ধারিত স্বাধীনতা নেই। প্রথম তরঙ্গের পরপরই দ্বিতীয় তরঙ্গরূপ শুরু হয়। সামগ্রিক সময়সূচির সময়কাল পরিবর্তন না করে "D0" এর পালসটি "t = 0" এবং "t = 100" এর মধ্যে যেকোনো সময় শুরু হতে পারে। "Align_left" প্রসঙ্গ এই পালসটির শুরুর সময়কে "t = 0" এ সেট করে। আপনি এটিকে একটি টেক্সট ডকুমেন্টের বাম-ন্যায্যতার মতো ভাবতে পারেন।

align_right

Unsurprisingly, align_right does the opposite of align_left. It will choose t=100 in the above example to begin the gaussian pulse on D0. Left and right are also sometimes called "as soon as possible" and "as late as possible" scheduling, respectively.

[34]:
with pulse.build(backend, name='Right align example') as program:
    with pulse.align_right():
        gaussian_pulse = library.gaussian(100, 0.5, 20)
        pulse.play(gaussian_pulse, pulse.drive_channel(0))
        pulse.play(gaussian_pulse, pulse.drive_channel(1))
        pulse.play(gaussian_pulse, pulse.drive_channel(1))

program.draw()
[34]:
../../_images/tutorials_circuits_advanced_06_building_pulse_schedules_30_0.png

align_equispaced(duration)

যদি একটি নির্দিষ্ট ব্লকের সময়কাল জানা থাকে, আপনি প্রতিটি নির্দেশের মধ্যে একই সময়কাল বিলম্ব যুক্ত করতে align_equispaced ব্যবহার করতে পারেন।

[35]:
with pulse.build(backend, name='example') as program:
    gaussian_pulse = library.gaussian(100, 0.5, 20)
    with pulse.align_equispaced(2*gaussian_pulse.duration):
        pulse.play(gaussian_pulse, pulse.drive_channel(0))
    pulse.play(gaussian_pulse, pulse.drive_channel(1))
    pulse.play(gaussian_pulse, pulse.drive_channel(1))

program.draw()
[35]:
../../_images/tutorials_circuits_advanced_06_building_pulse_schedules_32_0.png

align_sequential

এই প্রান্তিককরণ প্রসঙ্গ সমান্তরাল নির্দেশাবলী নির্ধারণ করে না। প্রতিটি নির্দেশ পূর্বে যোগ করা নির্দেশের শেষে শুরু হবে।

[36]:
with pulse.build(backend, name='example') as program:
    with pulse.align_sequential():
        gaussian_pulse = library.gaussian(100, 0.5, 20)
        pulse.play(gaussian_pulse, pulse.drive_channel(0))
        pulse.play(gaussian_pulse, pulse.drive_channel(1))
        pulse.play(gaussian_pulse, pulse.drive_channel(1))

program.draw()
[36]:
../../_images/tutorials_circuits_advanced_06_building_pulse_schedules_34_0.png

ফেজ এবং ফ্রিকোয়েন্সি অফসেট

আমরা একটি চ্যানেলে আমাদের ফ্রিকোয়েন্সি বা পালস এর পর্যায়কে অস্থায়ীভাবে অফসেট করতে বিল্ডার এর সহায়তা নিতে পারি।

[37]:
with pulse.build(backend, name='Offset example') as program:
    with pulse.phase_offset(3.14, pulse.drive_channel(0)):
        pulse.play(gaussian_pulse, pulse.drive_channel(0))
        with pulse.frequency_offset(10e6, pulse.drive_channel(0)):
            pulse.play(gaussian_pulse, pulse.drive_channel(0))

program.draw()
[37]:
../../_images/tutorials_circuits_advanced_06_building_pulse_schedules_36_0.png

আরো জানার জন্য আমরা আপনাকে Pulse API reference দেখার জন্য উৎসাহিত করছি।

[38]:
import qiskit.tools.jupyter
%qiskit_version_table
%qiskit_copyright

Version Information

Qiskit SoftwareVersion
qiskit-terra0.22.3
qiskit-aer0.11.2
qiskit-ignis0.7.0
qiskit-ibmq-provider0.19.2
qiskit0.39.4
System information
Python version3.10.6
Python compilerGCC 11.3.0
Python buildmain, Nov 14 2022 16:10:14
OSLinux
CPUs4
Memory (Gb)3.7695083618164062
Thu Dec 22 18:42:20 2022 JST

This code is a part of Qiskit

© Copyright IBM 2017, 2022.

This code is licensed under the Apache License, Version 2.0. You may
obtain a copy of this license in the LICENSE.txt file in the root directory
of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.

Any modifications or derivative works of this code must retain this
copyright notice, and modified files need to carry a notice indicating
that they have been altered from the originals.