Skip to content

Commit b3b15e1

Browse files
committed
feat(config): add Bool type support for target arguments
Adds `Bool` to the `ArgumentType` enum for target configuration, enabling boolean flags that can be specified without a value. ## Changes ### Core Type Support - Add `Bool` to `ArgumentType` enum in TargetConfig.h - Add YAML mapping "bool" -> ArgumentType::Bool in TargetConfig.cpp ### Typed Value Utilities - Add `getTypedConfigValue()` to ServerHelper for proper JSON serialization - Add `getArgumentType()` to look up declared types from target config - Bool values serialize as JSON boolean literals (not strings) ### nvq++ Compiler Support - Add `--list-bool-args` mode to cudaq-target-conf tool - Modify nvq++ to detect Bool arguments and handle shift 1 vs shift 2 - Bool args can be specified without value (defaults to true) ### Backend Updates - Update IonQ backend: change `debias` and `sharpen` to `type: bool` - Simplify backend code using new typed value utilities ### Tests - Add unit test for Bool argument YAML parsing - Add integration test for --list-bool-args output - Add test YAML config with Bool/String/Int arguments ## Usage Target YAML: ```yaml target-arguments: - key: debias type: bool platform-arg: debias ``` Command line: ```bash nvq++ --target ionq --ionq-debias program.cpp # defaults to true nvq++ --target ionq --ionq-debias true program.cpp # explicit true nvq++ --target ionq --ionq-debias=false program.cpp # explicit false ``` Fixes #3699 Fixes #3525 Signed-off-by: andrewtkent <andrew_kent@brown.edu>
1 parent 48cf3d9 commit b3b15e1

File tree

12 files changed

+302
-21
lines changed

12 files changed

+302
-21
lines changed

include/cudaq/Support/TargetConfig.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ enum TargetFeatureFlag : unsigned {
2929

3030
/// @brief Configuration argument type annotation
3131
// e.g., to support type validation.
32-
enum class ArgumentType { String, Int, UUID, FeatureFlag, MachineConfig };
32+
enum class ArgumentType { String, Int, Bool, UUID, FeatureFlag, MachineConfig };
3333

3434
/// @brief Architecture-specific compilation settings
3535
// Different device architectures of a target may require customization.

lib/Support/Config/TargetConfig.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@ void ScalarEnumerationTraits<cudaq::config::ArgumentType>::enumeration(
267267
IO &io, cudaq::config::ArgumentType &value) {
268268
io.enumCase(value, "string", cudaq::config::ArgumentType::String);
269269
io.enumCase(value, "integer", cudaq::config::ArgumentType::Int);
270+
io.enumCase(value, "bool", cudaq::config::ArgumentType::Bool);
270271
io.enumCase(value, "uuid", cudaq::config::ArgumentType::UUID);
271272
io.enumCase(value, "option-flags", cudaq::config::ArgumentType::FeatureFlag);
272273
io.enumCase(value, "machine-config",

runtime/common/ServerHelper.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,53 @@ void ServerHelper::parseConfigForCommonParams(const BackendConfig &config) {
3838
}
3939
}
4040
}
41+
42+
std::optional<config::ArgumentType>
43+
ServerHelper::getArgumentType(const std::string &key) const {
44+
for (const auto &arg : runtimeTarget.config.TargetArguments)
45+
// Check both the key name and platform-arg key
46+
if (arg.KeyName == key || arg.PlatformArgKey == key)
47+
return arg.Type;
48+
return std::nullopt;
49+
}
50+
51+
nlohmann::json ServerHelper::getTypedConfigValue(const std::string &key) const {
52+
auto it = backendConfig.find(key);
53+
if (it == backendConfig.end())
54+
return nlohmann::json(); // null
55+
56+
const std::string &value = it->second;
57+
auto argType = getArgumentType(key);
58+
59+
// If no type info available, return as string
60+
if (!argType.has_value())
61+
return value;
62+
63+
switch (argType.value()) {
64+
case config::ArgumentType::Bool:
65+
// Handle common boolean string representations
66+
if (value == "true" || value == "True" || value == "TRUE" || value == "1")
67+
return true;
68+
if (value == "false" || value == "False" || value == "FALSE" || value == "0")
69+
return false;
70+
throw std::runtime_error("Invalid boolean value for '" + key + "': '" +
71+
value + "'. Expected true/false/1/0.");
72+
case config::ArgumentType::Int: {
73+
try {
74+
return std::stoll(value);
75+
} catch (...) {
76+
// If parsing fails, return as string
77+
return value;
78+
}
79+
}
80+
case config::ArgumentType::String:
81+
case config::ArgumentType::UUID:
82+
case config::ArgumentType::FeatureFlag:
83+
case config::ArgumentType::MachineConfig:
84+
default:
85+
return value;
86+
}
87+
}
4188
} // namespace cudaq
4289

4390
LLVM_INSTANTIATE_REGISTRY(cudaq::ServerHelper::RegistryType)

runtime/common/ServerHelper.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "common/RecordLogParser.h"
1717
#include "nlohmann/json.hpp"
1818
#include <filesystem>
19+
#include <optional>
1920

2021
namespace cudaq {
2122

@@ -91,6 +92,20 @@ class ServerHelper : public registry::RegisteredType<ServerHelper> {
9192
/// @brief Information about the runtime target managing this server helper.
9293
RuntimeTarget runtimeTarget;
9394

95+
/// @brief Get the ArgumentType for a config key from target configuration.
96+
/// @param key The config key to look up
97+
/// @return The ArgumentType if found, std::nullopt otherwise
98+
std::optional<config::ArgumentType> getArgumentType(const std::string &key) const;
99+
100+
/// @brief Get a config value converted to the appropriate JSON type based on
101+
/// the ArgumentType declared in the target configuration.
102+
/// - Bool: converts "true"/"false" strings to JSON boolean
103+
/// - Int: converts numeric strings to JSON number
104+
/// - String/UUID/others: keeps as JSON string
105+
/// @param key The config key to retrieve
106+
/// @return JSON value with appropriate type, or null if key not found
107+
nlohmann::json getTypedConfigValue(const std::string &key) const;
108+
94109
public:
95110
ServerHelper() = default;
96111
virtual ~ServerHelper() = default;

runtime/cudaq/platform/default/rest/helpers/ionq/IonQServerHelper.cpp

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -205,14 +205,10 @@ IonQServerHelper::createJob(std::vector<KernelExecution> &circuitCodes) {
205205
job["input"]["data"] = circuitCode.code;
206206
// Include error mitigation configuration if set in backendConfig
207207
if (keyExists("debias")) {
208-
try {
209-
bool debiasValue =
210-
nlohmann::json::parse(backendConfig["debias"]).get<bool>();
211-
job["error_mitigation"]["debias"] = debiasValue;
212-
} catch (const nlohmann::json::exception &e) {
213-
throw std::runtime_error(
214-
"Invalid value for 'debias'. It should be a boolean (true/false).");
215-
}
208+
job["error_mitigation"]["debias"] = getTypedConfigValue("debias");
209+
}
210+
if (keyExists("sharpen")) {
211+
job["error_mitigation"]["sharpen"] = getTypedConfigValue("sharpen");
216212
}
217213

218214
jobs.push_back(job);

runtime/cudaq/platform/default/rest/helpers/ionq/ionq.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,11 @@ target-arguments:
4040
help-string: "Specify the noise model for simulation."
4141
- key: debias
4242
required: false
43-
type: string
44-
platform-arg: debias
45-
help-string: "Specify debiasing."
43+
type: bool
44+
platform-arg: debias
45+
help-string: "Enable debiasing error mitigation."
4646
- key: sharpen
4747
required: false
48-
type: string
48+
type: bool
4949
platform-arg: sharpen
50-
help-string: "Specify sharpening."
50+
help-string: "Enable sharpening error mitigation."
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# ============================================================================ #
2+
# Copyright (c) 2022 - 2026 NVIDIA Corporation & Affiliates. #
3+
# All rights reserved. #
4+
# #
5+
# This source code and the accompanying materials are made available under #
6+
# the terms of the Apache License 2.0 which accompanies this distribution. #
7+
# ============================================================================ #
8+
9+
# Test target configuration with Bool arguments for testing --list-bool-args
10+
11+
name: test-bool-args
12+
description: "Test target for Bool argument type validation."
13+
config:
14+
platform-qpu: remote_rest
15+
codegen-emission: qir-base
16+
library-mode: false
17+
18+
target-arguments:
19+
- key: enable-opt
20+
required: false
21+
type: bool
22+
platform-arg: enable_opt
23+
help-string: "Enable optimization (Bool flag, no value needed)."
24+
- key: debug
25+
required: false
26+
type: bool
27+
help-string: "Enable debug mode (Bool flag)."
28+
- key: verbose
29+
required: false
30+
type: bool
31+
platform-arg: verbose
32+
help-string: "Enable verbose output (Bool flag)."
33+
- key: machine
34+
required: false
35+
type: string
36+
platform-arg: qpu
37+
help-string: "Specify QPU (string argument, should NOT appear in bool list)."
38+
- key: shots
39+
required: false
40+
type: integer
41+
platform-arg: shots
42+
help-string: "Number of shots (integer argument, should NOT appear in bool list)."
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# ============================================================================ #
2+
# Copyright (c) 2022 - 2026 NVIDIA Corporation & Affiliates. #
3+
# All rights reserved. #
4+
# #
5+
# This source code and the accompanying materials are made available under #
6+
# the terms of the Apache License 2.0 which accompanies this distribution. #
7+
# ============================================================================ #
8+
9+
# Validate that cudaq-target-conf --list-bool-args correctly identifies Bool arguments
10+
# and excludes non-Bool arguments (string, integer, etc.)
11+
12+
# RUN: cudaq-target-conf --list-bool-args %cudaq_src_dir/targettests/TargetConfig/Inputs/test-bool-args.yml | FileCheck %s
13+
14+
# Bool arguments should be listed
15+
# CHECK-DAG: enable-opt
16+
# CHECK-DAG: debug
17+
# CHECK-DAG: verbose
18+
19+
# Non-Bool arguments should NOT be listed
20+
# CHECK-NOT: machine
21+
# CHECK-NOT: shots

test/NVQPP/bool_target_args.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2022 - 2026 NVIDIA Corporation & Affiliates. *
3+
* All rights reserved. *
4+
* *
5+
* This source code and the accompanying materials are made available under *
6+
* the terms of the Apache License 2.0 which accompanies this distribution. *
7+
******************************************************************************/
8+
9+
// Test that Bool-type target arguments are correctly passed to the backend
10+
// configuration. Bool args can be specified without a value (implicit true).
11+
12+
// Test 1: Implicit true (--ionq-debias without value means true)
13+
// RUN: nvq++ -v --target ionq --ionq-debias %s -o %t |& FileCheck --check-prefix=IMPLICIT %s
14+
15+
// Test 2: Explicit true
16+
// RUN: nvq++ -v --target ionq --ionq-debias true %s -o %t |& FileCheck --check-prefix=EXPLICIT %s
17+
18+
// Test 3: Explicit false using = syntax
19+
// RUN: nvq++ -v --target ionq --ionq-debias=false %s -o %t |& FileCheck --check-prefix=FALSE %s
20+
21+
// IMPLICIT: -DNVQPP_TARGET_BACKEND_CONFIG
22+
// IMPLICIT-SAME: debias;true
23+
24+
// EXPLICIT: -DNVQPP_TARGET_BACKEND_CONFIG
25+
// EXPLICIT-SAME: debias;true
26+
27+
// FALSE: -DNVQPP_TARGET_BACKEND_CONFIG
28+
// FALSE-SAME: debias;false
29+
30+
#include <cudaq.h>
31+
32+
struct test_kernel {
33+
void operator()() __qpu__ {
34+
cudaq::qubit q;
35+
h(q);
36+
}
37+
};
38+
39+
int main() {
40+
return 0;
41+
}

tools/cudaq-target-conf/cudaq-target-conf.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ static cl::opt<bool> skipGpuCheck(
5151
cl::desc("Skip NVIDIA check on target configuration that requires GPUs."),
5252
cl::init(false));
5353

54+
static cl::opt<bool> listBoolArgs(
55+
"list-bool-args",
56+
cl::desc("List argument keys that are Bool type (no value required)."),
57+
cl::init(false));
58+
5459
static constexpr const char BOLD[] = "\033[1m";
5560
static constexpr const char RED[] = "\033[91m";
5661
static constexpr const char CLEAR[] = "\033[0m";
@@ -108,6 +113,15 @@ int main(int argc, char **argv) {
108113
llvm::yaml::Input Input(*(fileOrErr.get()));
109114
Input >> config;
110115

116+
// If --list-bool-args is specified, just output Bool argument keys and exit
117+
if (listBoolArgs) {
118+
for (const auto &arg : config.TargetArguments) {
119+
if (arg.Type == cudaq::config::ArgumentType::Bool)
120+
llvm::outs() << arg.KeyName << "\n";
121+
}
122+
return 0;
123+
}
124+
111125
// Verify GPU requirement
112126
if (!skipGpuCheck && config.GpuRequired && countGPUs() <= 0) {
113127
llvm::errs() << "Target '" << config.Name

0 commit comments

Comments
 (0)