fil-ocl 0.19.6

OpenCL bindings and interfaces for Rust.
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
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
//! Get information about all the things using `core` function calls.
//!
//! Set `INFO_FORMAT_MULTILINE` to `false` for compact printing.

extern crate fil_ocl as ocl;

use ocl::core::{self, PlatformInfo, DeviceInfo, ContextInfo,
    CommandQueueInfo, MemInfo, ImageInfo, SamplerInfo, ProgramInfo,
    ProgramBuildInfo, KernelInfo, KernelArgInfo, KernelWorkGroupInfo,
    EventInfo, ProfilingInfo, Status};
use ocl::{Platform, Device, Context, Queue, Buffer, Image, Sampler, Program,
    Kernel, Event, EventList, SpatialDims};

const WORK_SIZE: [usize; 3] = [1024, 64, 16];
const INFO_FORMAT_MULTILINE: bool = true;

static SRC: &'static str = r#"
    __kernel void multiply(float coeff, __global float* buffer) {
        buffer[get_global_id(0)] *= coeff;
    }
"#;

/// Convert the info or error to a string for printing:
macro_rules! to_string {
    ( $ expr : expr ) => {
        match $expr {
            Ok(info) => info.to_string(),
            Err(err) => {
                match err.api_status() {
                    Some(Status::CL_KERNEL_ARG_INFO_NOT_AVAILABLE) => "Not available".into(),
                    _ => err.to_string(),
                }
            },
        }
    };
}


fn print_platform_device(plat_idx: usize, platform: Platform, device_idx: usize,
        device: Device) -> ocl::Result<()> {
    let work_dims = SpatialDims::from(WORK_SIZE);

    let context = Context::builder().platform(platform).devices(device).build()?;
    let program = Program::builder()
        .devices(device)
        .src(SRC)
        .build(&context)?;
    let queue = Queue::new(&context, device, Some(core::QUEUE_PROFILING_ENABLE))?;
    let buffer = Buffer::<f32>::builder()
        .queue(queue.clone())
        .len(work_dims)
        .build()?;
    let image = Image::<u8>::builder()
        .dims(work_dims)
        .queue(queue.clone())
        .build()?;
    let sampler = Sampler::with_defaults(&context)?;
        let kernel = Kernel::builder()
        .name("multiply")
        .program(&program)
        .queue(queue.clone())
        .global_work_size(work_dims)
        .arg(10.0f32)
        .arg(&buffer)
        .build()?;

    let mut event_list = EventList::new();
    unsafe { kernel.cmd().enew(&mut event_list).enq()?; }
    event_list.wait_for()?;

    let mut event = Event::empty();
    buffer.cmd().write(&vec![0.0; work_dims.to_len()]).enew(&mut event).enq()?;
    event.wait_for()?;

    let device_version = device.version()?;

    println!("############### OpenCL Platform-Device Full Info ################");
    print!("\n");

    let (begin, delim, end) = if INFO_FORMAT_MULTILINE {
        ("\n", "\n", "\n")
    } else {
        ("{ ", ", ", " }")
    };

    // ##################################################
    // #################### PLATFORM ####################
    // ##################################################

    println!("Platform [{}]:{b}\
            Profile: {}{d}\
            Version: {}{d}\
            Name: {}{d}\
            Vendor: {}{d}\
            Extensions: {}{e}\
        ",
        plat_idx,
        to_string!(core::get_platform_info(platform, PlatformInfo::Profile)),
        to_string!(core::get_platform_info(platform, PlatformInfo::Version)),
        to_string!(core::get_platform_info(platform, PlatformInfo::Name)),
        to_string!(core::get_platform_info(platform, PlatformInfo::Vendor)),
        to_string!(core::get_platform_info(platform, PlatformInfo::Extensions)),
        b = begin, d = delim, e = end,
    );


    // ##################################################
    // #################### DEVICES #####################
    // ##################################################

    debug_assert!(context.devices().len() == 1);

    println!("Device [{}]: {b}\
            Type: {}{d}\
            VendorId: {}{d}\
            MaxComputeUnits: {}{d}\
            MaxWorkItemDimensions: {}{d}\
            MaxWorkGroupSize: {}{d}\
            MaxWorkItemSizes: {}{d}\
            PreferredVectorWidthChar: {}{d}\
            PreferredVectorWidthShort: {}{d}\
            PreferredVectorWidthInt: {}{d}\
            PreferredVectorWidthLong: {}{d}\
            PreferredVectorWidthFloat: {}{d}\
            PreferredVectorWidthDouble: {}{d}\
            MaxClockFrequency: {}{d}\
            AddressBits: {}{d}\
            MaxReadImageArgs: {}{d}\
            MaxWriteImageArgs: {}{d}\
            MaxMemAllocSize: {}{d}\
            Image2dMaxWidth: {}{d}\
            Image2dMaxHeight: {}{d}\
            Image3dMaxWidth: {}{d}\
            Image3dMaxHeight: {}{d}\
            Image3dMaxDepth: {}{d}\
            ImageSupport: {}{d}\
            MaxParameterSize: {}{d}\
            MaxSamplers: {}{d}\
            MemBaseAddrAlign: {}{d}\
            MinDataTypeAlignSize: {}{d}\
            SingleFpConfig: {}{d}\
            GlobalMemCacheType: {}{d}\
            GlobalMemCachelineSize: {}{d}\
            GlobalMemCacheSize: {}{d}\
            GlobalMemSize: {}{d}\
            MaxConstantBufferSize: {}{d}\
            MaxConstantArgs: {}{d}\
            LocalMemType: {}{d}\
            LocalMemSize: {}{d}\
            ErrorCorrectionSupport: {}{d}\
            ProfilingTimerResolution: {}{d}\
            EndianLittle: {}{d}\
            Available: {}{d}\
            CompilerAvailable: {}{d}\
            ExecutionCapabilities: {}{d}\
            QueueProperties: {}{d}\
            Name: {}{d}\
            Vendor: {}{d}\
            DriverVersion: {}{d}\
            Profile: {}{d}\
            Version: {}{d}\
            Extensions: {}{d}\
            Platform: {}{d}\
            DoubleFpConfig: {}{d}\
            HalfFpConfig: {}{d}\
            PreferredVectorWidthHalf: {}{d}\
            HostUnifiedMemory: {}{d}\
            NativeVectorWidthChar: {}{d}\
            NativeVectorWidthShort: {}{d}\
            NativeVectorWidthInt: {}{d}\
            NativeVectorWidthLong: {}{d}\
            NativeVectorWidthFloat: {}{d}\
            NativeVectorWidthDouble: {}{d}\
            NativeVectorWidthHalf: {}{d}\
            OpenclCVersion: {}{d}\
            LinkerAvailable: {}{d}\
            BuiltInKernels: {}{d}\
            ImageMaxBufferSize: {}{d}\
            ImageMaxArraySize: {}{d}\
            ParentDevice: {}{d}\
            PartitionMaxSubDevices: {}{d}\
            PartitionProperties: {}{d}\
            PartitionAffinityDomain: {}{d}\
            PartitionType: {}{d}\
            ReferenceCount: {}{d}\
            PreferredInteropUserSync: {}{d}\
            PrintfBufferSize: {}{d}\
            ImagePitchAlignment: {}{d}\
            ImageBaseAddressAlignment: {}{e}\
        ",
        device_idx,
        to_string!(core::get_device_info(&device, DeviceInfo::Type)),
        to_string!(core::get_device_info(&device, DeviceInfo::VendorId)),
        to_string!(core::get_device_info(&device, DeviceInfo::MaxComputeUnits)),
        to_string!(core::get_device_info(&device, DeviceInfo::MaxWorkItemDimensions)),
        to_string!(core::get_device_info(&device, DeviceInfo::MaxWorkGroupSize)),
        to_string!(core::get_device_info(&device, DeviceInfo::MaxWorkItemSizes)),
        to_string!(core::get_device_info(&device, DeviceInfo::PreferredVectorWidthChar)),
        to_string!(core::get_device_info(&device, DeviceInfo::PreferredVectorWidthShort)),
        to_string!(core::get_device_info(&device, DeviceInfo::PreferredVectorWidthInt)),
        to_string!(core::get_device_info(&device, DeviceInfo::PreferredVectorWidthLong)),
        to_string!(core::get_device_info(&device, DeviceInfo::PreferredVectorWidthFloat)),
        to_string!(core::get_device_info(&device, DeviceInfo::PreferredVectorWidthDouble)),
        to_string!(core::get_device_info(&device, DeviceInfo::MaxClockFrequency)),
        to_string!(core::get_device_info(&device, DeviceInfo::AddressBits)),
        to_string!(core::get_device_info(&device, DeviceInfo::MaxReadImageArgs)),
        to_string!(core::get_device_info(&device, DeviceInfo::MaxWriteImageArgs)),
        to_string!(core::get_device_info(&device, DeviceInfo::MaxMemAllocSize)),
        to_string!(core::get_device_info(&device, DeviceInfo::Image2dMaxWidth)),
        to_string!(core::get_device_info(&device, DeviceInfo::Image2dMaxHeight)),
        to_string!(core::get_device_info(&device, DeviceInfo::Image3dMaxWidth)),
        to_string!(core::get_device_info(&device, DeviceInfo::Image3dMaxHeight)),
        to_string!(core::get_device_info(&device, DeviceInfo::Image3dMaxDepth)),
        to_string!(core::get_device_info(&device, DeviceInfo::ImageSupport)),
        to_string!(core::get_device_info(&device, DeviceInfo::MaxParameterSize)),
        to_string!(core::get_device_info(&device, DeviceInfo::MaxSamplers)),
        to_string!(core::get_device_info(&device, DeviceInfo::MemBaseAddrAlign)),
        to_string!(core::get_device_info(&device, DeviceInfo::MinDataTypeAlignSize)),
        to_string!(core::get_device_info(&device, DeviceInfo::SingleFpConfig)),
        to_string!(core::get_device_info(&device, DeviceInfo::GlobalMemCacheType)),
        to_string!(core::get_device_info(&device, DeviceInfo::GlobalMemCachelineSize)),
        to_string!(core::get_device_info(&device, DeviceInfo::GlobalMemCacheSize)),
        to_string!(core::get_device_info(&device, DeviceInfo::GlobalMemSize)),
        to_string!(core::get_device_info(&device, DeviceInfo::MaxConstantBufferSize)),
        to_string!(core::get_device_info(&device, DeviceInfo::MaxConstantArgs)),
        to_string!(core::get_device_info(&device, DeviceInfo::LocalMemType)),
        to_string!(core::get_device_info(&device, DeviceInfo::LocalMemSize)),
        to_string!(core::get_device_info(&device, DeviceInfo::ErrorCorrectionSupport)),
        to_string!(core::get_device_info(&device, DeviceInfo::ProfilingTimerResolution)),
        to_string!(core::get_device_info(&device, DeviceInfo::EndianLittle)),
        to_string!(core::get_device_info(&device, DeviceInfo::Available)),
        to_string!(core::get_device_info(&device, DeviceInfo::CompilerAvailable)),
        to_string!(core::get_device_info(&device, DeviceInfo::ExecutionCapabilities)),
        to_string!(core::get_device_info(&device, DeviceInfo::QueueProperties)),
        to_string!(core::get_device_info(&device, DeviceInfo::Name)),
        to_string!(core::get_device_info(&device, DeviceInfo::Vendor)),
        to_string!(core::get_device_info(&device, DeviceInfo::DriverVersion)),
        to_string!(core::get_device_info(&device, DeviceInfo::Profile)),
        to_string!(core::get_device_info(&device, DeviceInfo::Version)),
        to_string!(core::get_device_info(&device, DeviceInfo::Extensions)),
        to_string!(core::get_device_info(&device, DeviceInfo::Platform)),
        to_string!(core::get_device_info(&device, DeviceInfo::DoubleFpConfig)),
        to_string!(core::get_device_info(&device, DeviceInfo::HalfFpConfig)),
        to_string!(core::get_device_info(&device, DeviceInfo::PreferredVectorWidthHalf)),
        to_string!(core::get_device_info(&device, DeviceInfo::HostUnifiedMemory)),
        to_string!(core::get_device_info(&device, DeviceInfo::NativeVectorWidthChar)),
        to_string!(core::get_device_info(&device, DeviceInfo::NativeVectorWidthShort)),
        to_string!(core::get_device_info(&device, DeviceInfo::NativeVectorWidthInt)),
        to_string!(core::get_device_info(&device, DeviceInfo::NativeVectorWidthLong)),
        to_string!(core::get_device_info(&device, DeviceInfo::NativeVectorWidthFloat)),
        to_string!(core::get_device_info(&device, DeviceInfo::NativeVectorWidthDouble)),
        to_string!(core::get_device_info(&device, DeviceInfo::NativeVectorWidthHalf)),
        to_string!(core::get_device_info(&device, DeviceInfo::OpenclCVersion)),
        to_string!(core::get_device_info(&device, DeviceInfo::LinkerAvailable)),
        to_string!(core::get_device_info(&device, DeviceInfo::BuiltInKernels)),
        to_string!(core::get_device_info(&device, DeviceInfo::ImageMaxBufferSize)),
        to_string!(core::get_device_info(&device, DeviceInfo::ImageMaxArraySize)),
        to_string!(core::get_device_info(&device, DeviceInfo::ParentDevice)),
        to_string!(core::get_device_info(&device, DeviceInfo::PartitionMaxSubDevices)),
        to_string!(core::get_device_info(&device, DeviceInfo::PartitionProperties)),
        to_string!(core::get_device_info(&device, DeviceInfo::PartitionAffinityDomain)),
        to_string!(core::get_device_info(&device, DeviceInfo::PartitionType)),
        to_string!(core::get_device_info(&device, DeviceInfo::ReferenceCount)),
        to_string!(core::get_device_info(&device, DeviceInfo::PreferredInteropUserSync)),
        to_string!(core::get_device_info(&device, DeviceInfo::PrintfBufferSize)),
        to_string!(core::get_device_info(&device, DeviceInfo::ImagePitchAlignment)),
        to_string!(core::get_device_info(&device, DeviceInfo::ImageBaseAddressAlignment)),
        b = begin, d = delim, e = end,
    );


    // ##################################################
    // #################### CONTEXT #####################
    // ##################################################

    println!("Context:{b}\
            Reference Count: {}{d}\
            Devices: {}{d}\
            Properties: {}{d}\
            Device Count: {}{e}\
        ",
        to_string!(core::get_context_info(&context, ContextInfo::ReferenceCount)),
        to_string!(core::get_context_info(&context, ContextInfo::Devices)),
        to_string!(core::get_context_info(&context, ContextInfo::Properties)),
        to_string!(core::get_context_info(&context, ContextInfo::NumDevices)),
        b = begin, d = delim, e = end,
    );


    // ##################################################
    // ##################### QUEUE ######################
    // ##################################################

    println!("Command Queue:{b}\
            Context: {}{d}\
            Device: {}{d}\
            ReferenceCount: {}{d}\
            Properties: {}{e}\
        ",
        to_string!(core::get_command_queue_info(&queue, CommandQueueInfo::Context)),
        to_string!(core::get_command_queue_info(&queue, CommandQueueInfo::Device)),
        to_string!(core::get_command_queue_info(&queue, CommandQueueInfo::ReferenceCount)),
        to_string!(core::get_command_queue_info(&queue, CommandQueueInfo::Properties)),
        b = begin, d = delim, e = end,
    );


    // ##################################################
    // ################### MEM OBJECT ###################
    // ##################################################

    println!("Buffer Memory:{b}\
            Type: {}{d}\
            Flags: {}{d}\
            Size: {}{d}\
            HostPtr: {}{d}\
            MapCount: {}{d}\
            ReferenceCount: {}{d}\
            Context: {}{d}\
            AssociatedMemobject: {}{d}\
            Offset: {}{e}\
        ",
        to_string!(core::get_mem_object_info(&buffer, MemInfo::Type)),
        to_string!(core::get_mem_object_info(&buffer, MemInfo::Flags)),
        to_string!(core::get_mem_object_info(&buffer, MemInfo::Size)),
        to_string!(core::get_mem_object_info(&buffer, MemInfo::HostPtr)),
        to_string!(core::get_mem_object_info(&buffer, MemInfo::MapCount)),
        to_string!(core::get_mem_object_info(&buffer, MemInfo::ReferenceCount)),
        to_string!(core::get_mem_object_info(&buffer, MemInfo::Context)),
        to_string!(core::get_mem_object_info(&buffer, MemInfo::AssociatedMemobject)),
        to_string!(core::get_mem_object_info(&buffer, MemInfo::Offset)),
        b = begin, d = delim, e = end,
    );


    // ##################################################
    // ##################### IMAGE ######################
    // ##################################################

    println!("Image: {b}\
            ElementSize: {}{d}\
            RowPitch: {}{d}\
            SlicePitch: {}{d}\
            Width: {}{d}\
            Height: {}{d}\
            Depth: {}{d}\
            ArraySize: {}{d}\
            Buffer: {}{d}\
            NumMipLevels: {}{d}\
            NumSamples: {}{e}\
        ",
        to_string!(core::get_image_info(&image, ImageInfo::ElementSize)),
        to_string!(core::get_image_info(&image, ImageInfo::RowPitch)),
        to_string!(core::get_image_info(&image, ImageInfo::SlicePitch)),
        to_string!(core::get_image_info(&image, ImageInfo::Width)),
        to_string!(core::get_image_info(&image, ImageInfo::Height)),
        to_string!(core::get_image_info(&image, ImageInfo::Depth)),
        to_string!(core::get_image_info(&image, ImageInfo::ArraySize)),
        to_string!(core::get_image_info(&image, ImageInfo::Buffer)),
        to_string!(core::get_image_info(&image, ImageInfo::NumMipLevels)),
        to_string!(core::get_image_info(&image, ImageInfo::NumSamples)),
        b = begin, d = delim, e = end,
    );

    println!("Image Memory:{b}\
            Type: {}{d}\
            Flags: {}{d}\
            Size: {}{d}\
            HostPtr: {}{d}\
            MapCount: {}{d}\
            ReferenceCount: {}{d}\
            Context: {}{d}\
            AssociatedMemobject: {}{d}\
            Offset: {}{e}\
        ",
        to_string!(core::get_mem_object_info(&buffer, MemInfo::Type)),
        to_string!(core::get_mem_object_info(&buffer, MemInfo::Flags)),
        to_string!(core::get_mem_object_info(&buffer, MemInfo::Size)),
        to_string!(core::get_mem_object_info(&buffer, MemInfo::HostPtr)),
        to_string!(core::get_mem_object_info(&buffer, MemInfo::MapCount)),
        to_string!(core::get_mem_object_info(&buffer, MemInfo::ReferenceCount)),
        to_string!(core::get_mem_object_info(&buffer, MemInfo::Context)),
        to_string!(core::get_mem_object_info(&buffer, MemInfo::AssociatedMemobject)),
        to_string!(core::get_mem_object_info(&buffer, MemInfo::Offset)),
        b = begin, d = delim, e = end,
    );

    // ##################################################
    // #################### SAMPLER #####################
    // ##################################################


    println!("Sampler:{b}\
            ReferenceCount: {}{d}\
            Context: {}{d}\
            NormalizedCoords: {}{d}\
            AddressingMode: {}{d}\
            FilterMode: {}{e}\
        ",
        to_string!(core::get_sampler_info(&sampler, SamplerInfo::ReferenceCount)),
        to_string!(core::get_sampler_info(&sampler, SamplerInfo::Context)),
        to_string!(core::get_sampler_info(&sampler, SamplerInfo::NormalizedCoords)),
        to_string!(core::get_sampler_info(&sampler, SamplerInfo::AddressingMode)),
        to_string!(core::get_sampler_info(&sampler, SamplerInfo::FilterMode)),
        b = begin, d = delim, e = end,
    );

    // ##################################################
    // #################### PROGRAM #####################
    // ##################################################

    println!("Program:{b}\
            ReferenceCount: {}{d}\
            Context: {}{d}\
            NumDevices: {}{d}\
            Devices: {}{d}\
            Source: {}{d}\
            BinarySizes: {}{d}\
            Binaries: {}{d}\
            NumKernels: {}{d}\
            KernelNames: {}{e}\
        ",
        to_string!(core::get_program_info(&program, ProgramInfo::ReferenceCount)),
        to_string!(core::get_program_info(&program, ProgramInfo::Context)),
        to_string!(core::get_program_info(&program, ProgramInfo::NumDevices)),
        to_string!(core::get_program_info(&program, ProgramInfo::Devices)),
        to_string!(core::get_program_info(&program, ProgramInfo::Source)),
        to_string!(core::get_program_info(&program, ProgramInfo::BinarySizes)
            .map(|_| "{Omitted}")),
        to_string!(core::get_program_info(&program, ProgramInfo::NumKernels)),
        to_string!(core::get_program_info(&program, ProgramInfo::KernelNames)),
        b = begin, d = delim, e = end,
    );


    // ##################################################
    // ################# PROGRAM BUILD ##################
    // ##################################################

    println!("Program Build:{b}\
            BuildStatus: {}{d}\
            BuildOptions: {}{d}\
            BuildLog: \n\n{}{d}\n\
            BinaryType: {}{e}\
        ",
        to_string!(core::get_program_build_info(&program, &device, ProgramBuildInfo::BuildStatus)),
        to_string!(core::get_program_build_info(&program, &device, ProgramBuildInfo::BuildOptions)),
        to_string!(core::get_program_build_info(&program, &device, ProgramBuildInfo::BuildLog)),
        to_string!(core::get_program_build_info(&program, &device, ProgramBuildInfo::BinaryType)),
        b = begin, d = delim, e = end,
    );


    // ##################################################
    // ##################### KERNEL #####################
    // ##################################################

    println!("Kernel Info:{b}\
            FunctionName: {}{d}\
            NumArgs: {}{d}\
            ReferenceCount: {}{d}\
            Context: {}{d}\
            Program: {}{d}\
            Attributes: {}{e}\
        ",
        to_string!(core::get_kernel_info(&kernel, KernelInfo::FunctionName)),
        to_string!(core::get_kernel_info(&kernel, KernelInfo::NumArgs)),
        to_string!(core::get_kernel_info(&kernel, KernelInfo::ReferenceCount)),
        to_string!(core::get_kernel_info(&kernel, KernelInfo::Context)),
        to_string!(core::get_kernel_info(&kernel, KernelInfo::Program)),
        to_string!(core::get_kernel_info(&kernel, KernelInfo::Attributes)),
        b = begin, d = delim, e = end,
    );


    // ##################################################
    // ################# KERNEL ARGUMENT ################
    // ##################################################

    println!("Kernel Argument [0]:{b}\
            AddressQualifier: {}{d}\
            AccessQualifier: {}{d}\
            TypeName: {}{d}\
            TypeQualifier: {}{d}\
            Name: {}{e}\
        ",
        to_string!(core::get_kernel_arg_info(&kernel, 0, KernelArgInfo::AddressQualifier, Some(&[device_version]))),
        to_string!(core::get_kernel_arg_info(&kernel, 0, KernelArgInfo::AccessQualifier, Some(&[device_version]))),
        to_string!(core::get_kernel_arg_info(&kernel, 0, KernelArgInfo::TypeName, Some(&[device_version]))),
        to_string!(core::get_kernel_arg_info(&kernel, 0, KernelArgInfo::TypeQualifier, Some(&[device_version]))),
        to_string!(core::get_kernel_arg_info(&kernel, 0, KernelArgInfo::Name, Some(&[device_version]))),
        b = begin, d = delim, e = end,
    );

    // ##################################################
    // ################ KERNEL WORK GROUP ###############
    // ##################################################

    println!("Kernel Work Group:{b}\
            WorkGroupSize: {}{d}\
            CompileWorkGroupSize: {}{d}\
            LocalMemSize: {}{d}\
            PreferredWorkGroupSizeMultiple: {}{d}\
            PrivateMemSize: {}{d}\
            GlobalWorkSize: {}{e}\
        ",
        to_string!(core::get_kernel_work_group_info(&kernel, &device, KernelWorkGroupInfo::WorkGroupSize)),
        to_string!(core::get_kernel_work_group_info(&kernel, &device, KernelWorkGroupInfo::CompileWorkGroupSize)),
        to_string!(core::get_kernel_work_group_info(&kernel, &device, KernelWorkGroupInfo::LocalMemSize)),
        to_string!(core::get_kernel_work_group_info(&kernel, &device, KernelWorkGroupInfo::PreferredWorkGroupSizeMultiple)),
        to_string!(core::get_kernel_work_group_info(&kernel, &device, KernelWorkGroupInfo::PrivateMemSize)),
        to_string!(core::get_kernel_work_group_info(&kernel, &device, KernelWorkGroupInfo::GlobalWorkSize)),
        b = begin, d = delim, e = end,
    );


    // ##################################################
    // ##################### EVENT ######################
    // ##################################################

    println!("Event:{b}\
            CommandQueue: {}{d}\
            CommandType: {}{d}\
            ReferenceCount: {}{d}\
            CommandExecutionStatus: {}{d}\
            Context: {}{e}\
        ",
        to_string!(core::get_event_info(&event, EventInfo::CommandQueue)),
        to_string!(core::get_event_info(&event, EventInfo::CommandType)),
        to_string!(core::get_event_info(&event, EventInfo::ReferenceCount)),
        to_string!(core::get_event_info(&event, EventInfo::CommandExecutionStatus)),
        to_string!(core::get_event_info(&event, EventInfo::Context)),
        b = begin, d = delim, e = end,
    );


    // ##################################################
    // ################ EVENT PROFILING #################
    // ##################################################

    println!("Event Profiling:{b}\
            Queued: {}{d}\
            Submit: {}{d}\
            Start: {}{d}\
            End: {}{e}\
        ",
        to_string!(core::get_event_profiling_info(&event, ProfilingInfo::Queued)),
        to_string!(core::get_event_profiling_info(&event, ProfilingInfo::Submit)),
        to_string!(core::get_event_profiling_info(&event, ProfilingInfo::Start)),
        to_string!(core::get_event_profiling_info(&event, ProfilingInfo::End)),
        b = begin, d = delim, e = end,
    );


    // ##################################################
    // ###################### END #######################
    // ##################################################

    print!("\n");
    Ok(())
}

fn print_platform(plat_idx: usize, platform: Platform) -> ocl::Result<()> {
    for (device_idx, &device) in Device::list_all(&platform)?.iter().enumerate() {
        print_platform_device(plat_idx, platform, device_idx, device)?;
    }
    Ok(())
}

fn info_core() -> ocl::Result<()> {
    let platforms = Platform::list();
    for (plat_idx, &platform) in platforms.iter().enumerate() {
        print_platform(plat_idx, platform)?;
    }
    Ok(())
}

pub fn main() {
    match info_core() {
        Ok(_) => (),
        Err(err) => println!("{}", err),
    }
}