File size: 16,242 Bytes
9425aed | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 | ! BOB Quantum Civilization Engine - C ABI Wrapper
! Module: bob_abi
! Purpose: Complete C-compatible interface for all BOB functionality
! Standard: Fortran 2018
module bob_abi
use, intrinsic :: iso_c_binding
use bob_kinds
use bob_errors
use bob_state
use bob_gates
use bob_rng
use bob_lattice
use bob_measurement
use bob_metrics
use bob_hamiltonian
use bob_integrator
implicit none
private
! Export all C functions
public :: bob_engine_version
public :: bob_engine_info
public :: bob_last_error_message
contains
!> Get engine version string
subroutine bob_engine_version(version_str, max_len) bind(C, name="bob_engine_version")
character(kind=c_char), dimension(*), intent(out) :: version_str
integer(c_int), value :: max_len
character(len=64) :: version
integer :: i, len_version
version = "BOB Quantum Engine v1.0.0"
len_version = min(len_trim(version), max_len - 1)
do i = 1, len_version
version_str(i) = version(i:i)
end do
version_str(len_version + 1) = c_null_char
end subroutine bob_engine_version
!> Get engine information
subroutine bob_engine_info(info_str, max_len) bind(C, name="bob_engine_info")
character(kind=c_char), dimension(*), intent(out) :: info_str
integer(c_int), value :: max_len
character(len=512) :: info
integer :: i, len_info
info = "BOB Quantum Civilization Engine" // c_new_line // &
"Fortran 2018 Implementation" // c_new_line // &
"Features: State vectors, Gates, Lattices, Measurement, " // &
"Hamiltonians, Time evolution" // c_new_line // &
"License: MIT (Sovereign Source)"
len_info = min(len_trim(info), max_len - 1)
do i = 1, len_info
info_str(i) = info(i:i)
end do
info_str(len_info + 1) = c_null_char
end subroutine bob_engine_info
!> Get last error message
subroutine bob_last_error_message(msg_str, max_len) bind(C, name="bob_last_error_message")
character(kind=c_char), dimension(*), intent(out) :: msg_str
integer(c_int), value :: max_len
character(len=256) :: message
integer :: i, len_msg
integer(i4) :: error_code
error_code = bob_get_last_error()
message = bob_error_message(error_code)
if (len_trim(g_error_state%message) > 0) then
message = trim(message) // ": " // trim(g_error_state%message)
end if
if (len_trim(g_error_state%location) > 0) then
message = trim(message) // " [" // trim(g_error_state%location) // "]"
end if
len_msg = min(len_trim(message), max_len - 1)
do i = 1, len_msg
msg_str(i) = message(i:i)
end do
msg_str(len_msg + 1) = c_null_char
end subroutine bob_last_error_message
!> Create complete quantum simulation
function bob_simulation_create(num_qubits, seed) result(sim_ptr) &
bind(C, name="bob_simulation_create")
integer(c_int64_t), value :: num_qubits
integer(c_int64_t), value :: seed
type(c_ptr) :: sim_ptr
type :: bob_simulation
type(bob_quantum_state) :: state
type(bob_hamiltonian_operator) :: hamiltonian
type(bob_time_integrator) :: integrator
type(bob_rng_state) :: rng
type(bob_quantum_metrics) :: metrics
end type bob_simulation
type(bob_simulation), pointer :: sim
integer(i8) :: dim
allocate(sim)
! Initialize RNG
call sim%rng%init(seed)
! Create state
dim = ishft(1_i8, int(num_qubits))
call sim%state%allocate(dim, "simulation_state")
! Initialize to |0...0⟩
sim%state%amplitudes = CZERO
sim%state%amplitudes(1) = CONE
sim%state%is_normalized = .true.
! Create Hamiltonian
call sim%hamiltonian%init(dim, "simulation_hamiltonian")
! Create integrator (RK4 by default)
call sim%integrator%init(INTEGRATOR_RK4, 0.01_wp, "simulation_integrator")
! Initialize metrics
call sim%metrics%init()
sim_ptr = c_loc(sim)
end function bob_simulation_create
!> Destroy simulation
subroutine bob_simulation_destroy(sim_ptr) bind(C, name="bob_simulation_destroy")
type(c_ptr), value :: sim_ptr
type :: bob_simulation
type(bob_quantum_state) :: state
type(bob_hamiltonian_operator) :: hamiltonian
type(bob_time_integrator) :: integrator
type(bob_rng_state) :: rng
type(bob_quantum_metrics) :: metrics
end type bob_simulation
type(bob_simulation), pointer :: sim
if (.not. c_associated(sim_ptr)) return
call c_f_pointer(sim_ptr, sim)
call sim%state%deallocate()
call sim%hamiltonian%destroy()
deallocate(sim)
end subroutine bob_simulation_destroy
!> Run simulation step
function bob_simulation_step(sim_ptr) result(status) &
bind(C, name="bob_simulation_step")
type(c_ptr), value :: sim_ptr
integer(c_int) :: status
type :: bob_simulation
type(bob_quantum_state) :: state
type(bob_hamiltonian_operator) :: hamiltonian
type(bob_time_integrator) :: integrator
type(bob_rng_state) :: rng
type(bob_quantum_metrics) :: metrics
end type bob_simulation
type(bob_simulation), pointer :: sim
if (.not. c_associated(sim_ptr)) then
status = BOB_ERROR_INVALID_ARGUMENT
return
end if
call c_f_pointer(sim_ptr, sim)
! Take integration step
call sim%integrator%step(sim%state, sim%hamiltonian)
status = bob_get_last_error()
end function bob_simulation_step
!> Get simulation metrics
function bob_simulation_get_metrics(sim_ptr, energy, entropy, coherence) result(status) &
bind(C, name="bob_simulation_get_metrics")
type(c_ptr), value :: sim_ptr
real(c_double), intent(out) :: energy, entropy, coherence
integer(c_int) :: status
type :: bob_simulation
type(bob_quantum_state) :: state
type(bob_hamiltonian_operator) :: hamiltonian
type(bob_time_integrator) :: integrator
type(bob_rng_state) :: rng
type(bob_quantum_metrics) :: metrics
end type bob_simulation
type(bob_simulation), pointer :: sim
if (.not. c_associated(sim_ptr)) then
status = BOB_ERROR_INVALID_ARGUMENT
energy = ZERO
entropy = ZERO
coherence = ZERO
return
end if
call c_f_pointer(sim_ptr, sim)
! Compute metrics
call sim%metrics%compute_all(sim%state, sim%hamiltonian%matrix)
energy = sim%metrics%energy
entropy = sim%metrics%von_neumann_entropy
coherence = sim%metrics%coherence
status = bob_get_last_error()
end function bob_simulation_get_metrics
!> Batch operations: Create multiple states
function bob_batch_create_states(num_states, dim) result(batch_ptr) &
bind(C, name="bob_batch_create_states")
integer(c_int64_t), value :: num_states, dim
type(c_ptr) :: batch_ptr
type :: bob_state_batch
integer(i8) :: num_states
type(bob_quantum_state), allocatable :: states(:)
end type bob_state_batch
type(bob_state_batch), pointer :: batch
integer(i8) :: i
integer :: stat
allocate(batch, stat=stat)
if (stat /= 0) then
batch_ptr = c_null_ptr
return
end if
batch%num_states = num_states
allocate(batch%states(num_states), stat=stat)
if (stat /= 0) then
deallocate(batch)
batch_ptr = c_null_ptr
return
end if
do i = 1, num_states
call batch%states(i)%allocate(dim, "batch_state")
end do
batch_ptr = c_loc(batch)
end function bob_batch_create_states
!> Destroy batch of states
subroutine bob_batch_destroy_states(batch_ptr) bind(C, name="bob_batch_destroy_states")
type(c_ptr), value :: batch_ptr
type :: bob_state_batch
integer(i8) :: num_states
type(bob_quantum_state), allocatable :: states(:)
end type bob_state_batch
type(bob_state_batch), pointer :: batch
integer(i8) :: i
if (.not. c_associated(batch_ptr)) return
call c_f_pointer(batch_ptr, batch)
do i = 1, batch%num_states
call batch%states(i)%deallocate()
end do
deallocate(batch%states)
deallocate(batch)
end subroutine bob_batch_destroy_states
!> Parallel gate application
function bob_batch_apply_gate(batch_ptr, gate_type, qubit_index) result(status) &
bind(C, name="bob_batch_apply_gate")
type(c_ptr), value :: batch_ptr
integer(c_int), value :: gate_type
integer(c_int64_t), value :: qubit_index
integer(c_int) :: status
type :: bob_state_batch
integer(i8) :: num_states
type(bob_quantum_state), allocatable :: states(:)
end type bob_state_batch
type(bob_state_batch), pointer :: batch
integer(i8) :: i
if (.not. c_associated(batch_ptr)) then
status = BOB_ERROR_INVALID_ARGUMENT
return
end if
call c_f_pointer(batch_ptr, batch)
! Apply gate to all states
!$omp parallel do if(batch%num_states > 10)
do i = 1, batch%num_states
call apply_single_qubit_gate(batch%states(i), gate_type, qubit_index)
end do
!$omp end parallel do
status = BOB_SUCCESS
end function bob_batch_apply_gate
!> Snapshot operations: Save state to file
function bob_snapshot_save(state_ptr, filename, filename_len) result(status) &
bind(C, name="bob_snapshot_save")
type(c_ptr), value :: state_ptr
character(kind=c_char), dimension(*) :: filename
integer(c_int), value :: filename_len
integer(c_int) :: status
type(bob_quantum_state), pointer :: state
character(len=:), allocatable :: fname
integer :: unit, i, iostat
if (.not. c_associated(state_ptr)) then
status = BOB_ERROR_INVALID_ARGUMENT
return
end if
call c_f_pointer(state_ptr, state)
! Convert C string to Fortran string
allocate(character(len=filename_len) :: fname)
do i = 1, filename_len
fname(i:i) = filename(i)
end do
! Open file
open(newunit=unit, file=fname, form='unformatted', &
access='stream', status='replace', iostat=iostat)
if (iostat /= 0) then
status = BOB_ERROR_IO
return
end if
! Write state
write(unit, iostat=iostat) state%dim
write(unit, iostat=iostat) state%amplitudes
write(unit, iostat=iostat) state%is_normalized
close(unit)
if (iostat /= 0) then
status = BOB_ERROR_IO
else
status = BOB_SUCCESS
end if
end function bob_snapshot_save
!> Load state from file
function bob_snapshot_load(filename, filename_len) result(state_ptr) &
bind(C, name="bob_snapshot_load")
character(kind=c_char), dimension(*) :: filename
integer(c_int), value :: filename_len
type(c_ptr) :: state_ptr
type(bob_quantum_state), pointer :: state
character(len=:), allocatable :: fname
integer :: unit, i, iostat
integer(i8) :: dim
logical(lk) :: is_normalized
! Convert C string
allocate(character(len=filename_len) :: fname)
do i = 1, filename_len
fname(i:i) = filename(i)
end do
! Open file
open(newunit=unit, file=fname, form='unformatted', &
access='stream', status='old', iostat=iostat)
if (iostat /= 0) then
state_ptr = c_null_ptr
return
end if
! Read dimension
read(unit, iostat=iostat) dim
if (iostat /= 0) then
close(unit)
state_ptr = c_null_ptr
return
end if
! Allocate state
allocate(state)
call state%allocate(dim, "loaded_state")
! Read amplitudes
read(unit, iostat=iostat) state%amplitudes
read(unit, iostat=iostat) is_normalized
close(unit)
if (iostat /= 0) then
call state%deallocate()
deallocate(state)
state_ptr = c_null_ptr
return
end if
state%is_normalized = is_normalized
state_ptr = c_loc(state)
end function bob_snapshot_load
!> Utility: Get state amplitude
function bob_state_get_amplitude(state_ptr, index, real_part, imag_part) result(status) &
bind(C, name="bob_state_get_amplitude")
type(c_ptr), value :: state_ptr
integer(c_int64_t), value :: index
real(c_double), intent(out) :: real_part, imag_part
integer(c_int) :: status
type(bob_quantum_state), pointer :: state
if (.not. c_associated(state_ptr)) then
status = BOB_ERROR_INVALID_ARGUMENT
real_part = ZERO
imag_part = ZERO
return
end if
call c_f_pointer(state_ptr, state)
if (index < 0 .or. index >= state%dim) then
status = BOB_ERROR_INVALID_ARGUMENT
real_part = ZERO
imag_part = ZERO
return
end if
real_part = real(state%amplitudes(index + 1))
imag_part = aimag(state%amplitudes(index + 1))
status = BOB_SUCCESS
end function bob_state_get_amplitude
!> Utility: Set state amplitude
function bob_state_set_amplitude(state_ptr, index, real_part, imag_part) result(status) &
bind(C, name="bob_state_set_amplitude")
type(c_ptr), value :: state_ptr
integer(c_int64_t), value :: index
real(c_double), value :: real_part, imag_part
integer(c_int) :: status
type(bob_quantum_state), pointer :: state
if (.not. c_associated(state_ptr)) then
status = BOB_ERROR_INVALID_ARGUMENT
return
end if
call c_f_pointer(state_ptr, state)
if (index < 0 .or. index >= state%dim) then
status = BOB_ERROR_INVALID_ARGUMENT
return
end if
state%amplitudes(index + 1) = cmplx(real_part, imag_part, cwp)
state%is_normalized = .false.
status = BOB_SUCCESS
end function bob_state_set_amplitude
end module bob_abi
! Made with Bob
|