Skip to content

Enable AWS S3 remote data source for Presto GPU benchmarks - #376

Open
kingcrimsontianyu wants to merge 11 commits into
rapidsai:mainfrom
kingcrimsontianyu:enable-s3
Open

Enable AWS S3 remote data source for Presto GPU benchmarks#376
kingcrimsontianyu wants to merge 11 commits into
rapidsai:mainfrom
kingcrimsontianyu:enable-s3

Conversation

@kingcrimsontianyu

@kingcrimsontianyu kingcrimsontianyu commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

This PR lets Presto GPU TPC-H/TPC-DS benchmarks and integration tests run against data in a remote object store (AWS S3) with no local copy of the dataset. Only the Hive metastore stays local.

The key changes include:

  • Register tables for remote data: A new presto/scripts/register_external_tables.sh registers Hive tables at a URI base without generating or copying data. create_hive_tables.py gains --external-location-base. When set, each table's EXTERNAL_LOCATION is <base>/<table>. Otherwise it falls back to the local file: path.
  • Update schema templates: The 8 TPC-H + 24 TPC-DS .sql files now use EXTERNAL_LOCATION = '{location}' instead of the hardcoded 'file:{file_path}'.
  • Add AWS credentials and region to docker files: The docker-compose.common.yml file passes AWS_ACCESS_KEY_ID/SECRET_ACCESS_KEY/SESSION_TOKEN and AWS_DEFAULT_REGION/AWS_REGION to the coordinator and native worker.
  • Enable DuckDB S3: The new duckdb_utils.ensure_remote_access function configures httpfs and S3 credential_chain secret. read_scale_factor derives the scale factor from metadata.json (local via stdlib json, and S3 via DuckDB). This allows the integration tests to continue working for remote data source.
  • Update the documentation.

@kingcrimsontianyu kingcrimsontianyu added improvement Improves an existing functionality non-breaking Introduces a non-breaking change labels Jul 16, 2026
@copy-pr-bot

copy-pr-bot Bot commented Jul 16, 2026

Copy link
Copy Markdown

Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually.

Contributors can view more details about this message here.

@kingcrimsontianyu
kingcrimsontianyu marked this pull request as ready for review July 17, 2026 18:33
@kingcrimsontianyu
kingcrimsontianyu requested a review from a team as a code owner July 17, 2026 18:33
@kingcrimsontianyu
kingcrimsontianyu requested a review from shrshi July 17, 2026 18:33

@simoneves simoneves left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM but will test properly

@kingcrimsontianyu

Copy link
Copy Markdown
Contributor Author

Sure! This has been tested on my laptop with S3 TPC-H/TPC-DS SF-1. The planned next step is to test on an EC2 instance with S3 SF-1K.
Another thing is that I've only checked the cuDF/KvikIO data source path, and I'll need to test Velox's buffered input path (which uses AWS SDK for S3 access).

# When external_location_base is set (e.g. s3://bucket/prefix/sf100), point the
# table at that base. Otherwise fall back to the local bind-mounted file path.
if external_location_base:
location = f"{external_location_base}/{table_name}"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do the trailing backslashes need to be stripped here similar to what you have in L38 in generate_table_schemas.py?

@paul-aiyedun paul-aiyedun left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes overall look good to me. However, I had comments about extending existing logic and using more specific options names.


# AWS S3.
hive.s3.ssl.enabled=true
hive.s3.path-style-access=false

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was hive.s3.use-instance-credentials=false intentionally not added here?

def create_duckdb_table(table_name, data_path):
create_table(table_name, get_abs_file_path(__file__, data_path))
# Only resolve local path
if "://" not in data_path:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding a direct flag parameter e.g. is_s3_location here instead of the :// check.

"table). Mutually exclusive with --external-location-base.",
)
parser.add_argument(
"--external-location-base",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider a more specific option name like s3-data-dir-path.

Same comment applies to other files with a similar flag.

nargs="+",
default=None,
help="Table names to generate schemas for. Required with --external-location-base since a "
"remote prefix cannot be listed.",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe S3 supports listing objects with a specified prefix?


Usage: $0 [OPTIONS]

Registers benchmark external tables in a Presto Hive schema whose data lives at an

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this script is effectively doing the same thing as setup_benchmark_tables.sh. Can we extend setup_benchmark_tables.sh with S3 options (e.g. --s3/--data-location {file|s3}, --s3-data-dir-path, etc.) instead of adding a new script?

external_dir = ""
# Capture everything between two single quotes
location_match = re.search(r"external_location = '([^']*)'", create_table_text[0])
location = location_match.group(1) if location_match else ""

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we assert that location_match and location exist?

Comment on lines +36 to +51
def _extract_scale_factor(metadata: dict):
"""Return the scale factor from parsed metadata, whether it is a top-level field or
nested under 'options'."""
return metadata.get("scale_factor") or metadata.get("options", {}).get("scale_factor")


def read_scale_factor(metadata_uri: str):
"""Read the scale_factor field from a metadata.json at ``metadata_uri``."""
# For local data
if not str(metadata_uri).startswith("s3://"):
with open(metadata_uri) as file:
return _extract_scale_factor(json.load(file))
# For remote data
ensure_remote_access(metadata_uri)
raw = duckdb.sql(f"SELECT content FROM read_text('{metadata_uri}')").fetchone()[0]
return _extract_scale_factor(json.loads(raw))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think scale factor access/reading is DuckDB specific logic?

_s3_configured = False


def ensure_remote_access(path) -> None:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider something like configure_data_access, since this also applies to local files.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

improvement Improves an existing functionality non-breaking Introduces a non-breaking change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants