Skip to content

OpenCL Device.addressBits uses CL_DEVICE_TYPE (0x1000) instead of CL_DEVICE_ADDRESS_BITS (0x100D) #102

Description

@niy-ati

Summary

In the OpenCL device info wrapper, Device.Info.addressBits is annotated with the wrong cl_device_info value, so device.addressBits does not query address width.

Location

source/dcompute/driver/ocl/device.d (current master):

@(0x100C) uint maxClockFrequency;
@(0x1000) uint addressBits;   // <-- wrong
@(0x100E) uint maxReadImageArgs;

type already correctly uses @(0x1000) a few lines above:

@(0x1000) Type type;

So addressBits reuses CL_DEVICE_TYPE and skips the constant that belongs between 0x100C and 0x100E.

Reference

From the OpenCL C headers (Khronos OpenCL-Headers CL/cl.h):

Constant Value Meaning
CL_DEVICE_TYPE 0x1000 device type bitfield
CL_DEVICE_MAX_CLOCK_FREQUENCY 0x100C clock frequency
CL_DEVICE_ADDRESS_BITS 0x100D address bits (cl_uint)
CL_DEVICE_MAX_READ_IMAGE_ARGS 0x100E max read image args

addressBits should use 0x100D, not 0x1000.

The generated getter (via generateGetInfo / clGetDeviceInfo) passes that UDA value as param_name, so the wrong query is what runs at runtime.

How this was found

While reviewing Device.Info UDA values against cl.h (after looking at the related size fix in #84 , #85, which corrected enum base types but did not change this attribute), the sequence 0x100C -> 0x1000 -> 0x100E stood out: 0x100D is missing and 0x1000 is already used for type.

Expected

device.addressBits should call clGetDeviceInfo(..., CL_DEVICE_ADDRESS_BITS, ...) and return the device address width (commonly 32 or 64).

Actual

device.addressBits calls clGetDeviceInfo(..., CL_DEVICE_TYPE, ...) with a uint-sized buffer. That is not the address-bits query; the returned value is not meaningful as address width.

How to reproduce

On any machine with a working OpenCL ICD and dcompute’s OCL driver:

import std.stdio;
import std.experimental.allocator;
import dcompute.driver.ocl;

void main()
{
    Platform.initialise();
    auto platforms = Platform.getPlatforms(theAllocator);
    auto devices = platforms[0].getDevices(theAllocator);
    auto d = devices[0];

    writefln("name: %s", d.name);
    writefln("type: %s (%s)", d.type, cast(ulong)d.type);
    writefln("addressBits: %s", d.addressBits);
}

Compare addressBits with a direct query (or clinfo):

cl_uint bits;
clGetDeviceInfo(device, CL_DEVICE_ADDRESS_BITS, sizeof(bits), &bits, NULL);

You should see a mismatch: dcompute’s addressBits does not match CL_DEVICE_ADDRESS_BITS from clinfo / the direct call. (Exact wrong numeric value depends on the device and how the truncated CL_DEVICE_TYPE read lands in a uint.)

Proposed fix

Change the attribute only:

@(0x100D) uint addressBits;

Note on related work

#84 / #85 fixed OpenCL enum base type sizes so fields like type are read with the correct sizeof. That is separate from this bug, which is a wrong param_name constant on addressBits.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions