From 1dc09f201603a3f169c845624d6fd912115f98dc Mon Sep 17 00:00:00 2001 From: Sameer Raheja Date: Thu, 16 Jul 2020 08:18:37 -0700 Subject: [PATCH] Karthik changes (#359) * Changes from Karthik * fixing _config.yml, adding get-started * fixing _config.yml (removing whitespace) * Some additional fixes * remove localhost reference * updates to index, getting started gcp, perf image, stable release * remove unused notebook, add description and reference for each cell of the notebook, reference to mortgage data and spark rapids config * updated examples with mortgage dataset info, databricks guide with executor info and cluster config based on comments * add reference to rapids plugin, cudf and spark xgboost inn readme Co-authored-by: Karthikeyan Co-authored-by: DougM --- .../Databricks/generate-init-script.ipynb | 1 + docs/demo/GCP/Mortgage-ETL-CPU.ipynb | 1174 +++++++++++++++ docs/demo/GCP/Mortgage-ETL-GPU.ipynb | 1292 +++++++++++++++++ .../GCP/mortgage-xgboost4j-gpu-scala.ipynb | 173 +++ .../GCP/mortgage-xgboost4j-gpu-scala.zpln | 1025 +++++++++++++ docs/demo/gpu-mortgage_accelerated.ipynb | 1 + docs/examples.md | 15 + docs/get-started/getting-started-gcp.md | 115 ++ docs/get-started/getting-started-menu.md | 57 + ...d-with-rapids-accelerator-on-databricks.md | 80 + docs/{ => get-started}/getting-started.md | 104 +- docs/get-started/yarn-gpu.md | 120 ++ docs/img/dataproc-cluster.png | Bin 0 -> 47130 bytes docs/img/dataproc-service.png | Bin 0 -> 75408 bytes docs/img/ease-of-use.png | Bin 0 -> 117376 bytes docs/img/initscript.png | Bin 0 -> 12946 bytes docs/img/perf-cost.png | Bin 0 -> 141480 bytes docs/img/spark3cluster.png | Bin 0 -> 46767 bytes docs/img/sparkconfig.png | Bin 0 -> 29809 bytes docs/index.md | 22 + docs/version/stable-release.md | 36 + docs/version/version.md | 7 + 22 files changed, 4143 insertions(+), 79 deletions(-) create mode 100644 docs/demo/Databricks/generate-init-script.ipynb create mode 100644 docs/demo/GCP/Mortgage-ETL-CPU.ipynb create mode 100644 docs/demo/GCP/Mortgage-ETL-GPU.ipynb create mode 100644 docs/demo/GCP/mortgage-xgboost4j-gpu-scala.ipynb create mode 100644 docs/demo/GCP/mortgage-xgboost4j-gpu-scala.zpln create mode 100644 docs/demo/gpu-mortgage_accelerated.ipynb create mode 100644 docs/examples.md create mode 100644 docs/get-started/getting-started-gcp.md create mode 100644 docs/get-started/getting-started-menu.md create mode 100644 docs/get-started/getting-started-with-rapids-accelerator-on-databricks.md rename docs/{ => get-started}/getting-started.md (83%) create mode 100644 docs/get-started/yarn-gpu.md create mode 100644 docs/img/dataproc-cluster.png create mode 100644 docs/img/dataproc-service.png create mode 100644 docs/img/ease-of-use.png create mode 100644 docs/img/initscript.png create mode 100644 docs/img/perf-cost.png create mode 100644 docs/img/spark3cluster.png create mode 100644 docs/img/sparkconfig.png create mode 100644 docs/version/stable-release.md create mode 100644 docs/version/version.md diff --git a/docs/demo/Databricks/generate-init-script.ipynb b/docs/demo/Databricks/generate-init-script.ipynb new file mode 100644 index 00000000000..bad856791ce --- /dev/null +++ b/docs/demo/Databricks/generate-init-script.ipynb @@ -0,0 +1 @@ +{"cells":[{"cell_type":"code","source":["dbutils.fs.mkdirs(\"dbfs:/databricks/init_scripts/\")\n \ndbutils.fs.put(\"/databricks/init_scripts/init.sh\",\"\"\"\n#!/bin/bash\nsudo wget -O /databricks/jars/rapids-4-spark_2.12-0.1.0-databricks.jar https://repo1.maven.org/maven2/com/nvidia/rapids-4-spark_2.12/0.1.0-databricks/rapids-4-spark_2.12-0.1.0-databricks.jar\nsudo wget -O /databricks/jars/cudf-0.14-cuda10-1.jar https://repo1.maven.org/maven2/ai/rapids/cudf/0.14/cudf-0.14-cuda10-1.jar\"\"\", True)"],"metadata":{},"outputs":[],"execution_count":1},{"cell_type":"code","source":["%sh\ncd ../../dbfs/databricks/init_scripts\npwd\nls -ltr\ncat init.sh"],"metadata":{},"outputs":[],"execution_count":2},{"cell_type":"code","source":[""],"metadata":{},"outputs":[],"execution_count":3}],"metadata":{"name":"generate-init-script","notebookId":2645746662301564},"nbformat":4,"nbformat_minor":0} diff --git a/docs/demo/GCP/Mortgage-ETL-CPU.ipynb b/docs/demo/GCP/Mortgage-ETL-CPU.ipynb new file mode 100644 index 00000000000..8618ed1f072 --- /dev/null +++ b/docs/demo/GCP/Mortgage-ETL-CPU.ipynb @@ -0,0 +1,1174 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Data Source\n", + "\n", + "Dataset is derived from Fannie Mae’s [Single-Family Loan Performance Data](http://www.fanniemae.com/portal/funding-the-market/data/loan-performance-data.html) with all rights reserved by Fannie Mae. This processed dataset is redistributed with permission and consent from Fannie Mae. For the full raw dataset visit [Fannie Mae]() to register for an account and to download\n", + "\n", + "Instruction is available at NVIDIA [RAPIDS demo site](https://rapidsai.github.io/demos/datasets/mortgage-data).\n", + "\n", + "### Prerequisite\n", + "\n", + "This notebook runs in a Dataproc cluster with GPU nodes, with [Spark RAPIDS](https://github.com/GoogleCloudDataproc/initialization-actions/tree/master/rapids) set up.\n", + "\n", + "### Define ETL Process\n", + "\n", + "Define data schema and steps to do the ETL process:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import time\n", + "from pyspark import broadcast\n", + "from pyspark.sql import SparkSession\n", + "from pyspark.sql.functions import *\n", + "from pyspark.sql.types import *\n", + "from pyspark.sql.window import Window\n", + "\n", + "def _get_quarter_from_csv_file_name():\n", + " return substring_index(substring_index(input_file_name(), '.', 1), '_', -1)\n", + "\n", + "_csv_perf_schema = StructType([\n", + " StructField('loan_id', LongType()),\n", + " StructField('monthly_reporting_period', StringType()),\n", + " StructField('servicer', StringType()),\n", + " StructField('interest_rate', DoubleType()),\n", + " StructField('current_actual_upb', DoubleType()),\n", + " StructField('loan_age', DoubleType()),\n", + " StructField('remaining_months_to_legal_maturity', DoubleType()),\n", + " StructField('adj_remaining_months_to_maturity', DoubleType()),\n", + " StructField('maturity_date', StringType()),\n", + " StructField('msa', DoubleType()),\n", + " StructField('current_loan_delinquency_status', IntegerType()),\n", + " StructField('mod_flag', StringType()),\n", + " StructField('zero_balance_code', StringType()),\n", + " StructField('zero_balance_effective_date', StringType()),\n", + " StructField('last_paid_installment_date', StringType()),\n", + " StructField('foreclosed_after', StringType()),\n", + " StructField('disposition_date', StringType()),\n", + " StructField('foreclosure_costs', DoubleType()),\n", + " StructField('prop_preservation_and_repair_costs', DoubleType()),\n", + " StructField('asset_recovery_costs', DoubleType()),\n", + " StructField('misc_holding_expenses', DoubleType()),\n", + " StructField('holding_taxes', DoubleType()),\n", + " StructField('net_sale_proceeds', DoubleType()),\n", + " StructField('credit_enhancement_proceeds', DoubleType()),\n", + " StructField('repurchase_make_whole_proceeds', StringType()),\n", + " StructField('other_foreclosure_proceeds', DoubleType()),\n", + " StructField('non_interest_bearing_upb', DoubleType()),\n", + " StructField('principal_forgiveness_upb', StringType()),\n", + " StructField('repurchase_make_whole_proceeds_flag', StringType()),\n", + " StructField('foreclosure_principal_write_off_amount', StringType()),\n", + " StructField('servicing_activity_indicator', StringType())])\n", + "_csv_acq_schema = StructType([\n", + " StructField('loan_id', LongType()),\n", + " StructField('orig_channel', StringType()),\n", + " StructField('seller_name', StringType()),\n", + " StructField('orig_interest_rate', DoubleType()),\n", + " StructField('orig_upb', IntegerType()),\n", + " StructField('orig_loan_term', IntegerType()),\n", + " StructField('orig_date', StringType()),\n", + " StructField('first_pay_date', StringType()),\n", + " StructField('orig_ltv', DoubleType()),\n", + " StructField('orig_cltv', DoubleType()),\n", + " StructField('num_borrowers', DoubleType()),\n", + " StructField('dti', DoubleType()),\n", + " StructField('borrower_credit_score', DoubleType()),\n", + " StructField('first_home_buyer', StringType()),\n", + " StructField('loan_purpose', StringType()),\n", + " StructField('property_type', StringType()),\n", + " StructField('num_units', IntegerType()),\n", + " StructField('occupancy_status', StringType()),\n", + " StructField('property_state', StringType()),\n", + " StructField('zip', IntegerType()),\n", + " StructField('mortgage_insurance_percent', DoubleType()),\n", + " StructField('product_type', StringType()),\n", + " StructField('coborrow_credit_score', DoubleType()),\n", + " StructField('mortgage_insurance_type', DoubleType()),\n", + " StructField('relocation_mortgage_indicator', StringType())])\n", + "_name_mapping = [\n", + " (\"WITMER FUNDING, LLC\", \"Witmer\"),\n", + " (\"WELLS FARGO CREDIT RISK TRANSFER SECURITIES TRUST 2015\", \"Wells Fargo\"),\n", + " (\"WELLS FARGO BANK, NA\" , \"Wells Fargo\"),\n", + " (\"WELLS FARGO BANK, N.A.\" , \"Wells Fargo\"),\n", + " (\"WELLS FARGO BANK, NA\" , \"Wells Fargo\"),\n", + " (\"USAA FEDERAL SAVINGS BANK\" , \"USAA\"),\n", + " (\"UNITED SHORE FINANCIAL SERVICES, LLC D\\\\/B\\\\/A UNITED WHOLESALE MORTGAGE\" , \"United Seq(e\"),\n", + " (\"U.S. BANK N.A.\" , \"US Bank\"),\n", + " (\"SUNTRUST MORTGAGE INC.\" , \"Suntrust\"),\n", + " (\"STONEGATE MORTGAGE CORPORATION\" , \"Stonegate Mortgage\"),\n", + " (\"STEARNS LENDING, LLC\" , \"Stearns Lending\"),\n", + " (\"STEARNS LENDING, INC.\" , \"Stearns Lending\"),\n", + " (\"SIERRA PACIFIC MORTGAGE COMPANY, INC.\" , \"Sierra Pacific Mortgage\"),\n", + " (\"REGIONS BANK\" , \"Regions\"),\n", + " (\"RBC MORTGAGE COMPANY\" , \"RBC\"),\n", + " (\"QUICKEN LOANS INC.\" , \"Quicken Loans\"),\n", + " (\"PULTE MORTGAGE, L.L.C.\" , \"Pulte Mortgage\"),\n", + " (\"PROVIDENT FUNDING ASSOCIATES, L.P.\" , \"Provident Funding\"),\n", + " (\"PROSPECT MORTGAGE, LLC\" , \"Prospect Mortgage\"),\n", + " (\"PRINCIPAL RESIDENTIAL MORTGAGE CAPITAL RESOURCES, LLC\" , \"Principal Residential\"),\n", + " (\"PNC BANK, N.A.\" , \"PNC\"),\n", + " (\"PMT CREDIT RISK TRANSFER TRUST 2015-2\" , \"PennyMac\"),\n", + " (\"PHH MORTGAGE CORPORATION\" , \"PHH Mortgage\"),\n", + " (\"PENNYMAC CORP.\" , \"PennyMac\"),\n", + " (\"PACIFIC UNION FINANCIAL, LLC\" , \"Other\"),\n", + " (\"OTHER\" , \"Other\"),\n", + " (\"NYCB MORTGAGE COMPANY, LLC\" , \"NYCB\"),\n", + " (\"NEW YORK COMMUNITY BANK\" , \"NYCB\"),\n", + " (\"NETBANK FUNDING SERVICES\" , \"Netbank\"),\n", + " (\"NATIONSTAR MORTGAGE, LLC\" , \"Nationstar Mortgage\"),\n", + " (\"METLIFE BANK, NA\" , \"Metlife\"),\n", + " (\"LOANDEPOT.COM, LLC\" , \"LoanDepot.com\"),\n", + " (\"J.P. MORGAN MADISON AVENUE SECURITIES TRUST, SERIES 2015-1\" , \"JP Morgan Chase\"),\n", + " (\"J.P. MORGAN MADISON AVENUE SECURITIES TRUST, SERIES 2014-1\" , \"JP Morgan Chase\"),\n", + " (\"JPMORGAN CHASE BANK, NATIONAL ASSOCIATION\" , \"JP Morgan Chase\"),\n", + " (\"JPMORGAN CHASE BANK, NA\" , \"JP Morgan Chase\"),\n", + " (\"JP MORGAN CHASE BANK, NA\" , \"JP Morgan Chase\"),\n", + " (\"IRWIN MORTGAGE, CORPORATION\" , \"Irwin Mortgage\"),\n", + " (\"IMPAC MORTGAGE CORP.\" , \"Impac Mortgage\"),\n", + " (\"HSBC BANK USA, NATIONAL ASSOCIATION\" , \"HSBC\"),\n", + " (\"HOMEWARD RESIDENTIAL, INC.\" , \"Homeward Mortgage\"),\n", + " (\"HOMESTREET BANK\" , \"Other\"),\n", + " (\"HOMEBRIDGE FINANCIAL SERVICES, INC.\" , \"HomeBridge\"),\n", + " (\"HARWOOD STREET FUNDING I, LLC\" , \"Harwood Mortgage\"),\n", + " (\"GUILD MORTGAGE COMPANY\" , \"Guild Mortgage\"),\n", + " (\"GMAC MORTGAGE, LLC (USAA FEDERAL SAVINGS BANK)\" , \"GMAC\"),\n", + " (\"GMAC MORTGAGE, LLC\" , \"GMAC\"),\n", + " (\"GMAC (USAA)\" , \"GMAC\"),\n", + " (\"FREMONT BANK\" , \"Fremont Bank\"),\n", + " (\"FREEDOM MORTGAGE CORP.\" , \"Freedom Mortgage\"),\n", + " (\"FRANKLIN AMERICAN MORTGAGE COMPANY\" , \"Franklin America\"),\n", + " (\"FLEET NATIONAL BANK\" , \"Fleet National\"),\n", + " (\"FLAGSTAR CAPITAL MARKETS CORPORATION\" , \"Flagstar Bank\"),\n", + " (\"FLAGSTAR BANK, FSB\" , \"Flagstar Bank\"),\n", + " (\"FIRST TENNESSEE BANK NATIONAL ASSOCIATION\" , \"Other\"),\n", + " (\"FIFTH THIRD BANK\" , \"Fifth Third Bank\"),\n", + " (\"FEDERAL HOME LOAN BANK OF CHICAGO\" , \"Fedral Home of Chicago\"),\n", + " (\"FDIC, RECEIVER, INDYMAC FEDERAL BANK FSB\" , \"FDIC\"),\n", + " (\"DOWNEY SAVINGS AND LOAN ASSOCIATION, F.A.\" , \"Downey Mortgage\"),\n", + " (\"DITECH FINANCIAL LLC\" , \"Ditech\"),\n", + " (\"CITIMORTGAGE, INC.\" , \"Citi\"),\n", + " (\"CHICAGO MORTGAGE SOLUTIONS DBA INTERFIRST MORTGAGE COMPANY\" , \"Chicago Mortgage\"),\n", + " (\"CHICAGO MORTGAGE SOLUTIONS DBA INTERBANK MORTGAGE COMPANY\" , \"Chicago Mortgage\"),\n", + " (\"CHASE HOME FINANCE, LLC\" , \"JP Morgan Chase\"),\n", + " (\"CHASE HOME FINANCE FRANKLIN AMERICAN MORTGAGE COMPANY\" , \"JP Morgan Chase\"),\n", + " (\"CHASE HOME FINANCE (CIE 1)\" , \"JP Morgan Chase\"),\n", + " (\"CHASE HOME FINANCE\" , \"JP Morgan Chase\"),\n", + " (\"CASHCALL, INC.\" , \"CashCall\"),\n", + " (\"CAPITAL ONE, NATIONAL ASSOCIATION\" , \"Capital One\"),\n", + " (\"CALIBER HOME LOANS, INC.\" , \"Caliber Funding\"),\n", + " (\"BISHOPS GATE RESIDENTIAL MORTGAGE TRUST\" , \"Bishops Gate Mortgage\"),\n", + " (\"BANK OF AMERICA, N.A.\" , \"Bank of America\"),\n", + " (\"AMTRUST BANK\" , \"AmTrust\"),\n", + " (\"AMERISAVE MORTGAGE CORPORATION\" , \"Amerisave\"),\n", + " (\"AMERIHOME MORTGAGE COMPANY, LLC\" , \"AmeriHome Mortgage\"),\n", + " (\"ALLY BANK\" , \"Ally Bank\"),\n", + " (\"ACADEMY MORTGAGE CORPORATION\" , \"Academy Mortgage\"),\n", + " (\"NO CASH-OUT REFINANCE\" , \"OTHER REFINANCE\"),\n", + " (\"REFINANCE - NOT SPECIFIED\" , \"OTHER REFINANCE\"),\n", + " (\"Other REFINANCE\" , \"OTHER REFINANCE\")]\n", + "\n", + "cate_col_names = [\n", + " \"orig_channel\",\n", + " \"first_home_buyer\",\n", + " \"loan_purpose\",\n", + " \"property_type\",\n", + " \"occupancy_status\",\n", + " \"property_state\",\n", + " \"relocation_mortgage_indicator\",\n", + " \"seller_name\",\n", + " \"mod_flag\"\n", + "]\n", + "# Numberic columns\n", + "label_col_name = \"delinquency_12\"\n", + "numeric_col_names = [\n", + " \"orig_interest_rate\",\n", + " \"orig_upb\",\n", + " \"orig_loan_term\",\n", + " \"orig_ltv\",\n", + " \"orig_cltv\",\n", + " \"num_borrowers\",\n", + " \"dti\",\n", + " \"borrower_credit_score\",\n", + " \"num_units\",\n", + " \"zip\",\n", + " \"mortgage_insurance_percent\",\n", + " \"current_loan_delinquency_status\",\n", + " \"current_actual_upb\",\n", + " \"interest_rate\",\n", + " \"loan_age\",\n", + " \"msa\",\n", + " \"non_interest_bearing_upb\",\n", + " label_col_name\n", + "]\n", + "all_col_names = cate_col_names + numeric_col_names\n", + "\n", + "def read_perf_csv(spark, path):\n", + " return spark.read.format('csv') \\\n", + " .option('nullValue', '') \\\n", + " .option('header', 'false') \\\n", + " .option('delimiter', '|') \\\n", + " .schema(_csv_perf_schema) \\\n", + " .load(path) \\\n", + " .withColumn('quarter', _get_quarter_from_csv_file_name())\n", + "\n", + "def read_acq_csv(spark, path):\n", + " return spark.read.format('csv') \\\n", + " .option('nullValue', '') \\\n", + " .option('header', 'false') \\\n", + " .option('delimiter', '|') \\\n", + " .schema(_csv_acq_schema) \\\n", + " .load(path) \\\n", + " .withColumn('quarter', _get_quarter_from_csv_file_name())\n", + "\n", + "def _parse_dates(perf):\n", + " return perf \\\n", + " .withColumn('monthly_reporting_period', to_date(col('monthly_reporting_period'), 'MM/dd/yyyy')) \\\n", + " .withColumn('monthly_reporting_period_month', month(col('monthly_reporting_period'))) \\\n", + " .withColumn('monthly_reporting_period_year', year(col('monthly_reporting_period'))) \\\n", + " .withColumn('monthly_reporting_period_day', dayofmonth(col('monthly_reporting_period'))) \\\n", + " .withColumn('last_paid_installment_date', to_date(col('last_paid_installment_date'), 'MM/dd/yyyy')) \\\n", + " .withColumn('foreclosed_after', to_date(col('foreclosed_after'), 'MM/dd/yyyy')) \\\n", + " .withColumn('disposition_date', to_date(col('disposition_date'), 'MM/dd/yyyy')) \\\n", + " .withColumn('maturity_date', to_date(col('maturity_date'), 'MM/yyyy')) \\\n", + " .withColumn('zero_balance_effective_date', to_date(col('zero_balance_effective_date'), 'MM/yyyy'))\n", + "\n", + "def _create_perf_deliquency(spark, perf):\n", + " aggDF = perf.select(\n", + " col(\"quarter\"),\n", + " col(\"loan_id\"),\n", + " col(\"current_loan_delinquency_status\"),\n", + " when(col(\"current_loan_delinquency_status\") >= 1, col(\"monthly_reporting_period\")).alias(\"delinquency_30\"),\n", + " when(col(\"current_loan_delinquency_status\") >= 3, col(\"monthly_reporting_period\")).alias(\"delinquency_90\"),\n", + " when(col(\"current_loan_delinquency_status\") >= 6, col(\"monthly_reporting_period\")).alias(\"delinquency_180\")) \\\n", + " .groupBy(\"quarter\", \"loan_id\") \\\n", + " .agg(\n", + " max(\"current_loan_delinquency_status\").alias(\"delinquency_12\"),\n", + " min(\"delinquency_30\").alias(\"delinquency_30\"),\n", + " min(\"delinquency_90\").alias(\"delinquency_90\"),\n", + " min(\"delinquency_180\").alias(\"delinquency_180\")) \\\n", + " .select(\n", + " col(\"quarter\"),\n", + " col(\"loan_id\"),\n", + " (col(\"delinquency_12\") >= 1).alias(\"ever_30\"),\n", + " (col(\"delinquency_12\") >= 3).alias(\"ever_90\"),\n", + " (col(\"delinquency_12\") >= 6).alias(\"ever_180\"),\n", + " col(\"delinquency_30\"),\n", + " col(\"delinquency_90\"),\n", + " col(\"delinquency_180\"))\n", + " joinedDf = perf \\\n", + " .withColumnRenamed(\"monthly_reporting_period\", \"timestamp\") \\\n", + " .withColumnRenamed(\"monthly_reporting_period_month\", \"timestamp_month\") \\\n", + " .withColumnRenamed(\"monthly_reporting_period_year\", \"timestamp_year\") \\\n", + " .withColumnRenamed(\"current_loan_delinquency_status\", \"delinquency_12\") \\\n", + " .withColumnRenamed(\"current_actual_upb\", \"upb_12\") \\\n", + " .select(\"quarter\", \"loan_id\", \"timestamp\", \"delinquency_12\", \"upb_12\", \"timestamp_month\", \"timestamp_year\") \\\n", + " .join(aggDF, [\"loan_id\", \"quarter\"], \"left_outer\")\n", + "\n", + " # calculate the 12 month delinquency and upb values\n", + " months = 12\n", + " monthArray = [lit(x) for x in range(0, 12)]\n", + " # explode on a small amount of data is actually slightly more efficient than a cross join\n", + " testDf = joinedDf \\\n", + " .withColumn(\"month_y\", explode(array(monthArray))) \\\n", + " .select(\n", + " col(\"quarter\"),\n", + " floor(((col(\"timestamp_year\") * 12 + col(\"timestamp_month\")) - 24000) / months).alias(\"josh_mody\"),\n", + " floor(((col(\"timestamp_year\") * 12 + col(\"timestamp_month\")) - 24000 - col(\"month_y\")) / months).alias(\"josh_mody_n\"),\n", + " col(\"ever_30\"),\n", + " col(\"ever_90\"),\n", + " col(\"ever_180\"),\n", + " col(\"delinquency_30\"),\n", + " col(\"delinquency_90\"),\n", + " col(\"delinquency_180\"),\n", + " col(\"loan_id\"),\n", + " col(\"month_y\"),\n", + " col(\"delinquency_12\"),\n", + " col(\"upb_12\")) \\\n", + " .groupBy(\"quarter\", \"loan_id\", \"josh_mody_n\", \"ever_30\", \"ever_90\", \"ever_180\", \"delinquency_30\", \"delinquency_90\", \"delinquency_180\", \"month_y\") \\\n", + " .agg(max(\"delinquency_12\").alias(\"delinquency_12\"), min(\"upb_12\").alias(\"upb_12\")) \\\n", + " .withColumn(\"timestamp_year\", floor((lit(24000) + (col(\"josh_mody_n\") * lit(months)) + (col(\"month_y\") - 1)) / lit(12))) \\\n", + " .selectExpr('*', 'pmod(24000 + (josh_mody_n * {}) + month_y, 12) as timestamp_month_tmp'.format(months)) \\\n", + " .withColumn(\"timestamp_month\", when(col(\"timestamp_month_tmp\") == lit(0), lit(12)).otherwise(col(\"timestamp_month_tmp\"))) \\\n", + " .withColumn(\"delinquency_12\", ((col(\"delinquency_12\") > 3).cast(\"int\") + (col(\"upb_12\") == 0).cast(\"int\")).alias(\"delinquency_12\")) \\\n", + " .drop(\"timestamp_month_tmp\", \"josh_mody_n\", \"month_y\")\n", + "\n", + " return perf.withColumnRenamed(\"monthly_reporting_period_month\", \"timestamp_month\") \\\n", + " .withColumnRenamed(\"monthly_reporting_period_year\", \"timestamp_year\") \\\n", + " .join(testDf, [\"quarter\", \"loan_id\", \"timestamp_year\", \"timestamp_month\"], \"left\") \\\n", + " .drop(\"timestamp_year\", \"timestamp_month\")\n", + "\n", + "def _create_acquisition(spark, acq):\n", + " nameMapping = spark.createDataFrame(_name_mapping, [\"from_seller_name\", \"to_seller_name\"])\n", + " return acq.join(nameMapping, col(\"seller_name\") == col(\"from_seller_name\"), \"left\") \\\n", + " .drop(\"from_seller_name\") \\\n", + " .withColumn(\"old_name\", col(\"seller_name\")) \\\n", + " .withColumn(\"seller_name\", coalesce(col(\"to_seller_name\"), col(\"seller_name\"))) \\\n", + " .drop(\"to_seller_name\") \\\n", + " .withColumn(\"orig_date\", to_date(col(\"orig_date\"), \"MM/yyyy\")) \\\n", + " .withColumn(\"first_pay_date\", to_date(col(\"first_pay_date\"), \"MM/yyyy\")) \\\n", + "\n", + "def _gen_dictionary(etl_df, col_names):\n", + " cnt_table = etl_df.select(posexplode(array([col(i) for i in col_names])))\\\n", + " .withColumnRenamed(\"pos\", \"column_id\")\\\n", + " .withColumnRenamed(\"col\", \"data\")\\\n", + " .filter(\"data is not null\")\\\n", + " .groupBy(\"column_id\", \"data\")\\\n", + " .count()\n", + " windowed = Window.partitionBy(\"column_id\").orderBy(desc(\"count\"))\n", + " return cnt_table.withColumn(\"id\", row_number().over(windowed)).drop(\"count\")\n", + "\n", + "\n", + "def _cast_string_columns_to_numeric(spark, input_df):\n", + " cached_dict_df = _gen_dictionary(input_df, cate_col_names).cache()\n", + " output_df = input_df\n", + " # Generate the final table with all columns being numeric.\n", + " for col_pos, col_name in enumerate(cate_col_names):\n", + " col_dict_df = cached_dict_df.filter(col(\"column_id\") == col_pos)\\\n", + " .drop(\"column_id\")\\\n", + " .withColumnRenamed(\"data\", col_name)\n", + " \n", + " output_df = output_df.join(broadcast(col_dict_df), col_name, \"left\")\\\n", + " .drop(col_name)\\\n", + " .withColumnRenamed(\"id\", col_name)\n", + " return output_df\n", + "\n", + "def run_mortgage(spark, perf, acq):\n", + " parsed_perf = _parse_dates(perf)\n", + " perf_deliqency = _create_perf_deliquency(spark, parsed_perf)\n", + " cleaned_acq = _create_acquisition(spark, acq)\n", + " df = perf_deliqency.join(cleaned_acq, [\"loan_id\", \"quarter\"], \"inner\")\n", + " test_quarters = ['2016Q1','2016Q2','2016Q3','2016Q4']\n", + " train_df = df.filter(~df.quarter.isin(test_quarters)).drop(\"quarter\")\n", + " test_df = df.filter(df.quarter.isin(test_quarters)).drop(\"quarter\")\n", + " casted_train_df = _cast_string_columns_to_numeric(spark, train_df)\\\n", + " .select(all_col_names)\\\n", + " .withColumn(label_col_name, when(col(label_col_name) > 0, 1).otherwise(0))\\\n", + " .fillna(float(0))\n", + " casted_test_df = _cast_string_columns_to_numeric(spark, test_df)\\\n", + " .select(all_col_names)\\\n", + " .withColumn(label_col_name, when(col(label_col_name) > 0, 1).otherwise(0))\\\n", + " .fillna(float(0))\n", + " return casted_train_df, casted_test_df" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Define Spark conf and Create Spark Session\n", + "For details explanation for spark conf, please go to Spark RAPIDS [config guide](https://nvidia.github.io/spark-rapids/docs/configs.html)." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "sc.stop()\n", + "\n", + "conf = SparkConf().setAppName(\"MortgageETL-CPU\")\n", + "conf.set(\"spark.executor.instances\", \"20\")\n", + "conf.set(\"spark.executor.cores\", \"7\") # spark.executor.cores times spark.executor.instances should equal total cores.\n", + "conf.set(\"spark.task.cpus\", \"1\")\n", + "conf.set(\"spark.executor.memory\", \"36g\")\n", + "conf.set(\"spark.locality.wait\", \"0s\")\n", + "conf.set(\"spark.sql.files.maxPartitionBytes\", \"512m\")\n", + "conf.set(\"spark.executor.resource.gpu.amount\", \"0\")\n", + "conf.set(\"spark.task.resource.gpu.amount\", \"0\")\n", + "conf.set(\"spark.plugins\", \" \")\n", + "conf.set(\"spark.sql.broadcastTimeout\", \"7200\")\n", + "spark = SparkSession.builder \\\n", + " .config(conf=conf) \\\n", + " .getOrCreate()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Define Data Input/Output location" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "orig_perf_path = 'gs://dataproc-nv-demo/mortgage_full/perf/*'\n", + "orig_acq_path = 'gs://dataproc-nv-demo/mortgage_full/acq/*'\n", + "train_path = 'gs://dataproc-nv-demo/mortgage_cpu/train/'\n", + "test_path = 'gs://dataproc-nv-demo/mortgage_cpu/test/'\n", + "tmp_perf_path = 'gs://dataproc-nv-demo/mortgage_parquet_cpu/perf/'\n", + "tmp_acq_path = 'gs://dataproc-nv-demo/mortgage_parquet_cpu/acq/'" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Read CSV data and Transcode to Parquet" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "# Lets transcode the data first\n", + "start = time.time()\n", + "# we want a few big files instead of lots of small files\n", + "spark.conf.set('spark.sql.files.maxPartitionBytes', '200G')\n", + "acq = read_acq_csv(spark, orig_acq_path)\n", + "acq.repartition(20).write.parquet(tmp_acq_path, mode='overwrite')\n", + "perf = read_perf_csv(spark, orig_perf_path)\n", + "perf.coalesce(80).write.parquet(tmp_perf_path, mode='overwrite')\n", + "end = time.time()\n", + "print(end - start)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Execute ETL Code Defined in 1st Cell" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1194.4553289413452\n", + "1813.5378119945526\n" + ] + } + ], + "source": [ + "# Now lets actually process the data\\n\",\n", + "start = time.time()\n", + "spark.conf.set('spark.sql.shuffle.partitions', '160')\n", + "perf = spark.read.parquet(tmp_perf_path)\n", + "acq = spark.read.parquet(tmp_acq_path)\n", + "train_out, test_out = run_mortgage(spark, perf, acq)\n", + "train_out.write.parquet(train_path, mode='overwrite')\n", + "end = time.time()\n", + "print(end - start)\n", + "test_out.write.parquet(test_path, mode='overwrite')\n", + "end = time.time()\n", + "print(end - start)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Print Physical Plan" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "== Physical Plan ==\n", + "*(27) Project [coalesce(orig_channel#1675, 0) AS orig_channel#3439, coalesce(first_home_buyer#1877, 0) AS first_home_buyer#3440, coalesce(loan_purpose#2079, 0) AS loan_purpose#3441, coalesce(property_type#2281, 0) AS property_type#3442, coalesce(occupancy_status#2483, 0) AS occupancy_status#3443, coalesce(property_state#2685, 0) AS property_state#3444, coalesce(relocation_mortgage_indicator#2887, 0) AS relocation_mortgage_indicator#3445, coalesce(seller_name#3089, 0) AS seller_name#3446, coalesce(id#1498, 0) AS mod_flag#3447, coalesce(nanvl(orig_interest_rate#67, null), 0.0) AS orig_interest_rate#3448, coalesce(orig_upb#68, 0) AS orig_upb#3449, coalesce(orig_loan_term#69, 0) AS orig_loan_term#3450, coalesce(nanvl(orig_ltv#72, null), 0.0) AS orig_ltv#3451, coalesce(nanvl(orig_cltv#73, null), 0.0) AS orig_cltv#3452, coalesce(nanvl(num_borrowers#74, null), 0.0) AS num_borrowers#3453, coalesce(nanvl(dti#75, null), 0.0) AS dti#3454, coalesce(nanvl(borrower_credit_score#76, null), 0.0) AS borrower_credit_score#3455, coalesce(num_units#80, 0) AS num_units#3456, coalesce(zip#83, 0) AS zip#3457, coalesce(nanvl(mortgage_insurance_percent#84, null), 0.0) AS mortgage_insurance_percent#3458, coalesce(current_loan_delinquency_status#10, 0) AS current_loan_delinquency_status#3459, coalesce(nanvl(current_actual_upb#4, null), 0.0) AS current_actual_upb#3460, coalesce(nanvl(interest_rate#3, null), 0.0) AS interest_rate#3461, coalesce(nanvl(loan_age#5, null), 0.0) AS loan_age#3462, ... 3 more fields]\n", + "+- *(27) BroadcastHashJoin [mod_flag#11], [mod_flag#3157], LeftOuter, BuildRight\n", + " :- *(27) Project [interest_rate#3, current_actual_upb#4, loan_age#5, msa#9, current_loan_delinquency_status#10, mod_flag#11, non_interest_bearing_upb#26, delinquency_12#812, orig_interest_rate#67, orig_upb#68, orig_loan_term#69, orig_ltv#72, orig_cltv#73, num_borrowers#74, dti#75, borrower_credit_score#76, num_units#80, zip#83, mortgage_insurance_percent#84, orig_channel#1675, first_home_buyer#1877, loan_purpose#2079, property_type#2281, occupancy_status#2483, ... 3 more fields]\n", + " : +- *(27) BroadcastHashJoin [seller_name#1172], [seller_name#2955], LeftOuter, BuildRight\n", + " : :- *(27) Project [interest_rate#3, current_actual_upb#4, loan_age#5, msa#9, current_loan_delinquency_status#10, mod_flag#11, non_interest_bearing_upb#26, delinquency_12#812, seller_name#1172, orig_interest_rate#67, orig_upb#68, orig_loan_term#69, orig_ltv#72, orig_cltv#73, num_borrowers#74, dti#75, borrower_credit_score#76, num_units#80, zip#83, mortgage_insurance_percent#84, orig_channel#1675, first_home_buyer#1877, loan_purpose#2079, property_type#2281, ... 3 more fields]\n", + " : : +- *(27) BroadcastHashJoin [relocation_mortgage_indicator#88], [relocation_mortgage_indicator#2753], LeftOuter, BuildRight\n", + " : : :- *(27) Project [interest_rate#3, current_actual_upb#4, loan_age#5, msa#9, current_loan_delinquency_status#10, mod_flag#11, non_interest_bearing_upb#26, delinquency_12#812, seller_name#1172, orig_interest_rate#67, orig_upb#68, orig_loan_term#69, orig_ltv#72, orig_cltv#73, num_borrowers#74, dti#75, borrower_credit_score#76, num_units#80, zip#83, mortgage_insurance_percent#84, relocation_mortgage_indicator#88, orig_channel#1675, first_home_buyer#1877, loan_purpose#2079, ... 3 more fields]\n", + " : : : +- *(27) BroadcastHashJoin [property_state#82], [property_state#2551], LeftOuter, BuildRight\n", + " : : : :- *(27) Project [interest_rate#3, current_actual_upb#4, loan_age#5, msa#9, current_loan_delinquency_status#10, mod_flag#11, non_interest_bearing_upb#26, delinquency_12#812, seller_name#1172, orig_interest_rate#67, orig_upb#68, orig_loan_term#69, orig_ltv#72, orig_cltv#73, num_borrowers#74, dti#75, borrower_credit_score#76, num_units#80, property_state#82, zip#83, mortgage_insurance_percent#84, relocation_mortgage_indicator#88, orig_channel#1675, first_home_buyer#1877, ... 3 more fields]\n", + " : : : : +- *(27) BroadcastHashJoin [occupancy_status#81], [occupancy_status#2349], LeftOuter, BuildRight\n", + " : : : : :- *(27) Project [interest_rate#3, current_actual_upb#4, loan_age#5, msa#9, current_loan_delinquency_status#10, mod_flag#11, non_interest_bearing_upb#26, delinquency_12#812, seller_name#1172, orig_interest_rate#67, orig_upb#68, orig_loan_term#69, orig_ltv#72, orig_cltv#73, num_borrowers#74, dti#75, borrower_credit_score#76, num_units#80, occupancy_status#81, property_state#82, zip#83, mortgage_insurance_percent#84, relocation_mortgage_indicator#88, orig_channel#1675, ... 3 more fields]\n", + " : : : : : +- *(27) BroadcastHashJoin [property_type#79], [property_type#2147], LeftOuter, BuildRight\n", + " : : : : : :- *(27) Project [interest_rate#3, current_actual_upb#4, loan_age#5, msa#9, current_loan_delinquency_status#10, mod_flag#11, non_interest_bearing_upb#26, delinquency_12#812, seller_name#1172, orig_interest_rate#67, orig_upb#68, orig_loan_term#69, orig_ltv#72, orig_cltv#73, num_borrowers#74, dti#75, borrower_credit_score#76, property_type#79, num_units#80, occupancy_status#81, property_state#82, zip#83, mortgage_insurance_percent#84, relocation_mortgage_indicator#88, ... 3 more fields]\n", + " : : : : : : +- *(27) BroadcastHashJoin [loan_purpose#78], [loan_purpose#1945], LeftOuter, BuildRight\n", + " : : : : : : :- *(27) Project [interest_rate#3, current_actual_upb#4, loan_age#5, msa#9, current_loan_delinquency_status#10, mod_flag#11, non_interest_bearing_upb#26, delinquency_12#812, seller_name#1172, orig_interest_rate#67, orig_upb#68, orig_loan_term#69, orig_ltv#72, orig_cltv#73, num_borrowers#74, dti#75, borrower_credit_score#76, loan_purpose#78, property_type#79, num_units#80, occupancy_status#81, property_state#82, zip#83, mortgage_insurance_percent#84, ... 3 more fields]\n", + " : : : : : : : +- *(27) BroadcastHashJoin [first_home_buyer#77], [first_home_buyer#1743], LeftOuter, BuildRight\n", + " : : : : : : : :- *(27) Project [interest_rate#3, current_actual_upb#4, loan_age#5, msa#9, current_loan_delinquency_status#10, mod_flag#11, non_interest_bearing_upb#26, delinquency_12#812, seller_name#1172, orig_interest_rate#67, orig_upb#68, orig_loan_term#69, orig_ltv#72, orig_cltv#73, num_borrowers#74, dti#75, borrower_credit_score#76, first_home_buyer#77, loan_purpose#78, property_type#79, num_units#80, occupancy_status#81, property_state#82, zip#83, ... 3 more fields]\n", + " : : : : : : : : +- *(27) BroadcastHashJoin [orig_channel#65], [orig_channel#1541], LeftOuter, BuildRight\n", + " : : : : : : : : :- *(27) Project [interest_rate#3, current_actual_upb#4, loan_age#5, msa#9, current_loan_delinquency_status#10, mod_flag#11, non_interest_bearing_upb#26, delinquency_12#812, orig_channel#65, seller_name#1172, orig_interest_rate#67, orig_upb#68, orig_loan_term#69, orig_ltv#72, orig_cltv#73, num_borrowers#74, dti#75, borrower_credit_score#76, first_home_buyer#77, loan_purpose#78, property_type#79, num_units#80, occupancy_status#81, property_state#82, ... 3 more fields]\n", + " : : : : : : : : : +- *(27) SortMergeJoin [loan_id#0L, quarter#31], [loan_id#64L, quarter#89], Inner\n", + " : : : : : : : : : :- *(11) Sort [loan_id#0L ASC NULLS FIRST, quarter#31 ASC NULLS FIRST], false, 0\n", + " : : : : : : : : : : +- Exchange hashpartitioning(loan_id#0L, quarter#31, 160), true, [id=#2011]\n", + " : : : : : : : : : : +- *(10) Project [quarter#31, loan_id#0L, interest_rate#3, current_actual_upb#4, loan_age#5, msa#9, current_loan_delinquency_status#10, mod_flag#11, non_interest_bearing_upb#26, delinquency_12#812]\n", + " : : : : : : : : : : +- SortMergeJoin [quarter#31, loan_id#0L, cast(timestamp_year#876 as bigint), cast(timestamp_month#840 as bigint)], [quarter#943, loan_id#912L, timestamp_year#766L, timestamp_month#795L], LeftOuter\n", + " : : : : : : : : : : :- *(2) Sort [quarter#31 ASC NULLS FIRST, loan_id#0L ASC NULLS FIRST, cast(timestamp_year#876 as bigint) ASC NULLS FIRST, cast(timestamp_month#840 as bigint) ASC NULLS FIRST], false, 0\n", + " : : : : : : : : : : : +- Exchange hashpartitioning(quarter#31, loan_id#0L, cast(timestamp_year#876 as bigint), cast(timestamp_month#840 as bigint), 160), true, [id=#1968]\n", + " : : : : : : : : : : : +- *(1) Project [loan_id#0L, interest_rate#3, current_actual_upb#4, loan_age#5, msa#9, current_loan_delinquency_status#10, mod_flag#11, non_interest_bearing_upb#26, quarter#31, month(cast(cast(unix_timestamp(monthly_reporting_period#1, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date)) AS timestamp_month#840, year(cast(cast(unix_timestamp(monthly_reporting_period#1, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date)) AS timestamp_year#876]\n", + " : : : : : : : : : : : +- *(1) Filter ((NOT quarter#31 IN (2016Q1,2016Q2,2016Q3,2016Q4) AND isnotnull(loan_id#0L)) AND isnotnull(quarter#31))\n", + " : : : : : : : : : : : +- *(1) ColumnarToRow\n", + " : : : : : : : : : : : +- FileScan parquet [loan_id#0L,monthly_reporting_period#1,interest_rate#3,current_actual_upb#4,loan_age#5,msa#9,current_loan_delinquency_status#10,mod_flag#11,non_interest_bearing_upb#26,quarter#31] Batched: true, DataFilters: [NOT quarter#31 IN (2016Q1,2016Q2,2016Q3,2016Q4), isnotnull(loan_id#0L), isnotnull(quarter#31)], Format: Parquet, Location: InMemoryFileIndex[gs://dataproc-nv-demo/mortgage_parquet_cpu/perf], PartitionFilters: [], PushedFilters: [Not(In(quarter, [2016Q1,2016Q2,2016Q3,2016Q4])), IsNotNull(loan_id), IsNotNull(quarter)], ReadSchema: struct= 1) THEN cast(cast(unix_timestamp(monthly_reporting_period#662, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date) END AS delinquency_30#434, CASE WHEN (current_loan_delinquency_status#671 >= 3) THEN cast(cast(unix_timestamp(monthly_reporting_period#662, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date) END AS delinquency_90#435, CASE WHEN (current_loan_delinquency_status#671 >= 6) THEN cast(cast(unix_timestamp(monthly_reporting_period#662, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date) END AS delinquency_180#436]\n", + " : : : : : : : : : : +- *(5) Filter (isnotnull(loan_id#661L) AND isnotnull(quarter#692))\n", + " : : : : : : : : : : +- *(5) ColumnarToRow\n", + " : : : : : : : : : : +- FileScan parquet [loan_id#661L,monthly_reporting_period#662,current_loan_delinquency_status#671,quarter#692] Batched: true, DataFilters: [isnotnull(loan_id#661L), isnotnull(quarter#692)], Format: Parquet, Location: InMemoryFileIndex[gs://dataproc-nv-demo/mortgage_parquet_cpu/perf], PartitionFilters: [], PushedFilters: [IsNotNull(loan_id), IsNotNull(quarter)], ReadSchema: struct\n", + " : : : : : : : : : +- *(9) Sort [quarter#943 ASC NULLS FIRST, loan_id#912L ASC NULLS FIRST, timestamp_year#766L ASC NULLS FIRST, timestamp_month#795L ASC NULLS FIRST], false, 0\n", + " : : : : : : : : : +- Exchange hashpartitioning(quarter#943, loan_id#912L, timestamp_year#766L, timestamp_month#795L, 160), true, [id=#264]\n", + " : : : : : : : : : +- *(8) HashAggregate(keys=[quarter#943, loan_id#912L, josh_mody_n#723L, ever_30#463, ever_90#464, ever_180#465, delinquency_30#452, delinquency_90#454, delinquency_180#456, month_y#707], functions=[])\n", + " : : : : : : : : : +- *(8) HashAggregate(keys=[quarter#943, loan_id#912L, josh_mody_n#723L, ever_30#463, ever_90#464, ever_180#465, delinquency_30#452, delinquency_90#454, delinquency_180#456, month_y#707], functions=[])\n", + " : : : : : : : : : +- *(8) Project [quarter#943, FLOOR((cast(((((timestamp_year#546 * 12) + timestamp_month#510) - 24000) - month_y#707) as double) / 12.0)) AS josh_mody_n#723L, ever_30#463, ever_90#464, ever_180#465, delinquency_30#452, delinquency_90#454, delinquency_180#456, loan_id#912L, month_y#707]\n", + " : : : : : : : : : +- *(8) Filter (isnotnull(CASE WHEN (pmod(((24000 + (FLOOR((cast(((((timestamp_year#546 * 12) + timestamp_month#510) - 24000) - month_y#707) as double) / 12.0)) * 12)) + cast(month_y#707 as bigint)), 12) = 0) THEN 12 ELSE pmod(((24000 + (FLOOR((cast(((((timestamp_year#546 * 12) + timestamp_month#510) - 24000) - month_y#707) as double) / 12.0)) * 12)) + cast(month_y#707 as bigint)), 12) END) AND isnotnull(FLOOR((cast(((24000 + (FLOOR((cast(((((timestamp_year#546 * 12) + timestamp_month#510) - 24000) - month_y#707) as double) / 12.0)) * 12)) + cast((month_y#707 - 1) as bigint)) as double) / 12.0))))\n", + " : : : : : : : : : +- Generate explode([0,1,2,3,4,5,6,7,8,9,10,11]), [loan_id#912L, quarter#943, timestamp_month#510, timestamp_year#546, ever_30#463, ever_90#464, ever_180#465, delinquency_30#452, delinquency_90#454, delinquency_180#456], false, [month_y#707]\n", + " : : : : : : : : : +- *(7) Project [loan_id#912L, quarter#943, timestamp_month#510, timestamp_year#546, ever_30#463, ever_90#464, ever_180#465, delinquency_30#452, delinquency_90#454, delinquency_180#456]\n", + " : : : : : : : : : +- SortMergeJoin [quarter#943, loan_id#912L], [quarter#692, loan_id#661L], LeftOuter\n", + " : : : : : : : : : :- *(4) Sort [quarter#943 ASC NULLS FIRST, loan_id#912L ASC NULLS FIRST], false, 0\n", + " : : : : : : : : : : +- Exchange hashpartitioning(quarter#943, loan_id#912L, 160), true, [id=#238]\n", + " : : : : : : : : : : +- *(3) Project [quarter#943, loan_id#912L, month(cast(cast(unix_timestamp(monthly_reporting_period#913, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date)) AS timestamp_month#510, year(cast(cast(unix_timestamp(monthly_reporting_period#913, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date)) AS timestamp_year#546]\n", + " : : : : : : : : : : +- *(3) Filter ((NOT quarter#943 IN (2016Q1,2016Q2,2016Q3,2016Q4) AND isnotnull(quarter#943)) AND isnotnull(loan_id#912L))\n", + " : : : : : : : : : : +- *(3) ColumnarToRow\n", + " : : : : : : : : : : +- FileScan parquet [loan_id#912L,monthly_reporting_period#913,quarter#943] Batched: true, DataFilters: [NOT quarter#943 IN (2016Q1,2016Q2,2016Q3,2016Q4), isnotnull(quarter#943), isnotnull(loan_id#912L)], Format: Parquet, Location: InMemoryFileIndex[gs://dataproc-nv-demo/mortgage_parquet_cpu/perf], PartitionFilters: [], PushedFilters: [Not(In(quarter, [2016Q1,2016Q2,2016Q3,2016Q4])), IsNotNull(quarter), IsNotNull(loan_id)], ReadSchema: struct\n", + " : : : : : : : : : +- *(6) Sort [quarter#692 ASC NULLS FIRST, loan_id#661L ASC NULLS FIRST], false, 0\n", + " : : : : : : : : : +- *(6) HashAggregate(keys=[quarter#692, loan_id#661L], functions=[max(current_loan_delinquency_status#671), min(delinquency_30#434), min(delinquency_90#435), min(delinquency_180#436)])\n", + " : : : : : : : : : +- Exchange hashpartitioning(quarter#692, loan_id#661L, 160), true, [id=#248]\n", + " : : : : : : : : : +- *(5) HashAggregate(keys=[quarter#692, loan_id#661L], functions=[partial_max(current_loan_delinquency_status#671), partial_min(delinquency_30#434), partial_min(delinquency_90#435), partial_min(delinquency_180#436)])\n", + " : : : : : : : : : +- *(5) Project [quarter#692, loan_id#661L, current_loan_delinquency_status#671, CASE WHEN (current_loan_delinquency_status#671 >= 1) THEN cast(cast(unix_timestamp(monthly_reporting_period#662, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date) END AS delinquency_30#434, CASE WHEN (current_loan_delinquency_status#671 >= 3) THEN cast(cast(unix_timestamp(monthly_reporting_period#662, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date) END AS delinquency_90#435, CASE WHEN (current_loan_delinquency_status#671 >= 6) THEN cast(cast(unix_timestamp(monthly_reporting_period#662, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date) END AS delinquency_180#436]\n", + " : : : : : : : : : +- *(5) Filter (isnotnull(loan_id#661L) AND isnotnull(quarter#692))\n", + " : : : : : : : : : +- *(5) ColumnarToRow\n", + " : : : : : : : : : +- FileScan parquet [loan_id#661L,monthly_reporting_period#662,current_loan_delinquency_status#671,quarter#692] Batched: true, DataFilters: [isnotnull(loan_id#661L), isnotnull(quarter#692)], Format: Parquet, Location: InMemoryFileIndex[gs://dataproc-nv-demo/mortgage_parquet_cpu/perf], PartitionFilters: [], PushedFilters: [IsNotNull(loan_id), IsNotNull(quarter)], ReadSchema: struct\n", + " : : : : : : : : +- *(9) Sort [quarter#943 ASC NULLS FIRST, loan_id#912L ASC NULLS FIRST, timestamp_year#766L ASC NULLS FIRST, timestamp_month#795L ASC NULLS FIRST], false, 0\n", + " : : : : : : : : +- Exchange hashpartitioning(quarter#943, loan_id#912L, timestamp_year#766L, timestamp_month#795L, 160), true, [id=#264]\n", + " : : : : : : : : +- *(8) HashAggregate(keys=[quarter#943, loan_id#912L, josh_mody_n#723L, ever_30#463, ever_90#464, ever_180#465, delinquency_30#452, delinquency_90#454, delinquency_180#456, month_y#707], functions=[])\n", + " : : : : : : : : +- *(8) HashAggregate(keys=[quarter#943, loan_id#912L, josh_mody_n#723L, ever_30#463, ever_90#464, ever_180#465, delinquency_30#452, delinquency_90#454, delinquency_180#456, month_y#707], functions=[])\n", + " : : : : : : : : +- *(8) Project [quarter#943, FLOOR((cast(((((timestamp_year#546 * 12) + timestamp_month#510) - 24000) - month_y#707) as double) / 12.0)) AS josh_mody_n#723L, ever_30#463, ever_90#464, ever_180#465, delinquency_30#452, delinquency_90#454, delinquency_180#456, loan_id#912L, month_y#707]\n", + " : : : : : : : : +- *(8) Filter (isnotnull(CASE WHEN (pmod(((24000 + (FLOOR((cast(((((timestamp_year#546 * 12) + timestamp_month#510) - 24000) - month_y#707) as double) / 12.0)) * 12)) + cast(month_y#707 as bigint)), 12) = 0) THEN 12 ELSE pmod(((24000 + (FLOOR((cast(((((timestamp_year#546 * 12) + timestamp_month#510) - 24000) - month_y#707) as double) / 12.0)) * 12)) + cast(month_y#707 as bigint)), 12) END) AND isnotnull(FLOOR((cast(((24000 + (FLOOR((cast(((((timestamp_year#546 * 12) + timestamp_month#510) - 24000) - month_y#707) as double) / 12.0)) * 12)) + cast((month_y#707 - 1) as bigint)) as double) / 12.0))))\n", + " : : : : : : : : +- Generate explode([0,1,2,3,4,5,6,7,8,9,10,11]), [loan_id#912L, quarter#943, timestamp_month#510, timestamp_year#546, ever_30#463, ever_90#464, ever_180#465, delinquency_30#452, delinquency_90#454, delinquency_180#456], false, [month_y#707]\n", + " : : : : : : : : +- *(7) Project [loan_id#912L, quarter#943, timestamp_month#510, timestamp_year#546, ever_30#463, ever_90#464, ever_180#465, delinquency_30#452, delinquency_90#454, delinquency_180#456]\n", + " : : : : : : : : +- SortMergeJoin [quarter#943, loan_id#912L], [quarter#692, loan_id#661L], LeftOuter\n", + " : : : : : : : : :- *(4) Sort [quarter#943 ASC NULLS FIRST, loan_id#912L ASC NULLS FIRST], false, 0\n", + " : : : : : : : : : +- Exchange hashpartitioning(quarter#943, loan_id#912L, 160), true, [id=#238]\n", + " : : : : : : : : : +- *(3) Project [quarter#943, loan_id#912L, month(cast(cast(unix_timestamp(monthly_reporting_period#913, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date)) AS timestamp_month#510, year(cast(cast(unix_timestamp(monthly_reporting_period#913, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date)) AS timestamp_year#546]\n", + " : : : : : : : : : +- *(3) Filter ((NOT quarter#943 IN (2016Q1,2016Q2,2016Q3,2016Q4) AND isnotnull(quarter#943)) AND isnotnull(loan_id#912L))\n", + " : : : : : : : : : +- *(3) ColumnarToRow\n", + " : : : : : : : : : +- FileScan parquet [loan_id#912L,monthly_reporting_period#913,quarter#943] Batched: true, DataFilters: [NOT quarter#943 IN (2016Q1,2016Q2,2016Q3,2016Q4), isnotnull(quarter#943), isnotnull(loan_id#912L)], Format: Parquet, Location: InMemoryFileIndex[gs://dataproc-nv-demo/mortgage_parquet_cpu/perf], PartitionFilters: [], PushedFilters: [Not(In(quarter, [2016Q1,2016Q2,2016Q3,2016Q4])), IsNotNull(quarter), IsNotNull(loan_id)], ReadSchema: struct\n", + " : : : : : : : : +- *(6) Sort [quarter#692 ASC NULLS FIRST, loan_id#661L ASC NULLS FIRST], false, 0\n", + " : : : : : : : : +- *(6) HashAggregate(keys=[quarter#692, loan_id#661L], functions=[max(current_loan_delinquency_status#671), min(delinquency_30#434), min(delinquency_90#435), min(delinquency_180#436)])\n", + " : : : : : : : : +- Exchange hashpartitioning(quarter#692, loan_id#661L, 160), true, [id=#248]\n", + " : : : : : : : : +- *(5) HashAggregate(keys=[quarter#692, loan_id#661L], functions=[partial_max(current_loan_delinquency_status#671), partial_min(delinquency_30#434), partial_min(delinquency_90#435), partial_min(delinquency_180#436)])\n", + " : : : : : : : : +- *(5) Project [quarter#692, loan_id#661L, current_loan_delinquency_status#671, CASE WHEN (current_loan_delinquency_status#671 >= 1) THEN cast(cast(unix_timestamp(monthly_reporting_period#662, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date) END AS delinquency_30#434, CASE WHEN (current_loan_delinquency_status#671 >= 3) THEN cast(cast(unix_timestamp(monthly_reporting_period#662, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date) END AS delinquency_90#435, CASE WHEN (current_loan_delinquency_status#671 >= 6) THEN cast(cast(unix_timestamp(monthly_reporting_period#662, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date) END AS delinquency_180#436]\n", + " : : : : : : : : +- *(5) Filter (isnotnull(loan_id#661L) AND isnotnull(quarter#692))\n", + " : : : : : : : : +- *(5) ColumnarToRow\n", + " : : : : : : : : +- FileScan parquet [loan_id#661L,monthly_reporting_period#662,current_loan_delinquency_status#671,quarter#692] Batched: true, DataFilters: [isnotnull(loan_id#661L), isnotnull(quarter#692)], Format: Parquet, Location: InMemoryFileIndex[gs://dataproc-nv-demo/mortgage_parquet_cpu/perf], PartitionFilters: [], PushedFilters: [IsNotNull(loan_id), IsNotNull(quarter)], ReadSchema: struct\n", + " : : : : : : : +- *(9) Sort [quarter#943 ASC NULLS FIRST, loan_id#912L ASC NULLS FIRST, timestamp_year#766L ASC NULLS FIRST, timestamp_month#795L ASC NULLS FIRST], false, 0\n", + " : : : : : : : +- Exchange hashpartitioning(quarter#943, loan_id#912L, timestamp_year#766L, timestamp_month#795L, 160), true, [id=#264]\n", + " : : : : : : : +- *(8) HashAggregate(keys=[quarter#943, loan_id#912L, josh_mody_n#723L, ever_30#463, ever_90#464, ever_180#465, delinquency_30#452, delinquency_90#454, delinquency_180#456, month_y#707], functions=[])\n", + " : : : : : : : +- *(8) HashAggregate(keys=[quarter#943, loan_id#912L, josh_mody_n#723L, ever_30#463, ever_90#464, ever_180#465, delinquency_30#452, delinquency_90#454, delinquency_180#456, month_y#707], functions=[])\n", + " : : : : : : : +- *(8) Project [quarter#943, FLOOR((cast(((((timestamp_year#546 * 12) + timestamp_month#510) - 24000) - month_y#707) as double) / 12.0)) AS josh_mody_n#723L, ever_30#463, ever_90#464, ever_180#465, delinquency_30#452, delinquency_90#454, delinquency_180#456, loan_id#912L, month_y#707]\n", + " : : : : : : : +- *(8) Filter (isnotnull(CASE WHEN (pmod(((24000 + (FLOOR((cast(((((timestamp_year#546 * 12) + timestamp_month#510) - 24000) - month_y#707) as double) / 12.0)) * 12)) + cast(month_y#707 as bigint)), 12) = 0) THEN 12 ELSE pmod(((24000 + (FLOOR((cast(((((timestamp_year#546 * 12) + timestamp_month#510) - 24000) - month_y#707) as double) / 12.0)) * 12)) + cast(month_y#707 as bigint)), 12) END) AND isnotnull(FLOOR((cast(((24000 + (FLOOR((cast(((((timestamp_year#546 * 12) + timestamp_month#510) - 24000) - month_y#707) as double) / 12.0)) * 12)) + cast((month_y#707 - 1) as bigint)) as double) / 12.0))))\n", + " : : : : : : : +- Generate explode([0,1,2,3,4,5,6,7,8,9,10,11]), [loan_id#912L, quarter#943, timestamp_month#510, timestamp_year#546, ever_30#463, ever_90#464, ever_180#465, delinquency_30#452, delinquency_90#454, delinquency_180#456], false, [month_y#707]\n", + " : : : : : : : +- *(7) Project [loan_id#912L, quarter#943, timestamp_month#510, timestamp_year#546, ever_30#463, ever_90#464, ever_180#465, delinquency_30#452, delinquency_90#454, delinquency_180#456]\n", + " : : : : : : : +- SortMergeJoin [quarter#943, loan_id#912L], [quarter#692, loan_id#661L], LeftOuter\n", + " : : : : : : : :- *(4) Sort [quarter#943 ASC NULLS FIRST, loan_id#912L ASC NULLS FIRST], false, 0\n", + " : : : : : : : : +- Exchange hashpartitioning(quarter#943, loan_id#912L, 160), true, [id=#238]\n", + " : : : : : : : : +- *(3) Project [quarter#943, loan_id#912L, month(cast(cast(unix_timestamp(monthly_reporting_period#913, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date)) AS timestamp_month#510, year(cast(cast(unix_timestamp(monthly_reporting_period#913, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date)) AS timestamp_year#546]\n", + " : : : : : : : : +- *(3) Filter ((NOT quarter#943 IN (2016Q1,2016Q2,2016Q3,2016Q4) AND isnotnull(quarter#943)) AND isnotnull(loan_id#912L))\n", + " : : : : : : : : +- *(3) ColumnarToRow\n", + " : : : : : : : : +- FileScan parquet [loan_id#912L,monthly_reporting_period#913,quarter#943] Batched: true, DataFilters: [NOT quarter#943 IN (2016Q1,2016Q2,2016Q3,2016Q4), isnotnull(quarter#943), isnotnull(loan_id#912L)], Format: Parquet, Location: InMemoryFileIndex[gs://dataproc-nv-demo/mortgage_parquet_cpu/perf], PartitionFilters: [], PushedFilters: [Not(In(quarter, [2016Q1,2016Q2,2016Q3,2016Q4])), IsNotNull(quarter), IsNotNull(loan_id)], ReadSchema: struct\n", + " : : : : : : : +- *(6) Sort [quarter#692 ASC NULLS FIRST, loan_id#661L ASC NULLS FIRST], false, 0\n", + " : : : : : : : +- *(6) HashAggregate(keys=[quarter#692, loan_id#661L], functions=[max(current_loan_delinquency_status#671), min(delinquency_30#434), min(delinquency_90#435), min(delinquency_180#436)])\n", + " : : : : : : : +- Exchange hashpartitioning(quarter#692, loan_id#661L, 160), true, [id=#248]\n", + " : : : : : : : +- *(5) HashAggregate(keys=[quarter#692, loan_id#661L], functions=[partial_max(current_loan_delinquency_status#671), partial_min(delinquency_30#434), partial_min(delinquency_90#435), partial_min(delinquency_180#436)])\n", + " : : : : : : : +- *(5) Project [quarter#692, loan_id#661L, current_loan_delinquency_status#671, CASE WHEN (current_loan_delinquency_status#671 >= 1) THEN cast(cast(unix_timestamp(monthly_reporting_period#662, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date) END AS delinquency_30#434, CASE WHEN (current_loan_delinquency_status#671 >= 3) THEN cast(cast(unix_timestamp(monthly_reporting_period#662, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date) END AS delinquency_90#435, CASE WHEN (current_loan_delinquency_status#671 >= 6) THEN cast(cast(unix_timestamp(monthly_reporting_period#662, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date) END AS delinquency_180#436]\n", + " : : : : : : : +- *(5) Filter (isnotnull(loan_id#661L) AND isnotnull(quarter#692))\n", + " : : : : : : : +- *(5) ColumnarToRow\n", + " : : : : : : : +- FileScan parquet [loan_id#661L,monthly_reporting_period#662,current_loan_delinquency_status#671,quarter#692] Batched: true, DataFilters: [isnotnull(loan_id#661L), isnotnull(quarter#692)], Format: Parquet, Location: InMemoryFileIndex[gs://dataproc-nv-demo/mortgage_parquet_cpu/perf], PartitionFilters: [], PushedFilters: [IsNotNull(loan_id), IsNotNull(quarter)], ReadSchema: struct\n", + " : : : : : : +- *(9) Sort [quarter#943 ASC NULLS FIRST, loan_id#912L ASC NULLS FIRST, timestamp_year#766L ASC NULLS FIRST, timestamp_month#795L ASC NULLS FIRST], false, 0\n", + " : : : : : : +- Exchange hashpartitioning(quarter#943, loan_id#912L, timestamp_year#766L, timestamp_month#795L, 160), true, [id=#264]\n", + " : : : : : : +- *(8) HashAggregate(keys=[quarter#943, loan_id#912L, josh_mody_n#723L, ever_30#463, ever_90#464, ever_180#465, delinquency_30#452, delinquency_90#454, delinquency_180#456, month_y#707], functions=[])\n", + " : : : : : : +- *(8) HashAggregate(keys=[quarter#943, loan_id#912L, josh_mody_n#723L, ever_30#463, ever_90#464, ever_180#465, delinquency_30#452, delinquency_90#454, delinquency_180#456, month_y#707], functions=[])\n", + " : : : : : : +- *(8) Project [quarter#943, FLOOR((cast(((((timestamp_year#546 * 12) + timestamp_month#510) - 24000) - month_y#707) as double) / 12.0)) AS josh_mody_n#723L, ever_30#463, ever_90#464, ever_180#465, delinquency_30#452, delinquency_90#454, delinquency_180#456, loan_id#912L, month_y#707]\n", + " : : : : : : +- *(8) Filter (isnotnull(CASE WHEN (pmod(((24000 + (FLOOR((cast(((((timestamp_year#546 * 12) + timestamp_month#510) - 24000) - month_y#707) as double) / 12.0)) * 12)) + cast(month_y#707 as bigint)), 12) = 0) THEN 12 ELSE pmod(((24000 + (FLOOR((cast(((((timestamp_year#546 * 12) + timestamp_month#510) - 24000) - month_y#707) as double) / 12.0)) * 12)) + cast(month_y#707 as bigint)), 12) END) AND isnotnull(FLOOR((cast(((24000 + (FLOOR((cast(((((timestamp_year#546 * 12) + timestamp_month#510) - 24000) - month_y#707) as double) / 12.0)) * 12)) + cast((month_y#707 - 1) as bigint)) as double) / 12.0))))\n", + " : : : : : : +- Generate explode([0,1,2,3,4,5,6,7,8,9,10,11]), [loan_id#912L, quarter#943, timestamp_month#510, timestamp_year#546, ever_30#463, ever_90#464, ever_180#465, delinquency_30#452, delinquency_90#454, delinquency_180#456], false, [month_y#707]\n", + " : : : : : : +- *(7) Project [loan_id#912L, quarter#943, timestamp_month#510, timestamp_year#546, ever_30#463, ever_90#464, ever_180#465, delinquency_30#452, delinquency_90#454, delinquency_180#456]\n", + " : : : : : : +- SortMergeJoin [quarter#943, loan_id#912L], [quarter#692, loan_id#661L], LeftOuter\n", + " : : : : : : :- *(4) Sort [quarter#943 ASC NULLS FIRST, loan_id#912L ASC NULLS FIRST], false, 0\n", + " : : : : : : : +- Exchange hashpartitioning(quarter#943, loan_id#912L, 160), true, [id=#238]\n", + " : : : : : : : +- *(3) Project [quarter#943, loan_id#912L, month(cast(cast(unix_timestamp(monthly_reporting_period#913, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date)) AS timestamp_month#510, year(cast(cast(unix_timestamp(monthly_reporting_period#913, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date)) AS timestamp_year#546]\n", + " : : : : : : : +- *(3) Filter ((NOT quarter#943 IN (2016Q1,2016Q2,2016Q3,2016Q4) AND isnotnull(quarter#943)) AND isnotnull(loan_id#912L))\n", + " : : : : : : : +- *(3) ColumnarToRow\n", + " : : : : : : : +- FileScan parquet [loan_id#912L,monthly_reporting_period#913,quarter#943] Batched: true, DataFilters: [NOT quarter#943 IN (2016Q1,2016Q2,2016Q3,2016Q4), isnotnull(quarter#943), isnotnull(loan_id#912L)], Format: Parquet, Location: InMemoryFileIndex[gs://dataproc-nv-demo/mortgage_parquet_cpu/perf], PartitionFilters: [], PushedFilters: [Not(In(quarter, [2016Q1,2016Q2,2016Q3,2016Q4])), IsNotNull(quarter), IsNotNull(loan_id)], ReadSchema: struct\n", + " : : : : : : +- *(6) Sort [quarter#692 ASC NULLS FIRST, loan_id#661L ASC NULLS FIRST], false, 0\n", + " : : : : : : +- *(6) HashAggregate(keys=[quarter#692, loan_id#661L], functions=[max(current_loan_delinquency_status#671), min(delinquency_30#434), min(delinquency_90#435), min(delinquency_180#436)])\n", + " : : : : : : +- Exchange hashpartitioning(quarter#692, loan_id#661L, 160), true, [id=#248]\n", + " : : : : : : +- *(5) HashAggregate(keys=[quarter#692, loan_id#661L], functions=[partial_max(current_loan_delinquency_status#671), partial_min(delinquency_30#434), partial_min(delinquency_90#435), partial_min(delinquency_180#436)])\n", + " : : : : : : +- *(5) Project [quarter#692, loan_id#661L, current_loan_delinquency_status#671, CASE WHEN (current_loan_delinquency_status#671 >= 1) THEN cast(cast(unix_timestamp(monthly_reporting_period#662, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date) END AS delinquency_30#434, CASE WHEN (current_loan_delinquency_status#671 >= 3) THEN cast(cast(unix_timestamp(monthly_reporting_period#662, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date) END AS delinquency_90#435, CASE WHEN (current_loan_delinquency_status#671 >= 6) THEN cast(cast(unix_timestamp(monthly_reporting_period#662, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date) END AS delinquency_180#436]\n", + " : : : : : : +- *(5) Filter (isnotnull(loan_id#661L) AND isnotnull(quarter#692))\n", + " : : : : : : +- *(5) ColumnarToRow\n", + " : : : : : : +- FileScan parquet [loan_id#661L,monthly_reporting_period#662,current_loan_delinquency_status#671,quarter#692] Batched: true, DataFilters: [isnotnull(loan_id#661L), isnotnull(quarter#692)], Format: Parquet, Location: InMemoryFileIndex[gs://dataproc-nv-demo/mortgage_parquet_cpu/perf], PartitionFilters: [], PushedFilters: [IsNotNull(loan_id), IsNotNull(quarter)], ReadSchema: struct\n", + " : : : : : +- *(9) Sort [quarter#943 ASC NULLS FIRST, loan_id#912L ASC NULLS FIRST, timestamp_year#766L ASC NULLS FIRST, timestamp_month#795L ASC NULLS FIRST], false, 0\n", + " : : : : : +- Exchange hashpartitioning(quarter#943, loan_id#912L, timestamp_year#766L, timestamp_month#795L, 160), true, [id=#264]\n", + " : : : : : +- *(8) HashAggregate(keys=[quarter#943, loan_id#912L, josh_mody_n#723L, ever_30#463, ever_90#464, ever_180#465, delinquency_30#452, delinquency_90#454, delinquency_180#456, month_y#707], functions=[])\n", + " : : : : : +- *(8) HashAggregate(keys=[quarter#943, loan_id#912L, josh_mody_n#723L, ever_30#463, ever_90#464, ever_180#465, delinquency_30#452, delinquency_90#454, delinquency_180#456, month_y#707], functions=[])\n", + " : : : : : +- *(8) Project [quarter#943, FLOOR((cast(((((timestamp_year#546 * 12) + timestamp_month#510) - 24000) - month_y#707) as double) / 12.0)) AS josh_mody_n#723L, ever_30#463, ever_90#464, ever_180#465, delinquency_30#452, delinquency_90#454, delinquency_180#456, loan_id#912L, month_y#707]\n", + " : : : : : +- *(8) Filter (isnotnull(CASE WHEN (pmod(((24000 + (FLOOR((cast(((((timestamp_year#546 * 12) + timestamp_month#510) - 24000) - month_y#707) as double) / 12.0)) * 12)) + cast(month_y#707 as bigint)), 12) = 0) THEN 12 ELSE pmod(((24000 + (FLOOR((cast(((((timestamp_year#546 * 12) + timestamp_month#510) - 24000) - month_y#707) as double) / 12.0)) * 12)) + cast(month_y#707 as bigint)), 12) END) AND isnotnull(FLOOR((cast(((24000 + (FLOOR((cast(((((timestamp_year#546 * 12) + timestamp_month#510) - 24000) - month_y#707) as double) / 12.0)) * 12)) + cast((month_y#707 - 1) as bigint)) as double) / 12.0))))\n", + " : : : : : +- Generate explode([0,1,2,3,4,5,6,7,8,9,10,11]), [loan_id#912L, quarter#943, timestamp_month#510, timestamp_year#546, ever_30#463, ever_90#464, ever_180#465, delinquency_30#452, delinquency_90#454, delinquency_180#456], false, [month_y#707]\n", + " : : : : : +- *(7) Project [loan_id#912L, quarter#943, timestamp_month#510, timestamp_year#546, ever_30#463, ever_90#464, ever_180#465, delinquency_30#452, delinquency_90#454, delinquency_180#456]\n", + " : : : : : +- SortMergeJoin [quarter#943, loan_id#912L], [quarter#692, loan_id#661L], LeftOuter\n", + " : : : : : :- *(4) Sort [quarter#943 ASC NULLS FIRST, loan_id#912L ASC NULLS FIRST], false, 0\n", + " : : : : : : +- Exchange hashpartitioning(quarter#943, loan_id#912L, 160), true, [id=#238]\n", + " : : : : : : +- *(3) Project [quarter#943, loan_id#912L, month(cast(cast(unix_timestamp(monthly_reporting_period#913, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date)) AS timestamp_month#510, year(cast(cast(unix_timestamp(monthly_reporting_period#913, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date)) AS timestamp_year#546]\n", + " : : : : : : +- *(3) Filter ((NOT quarter#943 IN (2016Q1,2016Q2,2016Q3,2016Q4) AND isnotnull(quarter#943)) AND isnotnull(loan_id#912L))\n", + " : : : : : : +- *(3) ColumnarToRow\n", + " : : : : : : +- FileScan parquet [loan_id#912L,monthly_reporting_period#913,quarter#943] Batched: true, DataFilters: [NOT quarter#943 IN (2016Q1,2016Q2,2016Q3,2016Q4), isnotnull(quarter#943), isnotnull(loan_id#912L)], Format: Parquet, Location: InMemoryFileIndex[gs://dataproc-nv-demo/mortgage_parquet_cpu/perf], PartitionFilters: [], PushedFilters: [Not(In(quarter, [2016Q1,2016Q2,2016Q3,2016Q4])), IsNotNull(quarter), IsNotNull(loan_id)], ReadSchema: struct\n", + " : : : : : +- *(6) Sort [quarter#692 ASC NULLS FIRST, loan_id#661L ASC NULLS FIRST], false, 0\n", + " : : : : : +- *(6) HashAggregate(keys=[quarter#692, loan_id#661L], functions=[max(current_loan_delinquency_status#671), min(delinquency_30#434), min(delinquency_90#435), min(delinquency_180#436)])\n", + " : : : : : +- Exchange hashpartitioning(quarter#692, loan_id#661L, 160), true, [id=#248]\n", + " : : : : : +- *(5) HashAggregate(keys=[quarter#692, loan_id#661L], functions=[partial_max(current_loan_delinquency_status#671), partial_min(delinquency_30#434), partial_min(delinquency_90#435), partial_min(delinquency_180#436)])\n", + " : : : : : +- *(5) Project [quarter#692, loan_id#661L, current_loan_delinquency_status#671, CASE WHEN (current_loan_delinquency_status#671 >= 1) THEN cast(cast(unix_timestamp(monthly_reporting_period#662, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date) END AS delinquency_30#434, CASE WHEN (current_loan_delinquency_status#671 >= 3) THEN cast(cast(unix_timestamp(monthly_reporting_period#662, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date) END AS delinquency_90#435, CASE WHEN (current_loan_delinquency_status#671 >= 6) THEN cast(cast(unix_timestamp(monthly_reporting_period#662, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date) END AS delinquency_180#436]\n", + " : : : : : +- *(5) Filter (isnotnull(loan_id#661L) AND isnotnull(quarter#692))\n", + " : : : : : +- *(5) ColumnarToRow\n", + " : : : : : +- FileScan parquet [loan_id#661L,monthly_reporting_period#662,current_loan_delinquency_status#671,quarter#692] Batched: true, DataFilters: [isnotnull(loan_id#661L), isnotnull(quarter#692)], Format: Parquet, Location: InMemoryFileIndex[gs://dataproc-nv-demo/mortgage_parquet_cpu/perf], PartitionFilters: [], PushedFilters: [IsNotNull(loan_id), IsNotNull(quarter)], ReadSchema: struct\n", + " : : : : +- *(9) Sort [quarter#943 ASC NULLS FIRST, loan_id#912L ASC NULLS FIRST, timestamp_year#766L ASC NULLS FIRST, timestamp_month#795L ASC NULLS FIRST], false, 0\n", + " : : : : +- Exchange hashpartitioning(quarter#943, loan_id#912L, timestamp_year#766L, timestamp_month#795L, 160), true, [id=#264]\n", + " : : : : +- *(8) HashAggregate(keys=[quarter#943, loan_id#912L, josh_mody_n#723L, ever_30#463, ever_90#464, ever_180#465, delinquency_30#452, delinquency_90#454, delinquency_180#456, month_y#707], functions=[])\n", + " : : : : +- *(8) HashAggregate(keys=[quarter#943, loan_id#912L, josh_mody_n#723L, ever_30#463, ever_90#464, ever_180#465, delinquency_30#452, delinquency_90#454, delinquency_180#456, month_y#707], functions=[])\n", + " : : : : +- *(8) Project [quarter#943, FLOOR((cast(((((timestamp_year#546 * 12) + timestamp_month#510) - 24000) - month_y#707) as double) / 12.0)) AS josh_mody_n#723L, ever_30#463, ever_90#464, ever_180#465, delinquency_30#452, delinquency_90#454, delinquency_180#456, loan_id#912L, month_y#707]\n", + " : : : : +- *(8) Filter (isnotnull(CASE WHEN (pmod(((24000 + (FLOOR((cast(((((timestamp_year#546 * 12) + timestamp_month#510) - 24000) - month_y#707) as double) / 12.0)) * 12)) + cast(month_y#707 as bigint)), 12) = 0) THEN 12 ELSE pmod(((24000 + (FLOOR((cast(((((timestamp_year#546 * 12) + timestamp_month#510) - 24000) - month_y#707) as double) / 12.0)) * 12)) + cast(month_y#707 as bigint)), 12) END) AND isnotnull(FLOOR((cast(((24000 + (FLOOR((cast(((((timestamp_year#546 * 12) + timestamp_month#510) - 24000) - month_y#707) as double) / 12.0)) * 12)) + cast((month_y#707 - 1) as bigint)) as double) / 12.0))))\n", + " : : : : +- Generate explode([0,1,2,3,4,5,6,7,8,9,10,11]), [loan_id#912L, quarter#943, timestamp_month#510, timestamp_year#546, ever_30#463, ever_90#464, ever_180#465, delinquency_30#452, delinquency_90#454, delinquency_180#456], false, [month_y#707]\n", + " : : : : +- *(7) Project [loan_id#912L, quarter#943, timestamp_month#510, timestamp_year#546, ever_30#463, ever_90#464, ever_180#465, delinquency_30#452, delinquency_90#454, delinquency_180#456]\n", + " : : : : +- SortMergeJoin [quarter#943, loan_id#912L], [quarter#692, loan_id#661L], LeftOuter\n", + " : : : : :- *(4) Sort [quarter#943 ASC NULLS FIRST, loan_id#912L ASC NULLS FIRST], false, 0\n", + " : : : : : +- Exchange hashpartitioning(quarter#943, loan_id#912L, 160), true, [id=#238]\n", + " : : : : : +- *(3) Project [quarter#943, loan_id#912L, month(cast(cast(unix_timestamp(monthly_reporting_period#913, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date)) AS timestamp_month#510, year(cast(cast(unix_timestamp(monthly_reporting_period#913, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date)) AS timestamp_year#546]\n", + " : : : : : +- *(3) Filter ((NOT quarter#943 IN (2016Q1,2016Q2,2016Q3,2016Q4) AND isnotnull(quarter#943)) AND isnotnull(loan_id#912L))\n", + " : : : : : +- *(3) ColumnarToRow\n", + " : : : : : +- FileScan parquet [loan_id#912L,monthly_reporting_period#913,quarter#943] Batched: true, DataFilters: [NOT quarter#943 IN (2016Q1,2016Q2,2016Q3,2016Q4), isnotnull(quarter#943), isnotnull(loan_id#912L)], Format: Parquet, Location: InMemoryFileIndex[gs://dataproc-nv-demo/mortgage_parquet_cpu/perf], PartitionFilters: [], PushedFilters: [Not(In(quarter, [2016Q1,2016Q2,2016Q3,2016Q4])), IsNotNull(quarter), IsNotNull(loan_id)], ReadSchema: struct\n", + " : : : : +- *(6) Sort [quarter#692 ASC NULLS FIRST, loan_id#661L ASC NULLS FIRST], false, 0\n", + " : : : : +- *(6) HashAggregate(keys=[quarter#692, loan_id#661L], functions=[max(current_loan_delinquency_status#671), min(delinquency_30#434), min(delinquency_90#435), min(delinquency_180#436)])\n", + " : : : : +- Exchange hashpartitioning(quarter#692, loan_id#661L, 160), true, [id=#248]\n", + " : : : : +- *(5) HashAggregate(keys=[quarter#692, loan_id#661L], functions=[partial_max(current_loan_delinquency_status#671), partial_min(delinquency_30#434), partial_min(delinquency_90#435), partial_min(delinquency_180#436)])\n", + " : : : : +- *(5) Project [quarter#692, loan_id#661L, current_loan_delinquency_status#671, CASE WHEN (current_loan_delinquency_status#671 >= 1) THEN cast(cast(unix_timestamp(monthly_reporting_period#662, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date) END AS delinquency_30#434, CASE WHEN (current_loan_delinquency_status#671 >= 3) THEN cast(cast(unix_timestamp(monthly_reporting_period#662, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date) END AS delinquency_90#435, CASE WHEN (current_loan_delinquency_status#671 >= 6) THEN cast(cast(unix_timestamp(monthly_reporting_period#662, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date) END AS delinquency_180#436]\n", + " : : : : +- *(5) Filter (isnotnull(loan_id#661L) AND isnotnull(quarter#692))\n", + " : : : : +- *(5) ColumnarToRow\n", + " : : : : +- FileScan parquet [loan_id#661L,monthly_reporting_period#662,current_loan_delinquency_status#671,quarter#692] Batched: true, DataFilters: [isnotnull(loan_id#661L), isnotnull(quarter#692)], Format: Parquet, Location: InMemoryFileIndex[gs://dataproc-nv-demo/mortgage_parquet_cpu/perf], PartitionFilters: [], PushedFilters: [IsNotNull(loan_id), IsNotNull(quarter)], ReadSchema: struct\n", + " : : : +- *(9) Sort [quarter#943 ASC NULLS FIRST, loan_id#912L ASC NULLS FIRST, timestamp_year#766L ASC NULLS FIRST, timestamp_month#795L ASC NULLS FIRST], false, 0\n", + " : : : +- Exchange hashpartitioning(quarter#943, loan_id#912L, timestamp_year#766L, timestamp_month#795L, 160), true, [id=#264]\n", + " : : : +- *(8) HashAggregate(keys=[quarter#943, loan_id#912L, josh_mody_n#723L, ever_30#463, ever_90#464, ever_180#465, delinquency_30#452, delinquency_90#454, delinquency_180#456, month_y#707], functions=[])\n", + " : : : +- *(8) HashAggregate(keys=[quarter#943, loan_id#912L, josh_mody_n#723L, ever_30#463, ever_90#464, ever_180#465, delinquency_30#452, delinquency_90#454, delinquency_180#456, month_y#707], functions=[])\n", + " : : : +- *(8) Project [quarter#943, FLOOR((cast(((((timestamp_year#546 * 12) + timestamp_month#510) - 24000) - month_y#707) as double) / 12.0)) AS josh_mody_n#723L, ever_30#463, ever_90#464, ever_180#465, delinquency_30#452, delinquency_90#454, delinquency_180#456, loan_id#912L, month_y#707]\n", + " : : : +- *(8) Filter (isnotnull(CASE WHEN (pmod(((24000 + (FLOOR((cast(((((timestamp_year#546 * 12) + timestamp_month#510) - 24000) - month_y#707) as double) / 12.0)) * 12)) + cast(month_y#707 as bigint)), 12) = 0) THEN 12 ELSE pmod(((24000 + (FLOOR((cast(((((timestamp_year#546 * 12) + timestamp_month#510) - 24000) - month_y#707) as double) / 12.0)) * 12)) + cast(month_y#707 as bigint)), 12) END) AND isnotnull(FLOOR((cast(((24000 + (FLOOR((cast(((((timestamp_year#546 * 12) + timestamp_month#510) - 24000) - month_y#707) as double) / 12.0)) * 12)) + cast((month_y#707 - 1) as bigint)) as double) / 12.0))))\n", + " : : : +- Generate explode([0,1,2,3,4,5,6,7,8,9,10,11]), [loan_id#912L, quarter#943, timestamp_month#510, timestamp_year#546, ever_30#463, ever_90#464, ever_180#465, delinquency_30#452, delinquency_90#454, delinquency_180#456], false, [month_y#707]\n", + " : : : +- *(7) Project [loan_id#912L, quarter#943, timestamp_month#510, timestamp_year#546, ever_30#463, ever_90#464, ever_180#465, delinquency_30#452, delinquency_90#454, delinquency_180#456]\n", + " : : : +- SortMergeJoin [quarter#943, loan_id#912L], [quarter#692, loan_id#661L], LeftOuter\n", + " : : : :- *(4) Sort [quarter#943 ASC NULLS FIRST, loan_id#912L ASC NULLS FIRST], false, 0\n", + " : : : : +- Exchange hashpartitioning(quarter#943, loan_id#912L, 160), true, [id=#238]\n", + " : : : : +- *(3) Project [quarter#943, loan_id#912L, month(cast(cast(unix_timestamp(monthly_reporting_period#913, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date)) AS timestamp_month#510, year(cast(cast(unix_timestamp(monthly_reporting_period#913, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date)) AS timestamp_year#546]\n", + " : : : : +- *(3) Filter ((NOT quarter#943 IN (2016Q1,2016Q2,2016Q3,2016Q4) AND isnotnull(quarter#943)) AND isnotnull(loan_id#912L))\n", + " : : : : +- *(3) ColumnarToRow\n", + " : : : : +- FileScan parquet [loan_id#912L,monthly_reporting_period#913,quarter#943] Batched: true, DataFilters: [NOT quarter#943 IN (2016Q1,2016Q2,2016Q3,2016Q4), isnotnull(quarter#943), isnotnull(loan_id#912L)], Format: Parquet, Location: InMemoryFileIndex[gs://dataproc-nv-demo/mortgage_parquet_cpu/perf], PartitionFilters: [], PushedFilters: [Not(In(quarter, [2016Q1,2016Q2,2016Q3,2016Q4])), IsNotNull(quarter), IsNotNull(loan_id)], ReadSchema: struct\n", + " : : : +- *(6) Sort [quarter#692 ASC NULLS FIRST, loan_id#661L ASC NULLS FIRST], false, 0\n", + " : : : +- *(6) HashAggregate(keys=[quarter#692, loan_id#661L], functions=[max(current_loan_delinquency_status#671), min(delinquency_30#434), min(delinquency_90#435), min(delinquency_180#436)])\n", + " : : : +- Exchange hashpartitioning(quarter#692, loan_id#661L, 160), true, [id=#248]\n", + " : : : +- *(5) HashAggregate(keys=[quarter#692, loan_id#661L], functions=[partial_max(current_loan_delinquency_status#671), partial_min(delinquency_30#434), partial_min(delinquency_90#435), partial_min(delinquency_180#436)])\n", + " : : : +- *(5) Project [quarter#692, loan_id#661L, current_loan_delinquency_status#671, CASE WHEN (current_loan_delinquency_status#671 >= 1) THEN cast(cast(unix_timestamp(monthly_reporting_period#662, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date) END AS delinquency_30#434, CASE WHEN (current_loan_delinquency_status#671 >= 3) THEN cast(cast(unix_timestamp(monthly_reporting_period#662, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date) END AS delinquency_90#435, CASE WHEN (current_loan_delinquency_status#671 >= 6) THEN cast(cast(unix_timestamp(monthly_reporting_period#662, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date) END AS delinquency_180#436]\n", + " : : : +- *(5) Filter (isnotnull(loan_id#661L) AND isnotnull(quarter#692))\n", + " : : : +- *(5) ColumnarToRow\n", + " : : : +- FileScan parquet [loan_id#661L,monthly_reporting_period#662,current_loan_delinquency_status#671,quarter#692] Batched: true, DataFilters: [isnotnull(loan_id#661L), isnotnull(quarter#692)], Format: Parquet, Location: InMemoryFileIndex[gs://dataproc-nv-demo/mortgage_parquet_cpu/perf], PartitionFilters: [], PushedFilters: [IsNotNull(loan_id), IsNotNull(quarter)], ReadSchema: struct\n", + " : : +- *(9) Sort [quarter#943 ASC NULLS FIRST, loan_id#912L ASC NULLS FIRST, timestamp_year#766L ASC NULLS FIRST, timestamp_month#795L ASC NULLS FIRST], false, 0\n", + " : : +- Exchange hashpartitioning(quarter#943, loan_id#912L, timestamp_year#766L, timestamp_month#795L, 160), true, [id=#264]\n", + " : : +- *(8) HashAggregate(keys=[quarter#943, loan_id#912L, josh_mody_n#723L, ever_30#463, ever_90#464, ever_180#465, delinquency_30#452, delinquency_90#454, delinquency_180#456, month_y#707], functions=[])\n", + " : : +- *(8) HashAggregate(keys=[quarter#943, loan_id#912L, josh_mody_n#723L, ever_30#463, ever_90#464, ever_180#465, delinquency_30#452, delinquency_90#454, delinquency_180#456, month_y#707], functions=[])\n", + " : : +- *(8) Project [quarter#943, FLOOR((cast(((((timestamp_year#546 * 12) + timestamp_month#510) - 24000) - month_y#707) as double) / 12.0)) AS josh_mody_n#723L, ever_30#463, ever_90#464, ever_180#465, delinquency_30#452, delinquency_90#454, delinquency_180#456, loan_id#912L, month_y#707]\n", + " : : +- *(8) Filter (isnotnull(CASE WHEN (pmod(((24000 + (FLOOR((cast(((((timestamp_year#546 * 12) + timestamp_month#510) - 24000) - month_y#707) as double) / 12.0)) * 12)) + cast(month_y#707 as bigint)), 12) = 0) THEN 12 ELSE pmod(((24000 + (FLOOR((cast(((((timestamp_year#546 * 12) + timestamp_month#510) - 24000) - month_y#707) as double) / 12.0)) * 12)) + cast(month_y#707 as bigint)), 12) END) AND isnotnull(FLOOR((cast(((24000 + (FLOOR((cast(((((timestamp_year#546 * 12) + timestamp_month#510) - 24000) - month_y#707) as double) / 12.0)) * 12)) + cast((month_y#707 - 1) as bigint)) as double) / 12.0))))\n", + " : : +- Generate explode([0,1,2,3,4,5,6,7,8,9,10,11]), [loan_id#912L, quarter#943, timestamp_month#510, timestamp_year#546, ever_30#463, ever_90#464, ever_180#465, delinquency_30#452, delinquency_90#454, delinquency_180#456], false, [month_y#707]\n", + " : : +- *(7) Project [loan_id#912L, quarter#943, timestamp_month#510, timestamp_year#546, ever_30#463, ever_90#464, ever_180#465, delinquency_30#452, delinquency_90#454, delinquency_180#456]\n", + " : : +- SortMergeJoin [quarter#943, loan_id#912L], [quarter#692, loan_id#661L], LeftOuter\n", + " : : :- *(4) Sort [quarter#943 ASC NULLS FIRST, loan_id#912L ASC NULLS FIRST], false, 0\n", + " : : : +- Exchange hashpartitioning(quarter#943, loan_id#912L, 160), true, [id=#238]\n", + " : : : +- *(3) Project [quarter#943, loan_id#912L, month(cast(cast(unix_timestamp(monthly_reporting_period#913, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date)) AS timestamp_month#510, year(cast(cast(unix_timestamp(monthly_reporting_period#913, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date)) AS timestamp_year#546]\n", + " : : : +- *(3) Filter ((NOT quarter#943 IN (2016Q1,2016Q2,2016Q3,2016Q4) AND isnotnull(quarter#943)) AND isnotnull(loan_id#912L))\n", + " : : : +- *(3) ColumnarToRow\n", + " : : : +- FileScan parquet [loan_id#912L,monthly_reporting_period#913,quarter#943] Batched: true, DataFilters: [NOT quarter#943 IN (2016Q1,2016Q2,2016Q3,2016Q4), isnotnull(quarter#943), isnotnull(loan_id#912L)], Format: Parquet, Location: InMemoryFileIndex[gs://dataproc-nv-demo/mortgage_parquet_cpu/perf], PartitionFilters: [], PushedFilters: [Not(In(quarter, [2016Q1,2016Q2,2016Q3,2016Q4])), IsNotNull(quarter), IsNotNull(loan_id)], ReadSchema: struct\n", + " : : +- *(6) Sort [quarter#692 ASC NULLS FIRST, loan_id#661L ASC NULLS FIRST], false, 0\n", + " : : +- *(6) HashAggregate(keys=[quarter#692, loan_id#661L], functions=[max(current_loan_delinquency_status#671), min(delinquency_30#434), min(delinquency_90#435), min(delinquency_180#436)])\n", + " : : +- Exchange hashpartitioning(quarter#692, loan_id#661L, 160), true, [id=#248]\n", + " : : +- *(5) HashAggregate(keys=[quarter#692, loan_id#661L], functions=[partial_max(current_loan_delinquency_status#671), partial_min(delinquency_30#434), partial_min(delinquency_90#435), partial_min(delinquency_180#436)])\n", + " : : +- *(5) Project [quarter#692, loan_id#661L, current_loan_delinquency_status#671, CASE WHEN (current_loan_delinquency_status#671 >= 1) THEN cast(cast(unix_timestamp(monthly_reporting_period#662, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date) END AS delinquency_30#434, CASE WHEN (current_loan_delinquency_status#671 >= 3) THEN cast(cast(unix_timestamp(monthly_reporting_period#662, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date) END AS delinquency_90#435, CASE WHEN (current_loan_delinquency_status#671 >= 6) THEN cast(cast(unix_timestamp(monthly_reporting_period#662, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date) END AS delinquency_180#436]\n", + " : : +- *(5) Filter (isnotnull(loan_id#661L) AND isnotnull(quarter#692))\n", + " : : +- *(5) ColumnarToRow\n", + " : : +- FileScan parquet [loan_id#661L,monthly_reporting_period#662,current_loan_delinquency_status#671,quarter#692] Batched: true, DataFilters: [isnotnull(loan_id#661L), isnotnull(quarter#692)], Format: Parquet, Location: InMemoryFileIndex[gs://dataproc-nv-demo/mortgage_parquet_cpu/perf], PartitionFilters: [], PushedFilters: [IsNotNull(loan_id), IsNotNull(quarter)], ReadSchema: struct\n", + " : +- *(9) Sort [quarter#943 ASC NULLS FIRST, loan_id#912L ASC NULLS FIRST, timestamp_year#766L ASC NULLS FIRST, timestamp_month#795L ASC NULLS FIRST], false, 0\n", + " : +- Exchange hashpartitioning(quarter#943, loan_id#912L, timestamp_year#766L, timestamp_month#795L, 160), true, [id=#264]\n", + " : +- *(8) HashAggregate(keys=[quarter#943, loan_id#912L, josh_mody_n#723L, ever_30#463, ever_90#464, ever_180#465, delinquency_30#452, delinquency_90#454, delinquency_180#456, month_y#707], functions=[])\n", + " : +- *(8) HashAggregate(keys=[quarter#943, loan_id#912L, josh_mody_n#723L, ever_30#463, ever_90#464, ever_180#465, delinquency_30#452, delinquency_90#454, delinquency_180#456, month_y#707], functions=[])\n", + " : +- *(8) Project [quarter#943, FLOOR((cast(((((timestamp_year#546 * 12) + timestamp_month#510) - 24000) - month_y#707) as double) / 12.0)) AS josh_mody_n#723L, ever_30#463, ever_90#464, ever_180#465, delinquency_30#452, delinquency_90#454, delinquency_180#456, loan_id#912L, month_y#707]\n", + " : +- *(8) Filter (isnotnull(CASE WHEN (pmod(((24000 + (FLOOR((cast(((((timestamp_year#546 * 12) + timestamp_month#510) - 24000) - month_y#707) as double) / 12.0)) * 12)) + cast(month_y#707 as bigint)), 12) = 0) THEN 12 ELSE pmod(((24000 + (FLOOR((cast(((((timestamp_year#546 * 12) + timestamp_month#510) - 24000) - month_y#707) as double) / 12.0)) * 12)) + cast(month_y#707 as bigint)), 12) END) AND isnotnull(FLOOR((cast(((24000 + (FLOOR((cast(((((timestamp_year#546 * 12) + timestamp_month#510) - 24000) - month_y#707) as double) / 12.0)) * 12)) + cast((month_y#707 - 1) as bigint)) as double) / 12.0))))\n", + " : +- Generate explode([0,1,2,3,4,5,6,7,8,9,10,11]), [loan_id#912L, quarter#943, timestamp_month#510, timestamp_year#546, ever_30#463, ever_90#464, ever_180#465, delinquency_30#452, delinquency_90#454, delinquency_180#456], false, [month_y#707]\n", + " : +- *(7) Project [loan_id#912L, quarter#943, timestamp_month#510, timestamp_year#546, ever_30#463, ever_90#464, ever_180#465, delinquency_30#452, delinquency_90#454, delinquency_180#456]\n", + " : +- SortMergeJoin [quarter#943, loan_id#912L], [quarter#692, loan_id#661L], LeftOuter\n", + " : :- *(4) Sort [quarter#943 ASC NULLS FIRST, loan_id#912L ASC NULLS FIRST], false, 0\n", + " : : +- Exchange hashpartitioning(quarter#943, loan_id#912L, 160), true, [id=#238]\n", + " : : +- *(3) Project [quarter#943, loan_id#912L, month(cast(cast(unix_timestamp(monthly_reporting_period#913, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date)) AS timestamp_month#510, year(cast(cast(unix_timestamp(monthly_reporting_period#913, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date)) AS timestamp_year#546]\n", + " : : +- *(3) Filter ((NOT quarter#943 IN (2016Q1,2016Q2,2016Q3,2016Q4) AND isnotnull(quarter#943)) AND isnotnull(loan_id#912L))\n", + " : : +- *(3) ColumnarToRow\n", + " : : +- FileScan parquet [loan_id#912L,monthly_reporting_period#913,quarter#943] Batched: true, DataFilters: [NOT quarter#943 IN (2016Q1,2016Q2,2016Q3,2016Q4), isnotnull(quarter#943), isnotnull(loan_id#912L)], Format: Parquet, Location: InMemoryFileIndex[gs://dataproc-nv-demo/mortgage_parquet_cpu/perf], PartitionFilters: [], PushedFilters: [Not(In(quarter, [2016Q1,2016Q2,2016Q3,2016Q4])), IsNotNull(quarter), IsNotNull(loan_id)], ReadSchema: struct\n", + " : +- *(6) Sort [quarter#692 ASC NULLS FIRST, loan_id#661L ASC NULLS FIRST], false, 0\n", + " : +- *(6) HashAggregate(keys=[quarter#692, loan_id#661L], functions=[max(current_loan_delinquency_status#671), min(delinquency_30#434), min(delinquency_90#435), min(delinquency_180#436)])\n", + " : +- Exchange hashpartitioning(quarter#692, loan_id#661L, 160), true, [id=#248]\n", + " : +- *(5) HashAggregate(keys=[quarter#692, loan_id#661L], functions=[partial_max(current_loan_delinquency_status#671), partial_min(delinquency_30#434), partial_min(delinquency_90#435), partial_min(delinquency_180#436)])\n", + " : +- *(5) Project [quarter#692, loan_id#661L, current_loan_delinquency_status#671, CASE WHEN (current_loan_delinquency_status#671 >= 1) THEN cast(cast(unix_timestamp(monthly_reporting_period#662, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date) END AS delinquency_30#434, CASE WHEN (current_loan_delinquency_status#671 >= 3) THEN cast(cast(unix_timestamp(monthly_reporting_period#662, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date) END AS delinquency_90#435, CASE WHEN (current_loan_delinquency_status#671 >= 6) THEN cast(cast(unix_timestamp(monthly_reporting_period#662, MM/dd/yyyy, Some(Etc/UTC)) as timestamp) as date) END AS delinquency_180#436]\n", + " : +- *(5) Filter (isnotnull(loan_id#661L) AND isnotnull(quarter#692))\n", + " : +- *(5) ColumnarToRow\n", + " : +- FileScan parquet [loan_id#661L,monthly_reporting_period#662,current_loan_delinquency_status#671,quarter#692] Batched: true, DataFilters: [isnotnull(loan_id#661L), isnotnull(quarter#692)], Format: Parquet, Location: InMemoryFileIndex[gs://dataproc-nv-demo/mortgage_parquet_cpu/perf], PartitionFilters: [], PushedFilters: [IsNotNull(loan_id), IsNotNull(quarter)], ReadSchema: struct= 1, col(\"monthly_reporting_period\")).alias(\"delinquency_30\"),\n", + " when(col(\"current_loan_delinquency_status\") >= 3, col(\"monthly_reporting_period\")).alias(\"delinquency_90\"),\n", + " when(col(\"current_loan_delinquency_status\") >= 6, col(\"monthly_reporting_period\")).alias(\"delinquency_180\")) \\\n", + " .groupBy(\"quarter\", \"loan_id\") \\\n", + " .agg(\n", + " max(\"current_loan_delinquency_status\").alias(\"delinquency_12\"),\n", + " min(\"delinquency_30\").alias(\"delinquency_30\"),\n", + " min(\"delinquency_90\").alias(\"delinquency_90\"),\n", + " min(\"delinquency_180\").alias(\"delinquency_180\")) \\\n", + " .select(\n", + " col(\"quarter\"),\n", + " col(\"loan_id\"),\n", + " (col(\"delinquency_12\") >= 1).alias(\"ever_30\"),\n", + " (col(\"delinquency_12\") >= 3).alias(\"ever_90\"),\n", + " (col(\"delinquency_12\") >= 6).alias(\"ever_180\"),\n", + " col(\"delinquency_30\"),\n", + " col(\"delinquency_90\"),\n", + " col(\"delinquency_180\"))\n", + " joinedDf = perf \\\n", + " .withColumnRenamed(\"monthly_reporting_period\", \"timestamp\") \\\n", + " .withColumnRenamed(\"monthly_reporting_period_month\", \"timestamp_month\") \\\n", + " .withColumnRenamed(\"monthly_reporting_period_year\", \"timestamp_year\") \\\n", + " .withColumnRenamed(\"current_loan_delinquency_status\", \"delinquency_12\") \\\n", + " .withColumnRenamed(\"current_actual_upb\", \"upb_12\") \\\n", + " .select(\"quarter\", \"loan_id\", \"timestamp\", \"delinquency_12\", \"upb_12\", \"timestamp_month\", \"timestamp_year\") \\\n", + " .join(aggDF, [\"loan_id\", \"quarter\"], \"left_outer\")\n", + "\n", + " # calculate the 12 month delinquency and upb values\n", + " months = 12\n", + " monthArray = [lit(x) for x in range(0, 12)]\n", + " # explode on a small amount of data is actually slightly more efficient than a cross join\n", + " testDf = joinedDf \\\n", + " .withColumn(\"month_y\", explode(array(monthArray))) \\\n", + " .select(\n", + " col(\"quarter\"),\n", + " floor(((col(\"timestamp_year\") * 12 + col(\"timestamp_month\")) - 24000) / months).alias(\"josh_mody\"),\n", + " floor(((col(\"timestamp_year\") * 12 + col(\"timestamp_month\")) - 24000 - col(\"month_y\")) / months).alias(\"josh_mody_n\"),\n", + " col(\"ever_30\"),\n", + " col(\"ever_90\"),\n", + " col(\"ever_180\"),\n", + " col(\"delinquency_30\"),\n", + " col(\"delinquency_90\"),\n", + " col(\"delinquency_180\"),\n", + " col(\"loan_id\"),\n", + " col(\"month_y\"),\n", + " col(\"delinquency_12\"),\n", + " col(\"upb_12\")) \\\n", + " .groupBy(\"quarter\", \"loan_id\", \"josh_mody_n\", \"ever_30\", \"ever_90\", \"ever_180\", \"delinquency_30\", \"delinquency_90\", \"delinquency_180\", \"month_y\") \\\n", + " .agg(max(\"delinquency_12\").alias(\"delinquency_12\"), min(\"upb_12\").alias(\"upb_12\")) \\\n", + " .withColumn(\"timestamp_year\", floor((lit(24000) + (col(\"josh_mody_n\") * lit(months)) + (col(\"month_y\") - 1)) / lit(12))) \\\n", + " .selectExpr('*', 'pmod(24000 + (josh_mody_n * {}) + month_y, 12) as timestamp_month_tmp'.format(months)) \\\n", + " .withColumn(\"timestamp_month\", when(col(\"timestamp_month_tmp\") == lit(0), lit(12)).otherwise(col(\"timestamp_month_tmp\"))) \\\n", + " .withColumn(\"delinquency_12\", ((col(\"delinquency_12\") > 3).cast(\"int\") + (col(\"upb_12\") == 0).cast(\"int\")).alias(\"delinquency_12\")) \\\n", + " .drop(\"timestamp_month_tmp\", \"josh_mody_n\", \"month_y\")\n", + "\n", + " return perf.withColumnRenamed(\"monthly_reporting_period_month\", \"timestamp_month\") \\\n", + " .withColumnRenamed(\"monthly_reporting_period_year\", \"timestamp_year\") \\\n", + " .join(testDf, [\"quarter\", \"loan_id\", \"timestamp_year\", \"timestamp_month\"], \"left\") \\\n", + " .drop(\"timestamp_year\", \"timestamp_month\")\n", + "\n", + "def _create_acquisition(spark, acq):\n", + " nameMapping = spark.createDataFrame(_name_mapping, [\"from_seller_name\", \"to_seller_name\"])\n", + " return acq.join(nameMapping, col(\"seller_name\") == col(\"from_seller_name\"), \"left\") \\\n", + " .drop(\"from_seller_name\") \\\n", + " .withColumn(\"old_name\", col(\"seller_name\")) \\\n", + " .withColumn(\"seller_name\", coalesce(col(\"to_seller_name\"), col(\"seller_name\"))) \\\n", + " .drop(\"to_seller_name\") \\\n", + " .withColumn(\"orig_date\", to_date(col(\"orig_date\"), \"MM/yyyy\")) \\\n", + " .withColumn(\"first_pay_date\", to_date(col(\"first_pay_date\"), \"MM/yyyy\")) \\\n", + "\n", + "def _gen_dictionary(etl_df, col_names):\n", + " cnt_table = etl_df.select(posexplode(array([col(i) for i in col_names])))\\\n", + " .withColumnRenamed(\"pos\", \"column_id\")\\\n", + " .withColumnRenamed(\"col\", \"data\")\\\n", + " .filter(\"data is not null\")\\\n", + " .groupBy(\"column_id\", \"data\")\\\n", + " .count()\n", + " windowed = Window.partitionBy(\"column_id\").orderBy(desc(\"count\"))\n", + " return cnt_table.withColumn(\"id\", row_number().over(windowed)).drop(\"count\")\n", + "\n", + "\n", + "def _cast_string_columns_to_numeric(spark, input_df):\n", + " cached_dict_df = _gen_dictionary(input_df, cate_col_names).cache()\n", + " output_df = input_df\n", + " # Generate the final table with all columns being numeric.\n", + " for col_pos, col_name in enumerate(cate_col_names):\n", + " col_dict_df = cached_dict_df.filter(col(\"column_id\") == col_pos)\\\n", + " .drop(\"column_id\")\\\n", + " .withColumnRenamed(\"data\", col_name)\n", + " \n", + " output_df = output_df.join(broadcast(col_dict_df), col_name, \"left\")\\\n", + " .drop(col_name)\\\n", + " .withColumnRenamed(\"id\", col_name)\n", + " return output_df\n", + "\n", + "def run_mortgage(spark, perf, acq):\n", + " parsed_perf = _parse_dates(perf)\n", + " perf_deliqency = _create_perf_deliquency(spark, parsed_perf)\n", + " cleaned_acq = _create_acquisition(spark, acq)\n", + " df = perf_deliqency.join(cleaned_acq, [\"loan_id\", \"quarter\"], \"inner\")\n", + " test_quarters = ['2016Q1','2016Q2','2016Q3','2016Q4']\n", + " train_df = df.filter(~df.quarter.isin(test_quarters)).drop(\"quarter\")\n", + " test_df = df.filter(df.quarter.isin(test_quarters)).drop(\"quarter\")\n", + " casted_train_df = _cast_string_columns_to_numeric(spark, train_df)\\\n", + " .select(all_col_names)\\\n", + " .withColumn(label_col_name, when(col(label_col_name) > 0, 1).otherwise(0))\\\n", + " .fillna(float(0))\n", + " casted_test_df = _cast_string_columns_to_numeric(spark, test_df)\\\n", + " .select(all_col_names)\\\n", + " .withColumn(label_col_name, when(col(label_col_name) > 0, 1).otherwise(0))\\\n", + " .fillna(float(0))\n", + " return casted_train_df, casted_test_df" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Define Spark conf and Create Spark Session\n", + "For details explanation for spark conf, please go to Spark RAPIDS [config guide](https://nvidia.github.io/spark-rapids/docs/configs.html)." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "sc.stop()\n", + "\n", + "conf = SparkConf().setAppName(\"MortgageETL\")\n", + "conf.set('spark.rapids.sql.explain', 'ALL')\n", + "conf.set(\"spark.executor.instances\", \"20\")\n", + "conf.set(\"spark.executor.cores\", \"7\")\n", + "conf.set(\"spark.task.cpus\", \"1\")\n", + "conf.set(\"spark.rapids.sql.concurrentGpuTasks\", \"2\")\n", + "conf.set(\"spark.executor.memory\", \"4g\")\n", + "conf.set(\"spark.rapids.memory.pinnedPool.size\", \"2G\")\n", + "conf.set(\"spark.executor.memoryOverhead\", \"2G\")\n", + "conf.set(\"spark.executor.extraJavaOptions\", \"-Dai.rapids.cudf.prefer-pinned=true\")\n", + "conf.set(\"spark.locality.wait\", \"0s\")\n", + "conf.set(\"spark.sql.files.maxPartitionBytes\", \"512m\")\n", + "conf.set(\"spark.executor.resource.gpu.amount\", \"1\")\n", + "conf.set(\"spark.task.resource.gpu.amount\", \"0.142\")\n", + "conf.set(\"spark.plugins\", \"com.nvidia.spark.SQLPlugin\")\n", + "conf.set(\"spark.rapids.sql.hasNans\", \"false\")\n", + "conf.set('spark.rapids.sql.batchSizeBytes', '512M')\n", + "conf.set('spark.rapids.sql.reader.batchSizeBytes', '768M')\n", + "conf.set('spark.rapids.sql.variableFloatAgg.enabled', 'true')\n", + "\n", + "spark = SparkSession.builder \\\n", + " .config(conf=conf) \\\n", + " .getOrCreate()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Define Data Input/Output location" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "orig_perf_path = 'gs://dataproc-nv-demo/mortgage_full/perf/*'\n", + "orig_acq_path = 'gs://dataproc-nv-demo/mortgage_full/acq/*'\n", + "\n", + "train_path = 'gs://dataproc-nv-demo/mortgage_full/train/'\n", + "test_path = 'gs://dataproc-nv-demo/mortgage_full/test/'\n", + "tmp_perf_path = 'gs://dataproc-nv-demo/mortgage_parquet_gpu/perf/'\n", + "tmp_acq_path = 'gs://dataproc-nv-demo/mortgage_parquet_gpu/acq/'" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Read CSV data and Transcode to Parquet" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "108.28529238700867\n" + ] + } + ], + "source": [ + "# Lets transcode the data first\n", + "start = time.time()\n", + "# we want a few big files instead of lots of small files\n", + "spark.conf.set('spark.sql.files.maxPartitionBytes', '200G')\n", + "acq = read_acq_csv(spark, orig_acq_path)\n", + "acq.repartition(20).write.parquet(tmp_acq_path, mode='overwrite')\n", + "perf = read_perf_csv(spark, orig_perf_path)\n", + "perf.coalesce(80).write.parquet(tmp_perf_path, mode='overwrite')\n", + "end = time.time()\n", + "print(end - start)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Execute ETL Code Defined in 1st Cell" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "137.99262690544128\n", + "171.97584056854248\n" + ] + } + ], + "source": [ + "# Now lets actually process the data\\n\",\n", + "start = time.time()\n", + "spark.conf.set('spark.sql.files.maxPartitionBytes', '1G')\n", + "spark.conf.set('spark.sql.shuffle.partitions', '160')\n", + "perf = spark.read.parquet(tmp_perf_path)\n", + "acq = spark.read.parquet(tmp_acq_path)\n", + "train_out, test_out = run_mortgage(spark, perf, acq)\n", + "train_out.write.parquet(train_path, mode='overwrite')\n", + "end = time.time()\n", + "print(end - start)\n", + "test_out.write.parquet(test_path, mode='overwrite')\n", + "end = time.time()\n", + "print(end - start)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Print Physical Plan" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "== Physical Plan ==\n", + "*(2) GpuColumnarToRow false\n", + "+- GpuProject [gpucoalesce(orig_channel#1922, 0) AS orig_channel#3686, gpucoalesce(first_home_buyer#2124, 0) AS first_home_buyer#3687, gpucoalesce(loan_purpose#2326, 0) AS loan_purpose#3688, gpucoalesce(property_type#2528, 0) AS property_type#3689, gpucoalesce(occupancy_status#2730, 0) AS occupancy_status#3690, gpucoalesce(property_state#2932, 0) AS property_state#3691, gpucoalesce(relocation_mortgage_indicator#3134, 0) AS relocation_mortgage_indicator#3692, gpucoalesce(seller_name#3336, 0) AS seller_name#3693, gpucoalesce(id#1728, 0) AS mod_flag#3694, gpucoalesce(gpunanvl(orig_interest_rate#297, null), 0.0) AS orig_interest_rate#3695, gpucoalesce(orig_upb#298, 0) AS orig_upb#3696, gpucoalesce(orig_loan_term#299, 0) AS orig_loan_term#3697, gpucoalesce(gpunanvl(orig_ltv#302, null), 0.0) AS orig_ltv#3698, gpucoalesce(gpunanvl(orig_cltv#303, null), 0.0) AS orig_cltv#3699, gpucoalesce(gpunanvl(num_borrowers#304, null), 0.0) AS num_borrowers#3700, gpucoalesce(gpunanvl(dti#305, null), 0.0) AS dti#3701, gpucoalesce(gpunanvl(borrower_credit_score#306, null), 0.0) AS borrower_credit_score#3702, gpucoalesce(num_units#310, 0) AS num_units#3703, gpucoalesce(zip#313, 0) AS zip#3704, gpucoalesce(gpunanvl(mortgage_insurance_percent#314, null), 0.0) AS mortgage_insurance_percent#3705, gpucoalesce(current_loan_delinquency_status#240, 0) AS current_loan_delinquency_status#3706, gpucoalesce(gpunanvl(current_actual_upb#234, null), 0.0) AS current_actual_upb#3707, gpucoalesce(gpunanvl(interest_rate#233, null), 0.0) AS interest_rate#3708, gpucoalesce(gpunanvl(loan_age#235, null), 0.0) AS loan_age#3709, ... 3 more fields]\n", + " +- GpuBroadcastHashJoin [mod_flag#241], [mod_flag#3404], LeftOuter, BuildRight\n", + " :- GpuProject [interest_rate#233, current_actual_upb#234, loan_age#235, msa#239, current_loan_delinquency_status#240, mod_flag#241, non_interest_bearing_upb#256, delinquency_12#1042, orig_interest_rate#297, orig_upb#298, orig_loan_term#299, orig_ltv#302, orig_cltv#303, num_borrowers#304, dti#305, borrower_credit_score#306, num_units#310, zip#313, mortgage_insurance_percent#314, orig_channel#1922, first_home_buyer#2124, loan_purpose#2326, property_type#2528, occupancy_status#2730, ... 3 more fields]\n", + " : +- GpuBroadcastHashJoin [seller_name#1402], [seller_name#3202], LeftOuter, BuildRight\n", + " : :- GpuProject [interest_rate#233, current_actual_upb#234, loan_age#235, msa#239, current_loan_delinquency_status#240, mod_flag#241, non_interest_bearing_upb#256, delinquency_12#1042, seller_name#1402, orig_interest_rate#297, orig_upb#298, orig_loan_term#299, orig_ltv#302, orig_cltv#303, num_borrowers#304, dti#305, borrower_credit_score#306, num_units#310, zip#313, mortgage_insurance_percent#314, orig_channel#1922, first_home_buyer#2124, loan_purpose#2326, property_type#2528, ... 3 more fields]\n", + " : : +- GpuBroadcastHashJoin [relocation_mortgage_indicator#318], [relocation_mortgage_indicator#3000], LeftOuter, BuildRight\n", + " : : :- GpuProject [interest_rate#233, current_actual_upb#234, loan_age#235, msa#239, current_loan_delinquency_status#240, mod_flag#241, non_interest_bearing_upb#256, delinquency_12#1042, seller_name#1402, orig_interest_rate#297, orig_upb#298, orig_loan_term#299, orig_ltv#302, orig_cltv#303, num_borrowers#304, dti#305, borrower_credit_score#306, num_units#310, zip#313, mortgage_insurance_percent#314, relocation_mortgage_indicator#318, orig_channel#1922, first_home_buyer#2124, loan_purpose#2326, ... 3 more fields]\n", + " : : : +- GpuBroadcastHashJoin [property_state#312], [property_state#2798], LeftOuter, BuildRight\n", + " : : : :- GpuProject [interest_rate#233, current_actual_upb#234, loan_age#235, msa#239, current_loan_delinquency_status#240, mod_flag#241, non_interest_bearing_upb#256, delinquency_12#1042, seller_name#1402, orig_interest_rate#297, orig_upb#298, orig_loan_term#299, orig_ltv#302, orig_cltv#303, num_borrowers#304, dti#305, borrower_credit_score#306, num_units#310, property_state#312, zip#313, mortgage_insurance_percent#314, relocation_mortgage_indicator#318, orig_channel#1922, first_home_buyer#2124, ... 3 more fields]\n", + " : : : : +- GpuBroadcastHashJoin [occupancy_status#311], [occupancy_status#2596], LeftOuter, BuildRight\n", + " : : : : :- GpuProject [interest_rate#233, current_actual_upb#234, loan_age#235, msa#239, current_loan_delinquency_status#240, mod_flag#241, non_interest_bearing_upb#256, delinquency_12#1042, seller_name#1402, orig_interest_rate#297, orig_upb#298, orig_loan_term#299, orig_ltv#302, orig_cltv#303, num_borrowers#304, dti#305, borrower_credit_score#306, num_units#310, occupancy_status#311, property_state#312, zip#313, mortgage_insurance_percent#314, relocation_mortgage_indicator#318, orig_channel#1922, ... 3 more fields]\n", + " : : : : : +- GpuBroadcastHashJoin [property_type#309], [property_type#2394], LeftOuter, BuildRight\n", + " : : : : : :- GpuProject [interest_rate#233, current_actual_upb#234, loan_age#235, msa#239, current_loan_delinquency_status#240, mod_flag#241, non_interest_bearing_upb#256, delinquency_12#1042, seller_name#1402, orig_interest_rate#297, orig_upb#298, orig_loan_term#299, orig_ltv#302, orig_cltv#303, num_borrowers#304, dti#305, borrower_credit_score#306, property_type#309, num_units#310, occupancy_status#311, property_state#312, zip#313, mortgage_insurance_percent#314, relocation_mortgage_indicator#318, ... 3 more fields]\n", + " : : : : : : +- GpuBroadcastHashJoin [loan_purpose#308], [loan_purpose#2192], LeftOuter, BuildRight\n", + " : : : : : : :- GpuProject [interest_rate#233, current_actual_upb#234, loan_age#235, msa#239, current_loan_delinquency_status#240, mod_flag#241, non_interest_bearing_upb#256, delinquency_12#1042, seller_name#1402, orig_interest_rate#297, orig_upb#298, orig_loan_term#299, orig_ltv#302, orig_cltv#303, num_borrowers#304, dti#305, borrower_credit_score#306, loan_purpose#308, property_type#309, num_units#310, occupancy_status#311, property_state#312, zip#313, mortgage_insurance_percent#314, ... 3 more fields]\n", + " : : : : : : : +- GpuBroadcastHashJoin [first_home_buyer#307], [first_home_buyer#1990], LeftOuter, BuildRight\n", + " : : : : : : : :- GpuProject [interest_rate#233, current_actual_upb#234, loan_age#235, msa#239, current_loan_delinquency_status#240, mod_flag#241, non_interest_bearing_upb#256, delinquency_12#1042, seller_name#1402, orig_interest_rate#297, orig_upb#298, orig_loan_term#299, orig_ltv#302, orig_cltv#303, num_borrowers#304, dti#305, borrower_credit_score#306, first_home_buyer#307, loan_purpose#308, property_type#309, num_units#310, occupancy_status#311, property_state#312, zip#313, ... 3 more fields]\n", + " : : : : : : : : +- GpuBroadcastHashJoin [orig_channel#295], [orig_channel#1788], LeftOuter, BuildRight\n", + " : : : : : : : : :- GpuProject [interest_rate#233, current_actual_upb#234, loan_age#235, msa#239, current_loan_delinquency_status#240, mod_flag#241, non_interest_bearing_upb#256, delinquency_12#1042, orig_channel#295, seller_name#1402, orig_interest_rate#297, orig_upb#298, orig_loan_term#299, orig_ltv#302, orig_cltv#303, num_borrowers#304, dti#305, borrower_credit_score#306, first_home_buyer#307, loan_purpose#308, property_type#309, num_units#310, occupancy_status#311, property_state#312, ... 3 more fields]\n", + " : : : : : : : : : +- GpuShuffledHashJoin [loan_id#230L, quarter#261], [loan_id#294L, quarter#319], Inner, BuildRight\n", + " : : : : : : : : : :- GpuCoalesceBatches TargetSize(536870912)\n", + " : : : : : : : : : : +- GpuColumnarExchange gpuhashpartitioning(loan_id#230L, quarter#261, 160), true, [id=#3294]\n", + " : : : : : : : : : : +- GpuProject [quarter#261, loan_id#230L, interest_rate#233, current_actual_upb#234, loan_age#235, msa#239, current_loan_delinquency_status#240, mod_flag#241, non_interest_bearing_upb#256, delinquency_12#1042]\n", + " : : : : : : : : : : +- GpuShuffledHashJoin [quarter#261, loan_id#230L, cast(timestamp_year#1106 as bigint), cast(timestamp_month#1070 as bigint)], [quarter#1173, loan_id#1142L, timestamp_year#996L, timestamp_month#1025L], LeftOuter, BuildRight\n", + " : : : : : : : : : : :- GpuCoalesceBatches TargetSize(536870912)\n", + " : : : : : : : : : : : +- GpuColumnarExchange gpuhashpartitioning(quarter#261, loan_id#230L, cast(timestamp_year#1106 as bigint), cast(timestamp_month#1070 as bigint), 160), true, [id=#3124]\n", + " : : : : : : : : : : : +- GpuProject [loan_id#230L, interest_rate#233, current_actual_upb#234, loan_age#235, msa#239, current_loan_delinquency_status#240, mod_flag#241, non_interest_bearing_upb#256, quarter#261, gpumonth(cast(cast(gpuunixtimestamp(monthly_reporting_period#231, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date)) AS timestamp_month#1070, gpuyear(cast(cast(gpuunixtimestamp(monthly_reporting_period#231, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date)) AS timestamp_year#1106]\n", + " : : : : : : : : : : : +- GpuCoalesceBatches TargetSize(536870912)\n", + " : : : : : : : : : : : +- GpuFilter ((NOT quarter#261 INSET (2016Q1,2016Q2,2016Q3,2016Q4) AND gpuisnotnull(loan_id#230L)) AND gpuisnotnull(quarter#261))\n", + " : : : : : : : : : : : +- GpuFileGpuScan parquet [loan_id#230L,monthly_reporting_period#231,interest_rate#233,current_actual_upb#234,loan_age#235,msa#239,current_loan_delinquency_status#240,mod_flag#241,non_interest_bearing_upb#256,quarter#261] Batched: true, DataFilters: [NOT quarter#261 IN (2016Q1,2016Q2,2016Q3,2016Q4), isnotnull(loan_id#230L), isnotnull(quarter#261)], Format: Parquet, Location: InMemoryFileIndex[gs://dataproc-nv-demo/mortgage_parquet_gpu/perf], PartitionFilters: [], PushedFilters: [Not(In(quarter, [2016Q1,2016Q2,2016Q3,2016Q4])), IsNotNull(loan_id), IsNotNull(quarter)], ReadSchema: struct= 1) THEN cast(cast(gpuunixtimestamp(monthly_reporting_period#892, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date) END AS delinquency_30#664, CASE WHEN (current_loan_delinquency_status#901 >= 3) THEN cast(cast(gpuunixtimestamp(monthly_reporting_period#892, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date) END AS delinquency_90#665, CASE WHEN (current_loan_delinquency_status#901 >= 6) THEN cast(cast(gpuunixtimestamp(monthly_reporting_period#892, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date) END AS delinquency_180#666]\n", + " : : : : : : : : : : +- GpuCoalesceBatches TargetSize(536870912)\n", + " : : : : : : : : : : +- GpuFilter (gpuisnotnull(loan_id#891L) AND gpuisnotnull(quarter#922))\n", + " : : : : : : : : : : +- GpuFileGpuScan parquet [loan_id#891L,monthly_reporting_period#892,current_loan_delinquency_status#901,quarter#922] Batched: true, DataFilters: [isnotnull(loan_id#891L), isnotnull(quarter#922)], Format: Parquet, Location: InMemoryFileIndex[gs://dataproc-nv-demo/mortgage_parquet_gpu/perf], PartitionFilters: [], PushedFilters: [IsNotNull(loan_id), IsNotNull(quarter)], ReadSchema: struct\n", + " : : : : : : : : : +- GpuCoalesceBatches RequireSingleBatch\n", + " : : : : : : : : : +- GpuColumnarExchange gpuhashpartitioning(quarter#1173, loan_id#1142L, timestamp_year#996L, timestamp_month#1025L, 160), true, [id=#339]\n", + " : : : : : : : : : +- GpuHashAggregate(keys=[quarter#1173, loan_id#1142L, josh_mody_n#953L, ever_30#693, ever_90#694, ever_180#695, delinquency_30#682, delinquency_90#684, delinquency_180#686, month_y#937], functions=[]), filters=ArrayBuffer())\n", + " : : : : : : : : : +- GpuHashAggregate(keys=[quarter#1173, loan_id#1142L, josh_mody_n#953L, ever_30#693, ever_90#694, ever_180#695, delinquency_30#682, delinquency_90#684, delinquency_180#686, month_y#937], functions=[]), filters=ArrayBuffer())\n", + " : : : : : : : : : +- GpuProject [quarter#1173, FLOOR((cast(((((timestamp_year#776 * 12) + timestamp_month#740) - 24000) - month_y#937) as double) / 12.0)) AS josh_mody_n#953L, ever_30#693, ever_90#694, ever_180#695, delinquency_30#682, delinquency_90#684, delinquency_180#686, loan_id#1142L, month_y#937]\n", + " : : : : : : : : : +- GpuCoalesceBatches TargetSize(536870912)\n", + " : : : : : : : : : +- GpuFilter (gpuisnotnull(CASE WHEN ((((24000 + (FLOOR((cast(((((timestamp_year#776 * 12) + timestamp_month#740) - 24000) - month_y#937) as double) / 12.0)) * 12)) + cast(month_y#937 as bigint)) pmod 12) = 0) THEN 12 ELSE (((24000 + (FLOOR((cast(((((timestamp_year#776 * 12) + timestamp_month#740) - 24000) - month_y#937) as double) / 12.0)) * 12)) + cast(month_y#937 as bigint)) pmod 12) END) AND gpuisnotnull(FLOOR((cast(((24000 + (FLOOR((cast(((((timestamp_year#776 * 12) + timestamp_month#740) - 24000) - month_y#937) as double) / 12.0)) * 12)) + cast((month_y#937 - 1) as bigint)) as double) / 12.0))))\n", + " : : : : : : : : : +- GpuGenerate false, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], [loan_id#1142L, quarter#1173, timestamp_month#740, timestamp_year#776, ever_30#693, ever_90#694, ever_180#695, delinquency_30#682, delinquency_90#684, delinquency_180#686], [month_y#937]\n", + " : : : : : : : : : +- GpuProject [loan_id#1142L, quarter#1173, timestamp_month#740, timestamp_year#776, ever_30#693, ever_90#694, ever_180#695, delinquency_30#682, delinquency_90#684, delinquency_180#686]\n", + " : : : : : : : : : +- GpuShuffledHashJoin [quarter#1173, loan_id#1142L], [quarter#922, loan_id#891L], LeftOuter, BuildRight\n", + " : : : : : : : : : :- GpuCoalesceBatches TargetSize(536870912)\n", + " : : : : : : : : : : +- GpuColumnarExchange gpuhashpartitioning(quarter#1173, loan_id#1142L, 160), true, [id=#322]\n", + " : : : : : : : : : : +- GpuProject [quarter#1173, loan_id#1142L, gpumonth(cast(cast(gpuunixtimestamp(monthly_reporting_period#1143, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date)) AS timestamp_month#740, gpuyear(cast(cast(gpuunixtimestamp(monthly_reporting_period#1143, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date)) AS timestamp_year#776]\n", + " : : : : : : : : : : +- GpuCoalesceBatches TargetSize(536870912)\n", + " : : : : : : : : : : +- GpuFilter ((NOT quarter#1173 INSET (2016Q1,2016Q2,2016Q3,2016Q4) AND gpuisnotnull(loan_id#1142L)) AND gpuisnotnull(quarter#1173))\n", + " : : : : : : : : : : +- GpuFileGpuScan parquet [loan_id#1142L,monthly_reporting_period#1143,quarter#1173] Batched: true, DataFilters: [NOT quarter#1173 IN (2016Q1,2016Q2,2016Q3,2016Q4), isnotnull(loan_id#1142L), isnotnull(quarter#1..., Format: Parquet, Location: InMemoryFileIndex[gs://dataproc-nv-demo/mortgage_parquet_gpu/perf], PartitionFilters: [], PushedFilters: [Not(In(quarter, [2016Q1,2016Q2,2016Q3,2016Q4])), IsNotNull(loan_id), IsNotNull(quarter)], ReadSchema: struct\n", + " : : : : : : : : : +- GpuCoalesceBatches RequireSingleBatch\n", + " : : : : : : : : : +- GpuHashAggregate(keys=[quarter#922, loan_id#891L], functions=[gpumax(current_loan_delinquency_status#901), gpumin(delinquency_30#664), gpumin(delinquency_90#665), gpumin(delinquency_180#666)]), filters=ArrayBuffer(None, None, None, None))\n", + " : : : : : : : : : +- GpuCoalesceBatches TargetSize(536870912)\n", + " : : : : : : : : : +- GpuColumnarExchange gpuhashpartitioning(quarter#922, loan_id#891L, 160), true, [id=#327]\n", + " : : : : : : : : : +- GpuHashAggregate(keys=[quarter#922, loan_id#891L], functions=[partial_gpumax(current_loan_delinquency_status#901), partial_gpumin(delinquency_30#664), partial_gpumin(delinquency_90#665), partial_gpumin(delinquency_180#666)]), filters=ArrayBuffer(None, None, None, None))\n", + " : : : : : : : : : +- GpuProject [quarter#922, loan_id#891L, current_loan_delinquency_status#901, CASE WHEN (current_loan_delinquency_status#901 >= 1) THEN cast(cast(gpuunixtimestamp(monthly_reporting_period#892, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date) END AS delinquency_30#664, CASE WHEN (current_loan_delinquency_status#901 >= 3) THEN cast(cast(gpuunixtimestamp(monthly_reporting_period#892, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date) END AS delinquency_90#665, CASE WHEN (current_loan_delinquency_status#901 >= 6) THEN cast(cast(gpuunixtimestamp(monthly_reporting_period#892, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date) END AS delinquency_180#666]\n", + " : : : : : : : : : +- GpuCoalesceBatches TargetSize(536870912)\n", + " : : : : : : : : : +- GpuFilter (gpuisnotnull(loan_id#891L) AND gpuisnotnull(quarter#922))\n", + " : : : : : : : : : +- GpuFileGpuScan parquet [loan_id#891L,monthly_reporting_period#892,current_loan_delinquency_status#901,quarter#922] Batched: true, DataFilters: [isnotnull(loan_id#891L), isnotnull(quarter#922)], Format: Parquet, Location: InMemoryFileIndex[gs://dataproc-nv-demo/mortgage_parquet_gpu/perf], PartitionFilters: [], PushedFilters: [IsNotNull(loan_id), IsNotNull(quarter)], ReadSchema: struct\n", + " : : : : : : : : +- GpuCoalesceBatches RequireSingleBatch\n", + " : : : : : : : : +- GpuColumnarExchange gpuhashpartitioning(quarter#1173, loan_id#1142L, timestamp_year#996L, timestamp_month#1025L, 160), true, [id=#339]\n", + " : : : : : : : : +- GpuHashAggregate(keys=[quarter#1173, loan_id#1142L, josh_mody_n#953L, ever_30#693, ever_90#694, ever_180#695, delinquency_30#682, delinquency_90#684, delinquency_180#686, month_y#937], functions=[]), filters=ArrayBuffer())\n", + " : : : : : : : : +- GpuHashAggregate(keys=[quarter#1173, loan_id#1142L, josh_mody_n#953L, ever_30#693, ever_90#694, ever_180#695, delinquency_30#682, delinquency_90#684, delinquency_180#686, month_y#937], functions=[]), filters=ArrayBuffer())\n", + " : : : : : : : : +- GpuProject [quarter#1173, FLOOR((cast(((((timestamp_year#776 * 12) + timestamp_month#740) - 24000) - month_y#937) as double) / 12.0)) AS josh_mody_n#953L, ever_30#693, ever_90#694, ever_180#695, delinquency_30#682, delinquency_90#684, delinquency_180#686, loan_id#1142L, month_y#937]\n", + " : : : : : : : : +- GpuCoalesceBatches TargetSize(536870912)\n", + " : : : : : : : : +- GpuFilter (gpuisnotnull(CASE WHEN ((((24000 + (FLOOR((cast(((((timestamp_year#776 * 12) + timestamp_month#740) - 24000) - month_y#937) as double) / 12.0)) * 12)) + cast(month_y#937 as bigint)) pmod 12) = 0) THEN 12 ELSE (((24000 + (FLOOR((cast(((((timestamp_year#776 * 12) + timestamp_month#740) - 24000) - month_y#937) as double) / 12.0)) * 12)) + cast(month_y#937 as bigint)) pmod 12) END) AND gpuisnotnull(FLOOR((cast(((24000 + (FLOOR((cast(((((timestamp_year#776 * 12) + timestamp_month#740) - 24000) - month_y#937) as double) / 12.0)) * 12)) + cast((month_y#937 - 1) as bigint)) as double) / 12.0))))\n", + " : : : : : : : : +- GpuGenerate false, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], [loan_id#1142L, quarter#1173, timestamp_month#740, timestamp_year#776, ever_30#693, ever_90#694, ever_180#695, delinquency_30#682, delinquency_90#684, delinquency_180#686], [month_y#937]\n", + " : : : : : : : : +- GpuProject [loan_id#1142L, quarter#1173, timestamp_month#740, timestamp_year#776, ever_30#693, ever_90#694, ever_180#695, delinquency_30#682, delinquency_90#684, delinquency_180#686]\n", + " : : : : : : : : +- GpuShuffledHashJoin [quarter#1173, loan_id#1142L], [quarter#922, loan_id#891L], LeftOuter, BuildRight\n", + " : : : : : : : : :- GpuCoalesceBatches TargetSize(536870912)\n", + " : : : : : : : : : +- GpuColumnarExchange gpuhashpartitioning(quarter#1173, loan_id#1142L, 160), true, [id=#322]\n", + " : : : : : : : : : +- GpuProject [quarter#1173, loan_id#1142L, gpumonth(cast(cast(gpuunixtimestamp(monthly_reporting_period#1143, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date)) AS timestamp_month#740, gpuyear(cast(cast(gpuunixtimestamp(monthly_reporting_period#1143, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date)) AS timestamp_year#776]\n", + " : : : : : : : : : +- GpuCoalesceBatches TargetSize(536870912)\n", + " : : : : : : : : : +- GpuFilter ((NOT quarter#1173 INSET (2016Q1,2016Q2,2016Q3,2016Q4) AND gpuisnotnull(loan_id#1142L)) AND gpuisnotnull(quarter#1173))\n", + " : : : : : : : : : +- GpuFileGpuScan parquet [loan_id#1142L,monthly_reporting_period#1143,quarter#1173] Batched: true, DataFilters: [NOT quarter#1173 IN (2016Q1,2016Q2,2016Q3,2016Q4), isnotnull(loan_id#1142L), isnotnull(quarter#1..., Format: Parquet, Location: InMemoryFileIndex[gs://dataproc-nv-demo/mortgage_parquet_gpu/perf], PartitionFilters: [], PushedFilters: [Not(In(quarter, [2016Q1,2016Q2,2016Q3,2016Q4])), IsNotNull(loan_id), IsNotNull(quarter)], ReadSchema: struct\n", + " : : : : : : : : +- GpuCoalesceBatches RequireSingleBatch\n", + " : : : : : : : : +- GpuHashAggregate(keys=[quarter#922, loan_id#891L], functions=[gpumax(current_loan_delinquency_status#901), gpumin(delinquency_30#664), gpumin(delinquency_90#665), gpumin(delinquency_180#666)]), filters=ArrayBuffer(None, None, None, None))\n", + " : : : : : : : : +- GpuCoalesceBatches TargetSize(536870912)\n", + " : : : : : : : : +- GpuColumnarExchange gpuhashpartitioning(quarter#922, loan_id#891L, 160), true, [id=#327]\n", + " : : : : : : : : +- GpuHashAggregate(keys=[quarter#922, loan_id#891L], functions=[partial_gpumax(current_loan_delinquency_status#901), partial_gpumin(delinquency_30#664), partial_gpumin(delinquency_90#665), partial_gpumin(delinquency_180#666)]), filters=ArrayBuffer(None, None, None, None))\n", + " : : : : : : : : +- GpuProject [quarter#922, loan_id#891L, current_loan_delinquency_status#901, CASE WHEN (current_loan_delinquency_status#901 >= 1) THEN cast(cast(gpuunixtimestamp(monthly_reporting_period#892, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date) END AS delinquency_30#664, CASE WHEN (current_loan_delinquency_status#901 >= 3) THEN cast(cast(gpuunixtimestamp(monthly_reporting_period#892, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date) END AS delinquency_90#665, CASE WHEN (current_loan_delinquency_status#901 >= 6) THEN cast(cast(gpuunixtimestamp(monthly_reporting_period#892, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date) END AS delinquency_180#666]\n", + " : : : : : : : : +- GpuCoalesceBatches TargetSize(536870912)\n", + " : : : : : : : : +- GpuFilter (gpuisnotnull(loan_id#891L) AND gpuisnotnull(quarter#922))\n", + " : : : : : : : : +- GpuFileGpuScan parquet [loan_id#891L,monthly_reporting_period#892,current_loan_delinquency_status#901,quarter#922] Batched: true, DataFilters: [isnotnull(loan_id#891L), isnotnull(quarter#922)], Format: Parquet, Location: InMemoryFileIndex[gs://dataproc-nv-demo/mortgage_parquet_gpu/perf], PartitionFilters: [], PushedFilters: [IsNotNull(loan_id), IsNotNull(quarter)], ReadSchema: struct\n", + " : : : : : : : +- GpuCoalesceBatches RequireSingleBatch\n", + " : : : : : : : +- GpuColumnarExchange gpuhashpartitioning(quarter#1173, loan_id#1142L, timestamp_year#996L, timestamp_month#1025L, 160), true, [id=#339]\n", + " : : : : : : : +- GpuHashAggregate(keys=[quarter#1173, loan_id#1142L, josh_mody_n#953L, ever_30#693, ever_90#694, ever_180#695, delinquency_30#682, delinquency_90#684, delinquency_180#686, month_y#937], functions=[]), filters=ArrayBuffer())\n", + " : : : : : : : +- GpuHashAggregate(keys=[quarter#1173, loan_id#1142L, josh_mody_n#953L, ever_30#693, ever_90#694, ever_180#695, delinquency_30#682, delinquency_90#684, delinquency_180#686, month_y#937], functions=[]), filters=ArrayBuffer())\n", + " : : : : : : : +- GpuProject [quarter#1173, FLOOR((cast(((((timestamp_year#776 * 12) + timestamp_month#740) - 24000) - month_y#937) as double) / 12.0)) AS josh_mody_n#953L, ever_30#693, ever_90#694, ever_180#695, delinquency_30#682, delinquency_90#684, delinquency_180#686, loan_id#1142L, month_y#937]\n", + " : : : : : : : +- GpuCoalesceBatches TargetSize(536870912)\n", + " : : : : : : : +- GpuFilter (gpuisnotnull(CASE WHEN ((((24000 + (FLOOR((cast(((((timestamp_year#776 * 12) + timestamp_month#740) - 24000) - month_y#937) as double) / 12.0)) * 12)) + cast(month_y#937 as bigint)) pmod 12) = 0) THEN 12 ELSE (((24000 + (FLOOR((cast(((((timestamp_year#776 * 12) + timestamp_month#740) - 24000) - month_y#937) as double) / 12.0)) * 12)) + cast(month_y#937 as bigint)) pmod 12) END) AND gpuisnotnull(FLOOR((cast(((24000 + (FLOOR((cast(((((timestamp_year#776 * 12) + timestamp_month#740) - 24000) - month_y#937) as double) / 12.0)) * 12)) + cast((month_y#937 - 1) as bigint)) as double) / 12.0))))\n", + " : : : : : : : +- GpuGenerate false, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], [loan_id#1142L, quarter#1173, timestamp_month#740, timestamp_year#776, ever_30#693, ever_90#694, ever_180#695, delinquency_30#682, delinquency_90#684, delinquency_180#686], [month_y#937]\n", + " : : : : : : : +- GpuProject [loan_id#1142L, quarter#1173, timestamp_month#740, timestamp_year#776, ever_30#693, ever_90#694, ever_180#695, delinquency_30#682, delinquency_90#684, delinquency_180#686]\n", + " : : : : : : : +- GpuShuffledHashJoin [quarter#1173, loan_id#1142L], [quarter#922, loan_id#891L], LeftOuter, BuildRight\n", + " : : : : : : : :- GpuCoalesceBatches TargetSize(536870912)\n", + " : : : : : : : : +- GpuColumnarExchange gpuhashpartitioning(quarter#1173, loan_id#1142L, 160), true, [id=#322]\n", + " : : : : : : : : +- GpuProject [quarter#1173, loan_id#1142L, gpumonth(cast(cast(gpuunixtimestamp(monthly_reporting_period#1143, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date)) AS timestamp_month#740, gpuyear(cast(cast(gpuunixtimestamp(monthly_reporting_period#1143, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date)) AS timestamp_year#776]\n", + " : : : : : : : : +- GpuCoalesceBatches TargetSize(536870912)\n", + " : : : : : : : : +- GpuFilter ((NOT quarter#1173 INSET (2016Q1,2016Q2,2016Q3,2016Q4) AND gpuisnotnull(loan_id#1142L)) AND gpuisnotnull(quarter#1173))\n", + " : : : : : : : : +- GpuFileGpuScan parquet [loan_id#1142L,monthly_reporting_period#1143,quarter#1173] Batched: true, DataFilters: [NOT quarter#1173 IN (2016Q1,2016Q2,2016Q3,2016Q4), isnotnull(loan_id#1142L), isnotnull(quarter#1..., Format: Parquet, Location: InMemoryFileIndex[gs://dataproc-nv-demo/mortgage_parquet_gpu/perf], PartitionFilters: [], PushedFilters: [Not(In(quarter, [2016Q1,2016Q2,2016Q3,2016Q4])), IsNotNull(loan_id), IsNotNull(quarter)], ReadSchema: struct\n", + " : : : : : : : +- GpuCoalesceBatches RequireSingleBatch\n", + " : : : : : : : +- GpuHashAggregate(keys=[quarter#922, loan_id#891L], functions=[gpumax(current_loan_delinquency_status#901), gpumin(delinquency_30#664), gpumin(delinquency_90#665), gpumin(delinquency_180#666)]), filters=ArrayBuffer(None, None, None, None))\n", + " : : : : : : : +- GpuCoalesceBatches TargetSize(536870912)\n", + " : : : : : : : +- GpuColumnarExchange gpuhashpartitioning(quarter#922, loan_id#891L, 160), true, [id=#327]\n", + " : : : : : : : +- GpuHashAggregate(keys=[quarter#922, loan_id#891L], functions=[partial_gpumax(current_loan_delinquency_status#901), partial_gpumin(delinquency_30#664), partial_gpumin(delinquency_90#665), partial_gpumin(delinquency_180#666)]), filters=ArrayBuffer(None, None, None, None))\n", + " : : : : : : : +- GpuProject [quarter#922, loan_id#891L, current_loan_delinquency_status#901, CASE WHEN (current_loan_delinquency_status#901 >= 1) THEN cast(cast(gpuunixtimestamp(monthly_reporting_period#892, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date) END AS delinquency_30#664, CASE WHEN (current_loan_delinquency_status#901 >= 3) THEN cast(cast(gpuunixtimestamp(monthly_reporting_period#892, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date) END AS delinquency_90#665, CASE WHEN (current_loan_delinquency_status#901 >= 6) THEN cast(cast(gpuunixtimestamp(monthly_reporting_period#892, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date) END AS delinquency_180#666]\n", + " : : : : : : : +- GpuCoalesceBatches TargetSize(536870912)\n", + " : : : : : : : +- GpuFilter (gpuisnotnull(loan_id#891L) AND gpuisnotnull(quarter#922))\n", + " : : : : : : : +- GpuFileGpuScan parquet [loan_id#891L,monthly_reporting_period#892,current_loan_delinquency_status#901,quarter#922] Batched: true, DataFilters: [isnotnull(loan_id#891L), isnotnull(quarter#922)], Format: Parquet, Location: InMemoryFileIndex[gs://dataproc-nv-demo/mortgage_parquet_gpu/perf], PartitionFilters: [], PushedFilters: [IsNotNull(loan_id), IsNotNull(quarter)], ReadSchema: struct\n", + " : : : : : : +- GpuCoalesceBatches RequireSingleBatch\n", + " : : : : : : +- GpuColumnarExchange gpuhashpartitioning(quarter#1173, loan_id#1142L, timestamp_year#996L, timestamp_month#1025L, 160), true, [id=#339]\n", + " : : : : : : +- GpuHashAggregate(keys=[quarter#1173, loan_id#1142L, josh_mody_n#953L, ever_30#693, ever_90#694, ever_180#695, delinquency_30#682, delinquency_90#684, delinquency_180#686, month_y#937], functions=[]), filters=ArrayBuffer())\n", + " : : : : : : +- GpuHashAggregate(keys=[quarter#1173, loan_id#1142L, josh_mody_n#953L, ever_30#693, ever_90#694, ever_180#695, delinquency_30#682, delinquency_90#684, delinquency_180#686, month_y#937], functions=[]), filters=ArrayBuffer())\n", + " : : : : : : +- GpuProject [quarter#1173, FLOOR((cast(((((timestamp_year#776 * 12) + timestamp_month#740) - 24000) - month_y#937) as double) / 12.0)) AS josh_mody_n#953L, ever_30#693, ever_90#694, ever_180#695, delinquency_30#682, delinquency_90#684, delinquency_180#686, loan_id#1142L, month_y#937]\n", + " : : : : : : +- GpuCoalesceBatches TargetSize(536870912)\n", + " : : : : : : +- GpuFilter (gpuisnotnull(CASE WHEN ((((24000 + (FLOOR((cast(((((timestamp_year#776 * 12) + timestamp_month#740) - 24000) - month_y#937) as double) / 12.0)) * 12)) + cast(month_y#937 as bigint)) pmod 12) = 0) THEN 12 ELSE (((24000 + (FLOOR((cast(((((timestamp_year#776 * 12) + timestamp_month#740) - 24000) - month_y#937) as double) / 12.0)) * 12)) + cast(month_y#937 as bigint)) pmod 12) END) AND gpuisnotnull(FLOOR((cast(((24000 + (FLOOR((cast(((((timestamp_year#776 * 12) + timestamp_month#740) - 24000) - month_y#937) as double) / 12.0)) * 12)) + cast((month_y#937 - 1) as bigint)) as double) / 12.0))))\n", + " : : : : : : +- GpuGenerate false, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], [loan_id#1142L, quarter#1173, timestamp_month#740, timestamp_year#776, ever_30#693, ever_90#694, ever_180#695, delinquency_30#682, delinquency_90#684, delinquency_180#686], [month_y#937]\n", + " : : : : : : +- GpuProject [loan_id#1142L, quarter#1173, timestamp_month#740, timestamp_year#776, ever_30#693, ever_90#694, ever_180#695, delinquency_30#682, delinquency_90#684, delinquency_180#686]\n", + " : : : : : : +- GpuShuffledHashJoin [quarter#1173, loan_id#1142L], [quarter#922, loan_id#891L], LeftOuter, BuildRight\n", + " : : : : : : :- GpuCoalesceBatches TargetSize(536870912)\n", + " : : : : : : : +- GpuColumnarExchange gpuhashpartitioning(quarter#1173, loan_id#1142L, 160), true, [id=#322]\n", + " : : : : : : : +- GpuProject [quarter#1173, loan_id#1142L, gpumonth(cast(cast(gpuunixtimestamp(monthly_reporting_period#1143, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date)) AS timestamp_month#740, gpuyear(cast(cast(gpuunixtimestamp(monthly_reporting_period#1143, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date)) AS timestamp_year#776]\n", + " : : : : : : : +- GpuCoalesceBatches TargetSize(536870912)\n", + " : : : : : : : +- GpuFilter ((NOT quarter#1173 INSET (2016Q1,2016Q2,2016Q3,2016Q4) AND gpuisnotnull(loan_id#1142L)) AND gpuisnotnull(quarter#1173))\n", + " : : : : : : : +- GpuFileGpuScan parquet [loan_id#1142L,monthly_reporting_period#1143,quarter#1173] Batched: true, DataFilters: [NOT quarter#1173 IN (2016Q1,2016Q2,2016Q3,2016Q4), isnotnull(loan_id#1142L), isnotnull(quarter#1..., Format: Parquet, Location: InMemoryFileIndex[gs://dataproc-nv-demo/mortgage_parquet_gpu/perf], PartitionFilters: [], PushedFilters: [Not(In(quarter, [2016Q1,2016Q2,2016Q3,2016Q4])), IsNotNull(loan_id), IsNotNull(quarter)], ReadSchema: struct\n", + " : : : : : : +- GpuCoalesceBatches RequireSingleBatch\n", + " : : : : : : +- GpuHashAggregate(keys=[quarter#922, loan_id#891L], functions=[gpumax(current_loan_delinquency_status#901), gpumin(delinquency_30#664), gpumin(delinquency_90#665), gpumin(delinquency_180#666)]), filters=ArrayBuffer(None, None, None, None))\n", + " : : : : : : +- GpuCoalesceBatches TargetSize(536870912)\n", + " : : : : : : +- GpuColumnarExchange gpuhashpartitioning(quarter#922, loan_id#891L, 160), true, [id=#327]\n", + " : : : : : : +- GpuHashAggregate(keys=[quarter#922, loan_id#891L], functions=[partial_gpumax(current_loan_delinquency_status#901), partial_gpumin(delinquency_30#664), partial_gpumin(delinquency_90#665), partial_gpumin(delinquency_180#666)]), filters=ArrayBuffer(None, None, None, None))\n", + " : : : : : : +- GpuProject [quarter#922, loan_id#891L, current_loan_delinquency_status#901, CASE WHEN (current_loan_delinquency_status#901 >= 1) THEN cast(cast(gpuunixtimestamp(monthly_reporting_period#892, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date) END AS delinquency_30#664, CASE WHEN (current_loan_delinquency_status#901 >= 3) THEN cast(cast(gpuunixtimestamp(monthly_reporting_period#892, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date) END AS delinquency_90#665, CASE WHEN (current_loan_delinquency_status#901 >= 6) THEN cast(cast(gpuunixtimestamp(monthly_reporting_period#892, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date) END AS delinquency_180#666]\n", + " : : : : : : +- GpuCoalesceBatches TargetSize(536870912)\n", + " : : : : : : +- GpuFilter (gpuisnotnull(loan_id#891L) AND gpuisnotnull(quarter#922))\n", + " : : : : : : +- GpuFileGpuScan parquet [loan_id#891L,monthly_reporting_period#892,current_loan_delinquency_status#901,quarter#922] Batched: true, DataFilters: [isnotnull(loan_id#891L), isnotnull(quarter#922)], Format: Parquet, Location: InMemoryFileIndex[gs://dataproc-nv-demo/mortgage_parquet_gpu/perf], PartitionFilters: [], PushedFilters: [IsNotNull(loan_id), IsNotNull(quarter)], ReadSchema: struct\n", + " : : : : : +- GpuCoalesceBatches RequireSingleBatch\n", + " : : : : : +- GpuColumnarExchange gpuhashpartitioning(quarter#1173, loan_id#1142L, timestamp_year#996L, timestamp_month#1025L, 160), true, [id=#339]\n", + " : : : : : +- GpuHashAggregate(keys=[quarter#1173, loan_id#1142L, josh_mody_n#953L, ever_30#693, ever_90#694, ever_180#695, delinquency_30#682, delinquency_90#684, delinquency_180#686, month_y#937], functions=[]), filters=ArrayBuffer())\n", + " : : : : : +- GpuHashAggregate(keys=[quarter#1173, loan_id#1142L, josh_mody_n#953L, ever_30#693, ever_90#694, ever_180#695, delinquency_30#682, delinquency_90#684, delinquency_180#686, month_y#937], functions=[]), filters=ArrayBuffer())\n", + " : : : : : +- GpuProject [quarter#1173, FLOOR((cast(((((timestamp_year#776 * 12) + timestamp_month#740) - 24000) - month_y#937) as double) / 12.0)) AS josh_mody_n#953L, ever_30#693, ever_90#694, ever_180#695, delinquency_30#682, delinquency_90#684, delinquency_180#686, loan_id#1142L, month_y#937]\n", + " : : : : : +- GpuCoalesceBatches TargetSize(536870912)\n", + " : : : : : +- GpuFilter (gpuisnotnull(CASE WHEN ((((24000 + (FLOOR((cast(((((timestamp_year#776 * 12) + timestamp_month#740) - 24000) - month_y#937) as double) / 12.0)) * 12)) + cast(month_y#937 as bigint)) pmod 12) = 0) THEN 12 ELSE (((24000 + (FLOOR((cast(((((timestamp_year#776 * 12) + timestamp_month#740) - 24000) - month_y#937) as double) / 12.0)) * 12)) + cast(month_y#937 as bigint)) pmod 12) END) AND gpuisnotnull(FLOOR((cast(((24000 + (FLOOR((cast(((((timestamp_year#776 * 12) + timestamp_month#740) - 24000) - month_y#937) as double) / 12.0)) * 12)) + cast((month_y#937 - 1) as bigint)) as double) / 12.0))))\n", + " : : : : : +- GpuGenerate false, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], [loan_id#1142L, quarter#1173, timestamp_month#740, timestamp_year#776, ever_30#693, ever_90#694, ever_180#695, delinquency_30#682, delinquency_90#684, delinquency_180#686], [month_y#937]\n", + " : : : : : +- GpuProject [loan_id#1142L, quarter#1173, timestamp_month#740, timestamp_year#776, ever_30#693, ever_90#694, ever_180#695, delinquency_30#682, delinquency_90#684, delinquency_180#686]\n", + " : : : : : +- GpuShuffledHashJoin [quarter#1173, loan_id#1142L], [quarter#922, loan_id#891L], LeftOuter, BuildRight\n", + " : : : : : :- GpuCoalesceBatches TargetSize(536870912)\n", + " : : : : : : +- GpuColumnarExchange gpuhashpartitioning(quarter#1173, loan_id#1142L, 160), true, [id=#322]\n", + " : : : : : : +- GpuProject [quarter#1173, loan_id#1142L, gpumonth(cast(cast(gpuunixtimestamp(monthly_reporting_period#1143, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date)) AS timestamp_month#740, gpuyear(cast(cast(gpuunixtimestamp(monthly_reporting_period#1143, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date)) AS timestamp_year#776]\n", + " : : : : : : +- GpuCoalesceBatches TargetSize(536870912)\n", + " : : : : : : +- GpuFilter ((NOT quarter#1173 INSET (2016Q1,2016Q2,2016Q3,2016Q4) AND gpuisnotnull(loan_id#1142L)) AND gpuisnotnull(quarter#1173))\n", + " : : : : : : +- GpuFileGpuScan parquet [loan_id#1142L,monthly_reporting_period#1143,quarter#1173] Batched: true, DataFilters: [NOT quarter#1173 IN (2016Q1,2016Q2,2016Q3,2016Q4), isnotnull(loan_id#1142L), isnotnull(quarter#1..., Format: Parquet, Location: InMemoryFileIndex[gs://dataproc-nv-demo/mortgage_parquet_gpu/perf], PartitionFilters: [], PushedFilters: [Not(In(quarter, [2016Q1,2016Q2,2016Q3,2016Q4])), IsNotNull(loan_id), IsNotNull(quarter)], ReadSchema: struct\n", + " : : : : : +- GpuCoalesceBatches RequireSingleBatch\n", + " : : : : : +- GpuHashAggregate(keys=[quarter#922, loan_id#891L], functions=[gpumax(current_loan_delinquency_status#901), gpumin(delinquency_30#664), gpumin(delinquency_90#665), gpumin(delinquency_180#666)]), filters=ArrayBuffer(None, None, None, None))\n", + " : : : : : +- GpuCoalesceBatches TargetSize(536870912)\n", + " : : : : : +- GpuColumnarExchange gpuhashpartitioning(quarter#922, loan_id#891L, 160), true, [id=#327]\n", + " : : : : : +- GpuHashAggregate(keys=[quarter#922, loan_id#891L], functions=[partial_gpumax(current_loan_delinquency_status#901), partial_gpumin(delinquency_30#664), partial_gpumin(delinquency_90#665), partial_gpumin(delinquency_180#666)]), filters=ArrayBuffer(None, None, None, None))\n", + " : : : : : +- GpuProject [quarter#922, loan_id#891L, current_loan_delinquency_status#901, CASE WHEN (current_loan_delinquency_status#901 >= 1) THEN cast(cast(gpuunixtimestamp(monthly_reporting_period#892, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date) END AS delinquency_30#664, CASE WHEN (current_loan_delinquency_status#901 >= 3) THEN cast(cast(gpuunixtimestamp(monthly_reporting_period#892, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date) END AS delinquency_90#665, CASE WHEN (current_loan_delinquency_status#901 >= 6) THEN cast(cast(gpuunixtimestamp(monthly_reporting_period#892, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date) END AS delinquency_180#666]\n", + " : : : : : +- GpuCoalesceBatches TargetSize(536870912)\n", + " : : : : : +- GpuFilter (gpuisnotnull(loan_id#891L) AND gpuisnotnull(quarter#922))\n", + " : : : : : +- GpuFileGpuScan parquet [loan_id#891L,monthly_reporting_period#892,current_loan_delinquency_status#901,quarter#922] Batched: true, DataFilters: [isnotnull(loan_id#891L), isnotnull(quarter#922)], Format: Parquet, Location: InMemoryFileIndex[gs://dataproc-nv-demo/mortgage_parquet_gpu/perf], PartitionFilters: [], PushedFilters: [IsNotNull(loan_id), IsNotNull(quarter)], ReadSchema: struct\n", + " : : : : +- GpuCoalesceBatches RequireSingleBatch\n", + " : : : : +- GpuColumnarExchange gpuhashpartitioning(quarter#1173, loan_id#1142L, timestamp_year#996L, timestamp_month#1025L, 160), true, [id=#339]\n", + " : : : : +- GpuHashAggregate(keys=[quarter#1173, loan_id#1142L, josh_mody_n#953L, ever_30#693, ever_90#694, ever_180#695, delinquency_30#682, delinquency_90#684, delinquency_180#686, month_y#937], functions=[]), filters=ArrayBuffer())\n", + " : : : : +- GpuHashAggregate(keys=[quarter#1173, loan_id#1142L, josh_mody_n#953L, ever_30#693, ever_90#694, ever_180#695, delinquency_30#682, delinquency_90#684, delinquency_180#686, month_y#937], functions=[]), filters=ArrayBuffer())\n", + " : : : : +- GpuProject [quarter#1173, FLOOR((cast(((((timestamp_year#776 * 12) + timestamp_month#740) - 24000) - month_y#937) as double) / 12.0)) AS josh_mody_n#953L, ever_30#693, ever_90#694, ever_180#695, delinquency_30#682, delinquency_90#684, delinquency_180#686, loan_id#1142L, month_y#937]\n", + " : : : : +- GpuCoalesceBatches TargetSize(536870912)\n", + " : : : : +- GpuFilter (gpuisnotnull(CASE WHEN ((((24000 + (FLOOR((cast(((((timestamp_year#776 * 12) + timestamp_month#740) - 24000) - month_y#937) as double) / 12.0)) * 12)) + cast(month_y#937 as bigint)) pmod 12) = 0) THEN 12 ELSE (((24000 + (FLOOR((cast(((((timestamp_year#776 * 12) + timestamp_month#740) - 24000) - month_y#937) as double) / 12.0)) * 12)) + cast(month_y#937 as bigint)) pmod 12) END) AND gpuisnotnull(FLOOR((cast(((24000 + (FLOOR((cast(((((timestamp_year#776 * 12) + timestamp_month#740) - 24000) - month_y#937) as double) / 12.0)) * 12)) + cast((month_y#937 - 1) as bigint)) as double) / 12.0))))\n", + " : : : : +- GpuGenerate false, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], [loan_id#1142L, quarter#1173, timestamp_month#740, timestamp_year#776, ever_30#693, ever_90#694, ever_180#695, delinquency_30#682, delinquency_90#684, delinquency_180#686], [month_y#937]\n", + " : : : : +- GpuProject [loan_id#1142L, quarter#1173, timestamp_month#740, timestamp_year#776, ever_30#693, ever_90#694, ever_180#695, delinquency_30#682, delinquency_90#684, delinquency_180#686]\n", + " : : : : +- GpuShuffledHashJoin [quarter#1173, loan_id#1142L], [quarter#922, loan_id#891L], LeftOuter, BuildRight\n", + " : : : : :- GpuCoalesceBatches TargetSize(536870912)\n", + " : : : : : +- GpuColumnarExchange gpuhashpartitioning(quarter#1173, loan_id#1142L, 160), true, [id=#322]\n", + " : : : : : +- GpuProject [quarter#1173, loan_id#1142L, gpumonth(cast(cast(gpuunixtimestamp(monthly_reporting_period#1143, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date)) AS timestamp_month#740, gpuyear(cast(cast(gpuunixtimestamp(monthly_reporting_period#1143, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date)) AS timestamp_year#776]\n", + " : : : : : +- GpuCoalesceBatches TargetSize(536870912)\n", + " : : : : : +- GpuFilter ((NOT quarter#1173 INSET (2016Q1,2016Q2,2016Q3,2016Q4) AND gpuisnotnull(loan_id#1142L)) AND gpuisnotnull(quarter#1173))\n", + " : : : : : +- GpuFileGpuScan parquet [loan_id#1142L,monthly_reporting_period#1143,quarter#1173] Batched: true, DataFilters: [NOT quarter#1173 IN (2016Q1,2016Q2,2016Q3,2016Q4), isnotnull(loan_id#1142L), isnotnull(quarter#1..., Format: Parquet, Location: InMemoryFileIndex[gs://dataproc-nv-demo/mortgage_parquet_gpu/perf], PartitionFilters: [], PushedFilters: [Not(In(quarter, [2016Q1,2016Q2,2016Q3,2016Q4])), IsNotNull(loan_id), IsNotNull(quarter)], ReadSchema: struct\n", + " : : : : +- GpuCoalesceBatches RequireSingleBatch\n", + " : : : : +- GpuHashAggregate(keys=[quarter#922, loan_id#891L], functions=[gpumax(current_loan_delinquency_status#901), gpumin(delinquency_30#664), gpumin(delinquency_90#665), gpumin(delinquency_180#666)]), filters=ArrayBuffer(None, None, None, None))\n", + " : : : : +- GpuCoalesceBatches TargetSize(536870912)\n", + " : : : : +- GpuColumnarExchange gpuhashpartitioning(quarter#922, loan_id#891L, 160), true, [id=#327]\n", + " : : : : +- GpuHashAggregate(keys=[quarter#922, loan_id#891L], functions=[partial_gpumax(current_loan_delinquency_status#901), partial_gpumin(delinquency_30#664), partial_gpumin(delinquency_90#665), partial_gpumin(delinquency_180#666)]), filters=ArrayBuffer(None, None, None, None))\n", + " : : : : +- GpuProject [quarter#922, loan_id#891L, current_loan_delinquency_status#901, CASE WHEN (current_loan_delinquency_status#901 >= 1) THEN cast(cast(gpuunixtimestamp(monthly_reporting_period#892, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date) END AS delinquency_30#664, CASE WHEN (current_loan_delinquency_status#901 >= 3) THEN cast(cast(gpuunixtimestamp(monthly_reporting_period#892, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date) END AS delinquency_90#665, CASE WHEN (current_loan_delinquency_status#901 >= 6) THEN cast(cast(gpuunixtimestamp(monthly_reporting_period#892, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date) END AS delinquency_180#666]\n", + " : : : : +- GpuCoalesceBatches TargetSize(536870912)\n", + " : : : : +- GpuFilter (gpuisnotnull(loan_id#891L) AND gpuisnotnull(quarter#922))\n", + " : : : : +- GpuFileGpuScan parquet [loan_id#891L,monthly_reporting_period#892,current_loan_delinquency_status#901,quarter#922] Batched: true, DataFilters: [isnotnull(loan_id#891L), isnotnull(quarter#922)], Format: Parquet, Location: InMemoryFileIndex[gs://dataproc-nv-demo/mortgage_parquet_gpu/perf], PartitionFilters: [], PushedFilters: [IsNotNull(loan_id), IsNotNull(quarter)], ReadSchema: struct\n", + " : : : +- GpuCoalesceBatches RequireSingleBatch\n", + " : : : +- GpuColumnarExchange gpuhashpartitioning(quarter#1173, loan_id#1142L, timestamp_year#996L, timestamp_month#1025L, 160), true, [id=#339]\n", + " : : : +- GpuHashAggregate(keys=[quarter#1173, loan_id#1142L, josh_mody_n#953L, ever_30#693, ever_90#694, ever_180#695, delinquency_30#682, delinquency_90#684, delinquency_180#686, month_y#937], functions=[]), filters=ArrayBuffer())\n", + " : : : +- GpuHashAggregate(keys=[quarter#1173, loan_id#1142L, josh_mody_n#953L, ever_30#693, ever_90#694, ever_180#695, delinquency_30#682, delinquency_90#684, delinquency_180#686, month_y#937], functions=[]), filters=ArrayBuffer())\n", + " : : : +- GpuProject [quarter#1173, FLOOR((cast(((((timestamp_year#776 * 12) + timestamp_month#740) - 24000) - month_y#937) as double) / 12.0)) AS josh_mody_n#953L, ever_30#693, ever_90#694, ever_180#695, delinquency_30#682, delinquency_90#684, delinquency_180#686, loan_id#1142L, month_y#937]\n", + " : : : +- GpuCoalesceBatches TargetSize(536870912)\n", + " : : : +- GpuFilter (gpuisnotnull(CASE WHEN ((((24000 + (FLOOR((cast(((((timestamp_year#776 * 12) + timestamp_month#740) - 24000) - month_y#937) as double) / 12.0)) * 12)) + cast(month_y#937 as bigint)) pmod 12) = 0) THEN 12 ELSE (((24000 + (FLOOR((cast(((((timestamp_year#776 * 12) + timestamp_month#740) - 24000) - month_y#937) as double) / 12.0)) * 12)) + cast(month_y#937 as bigint)) pmod 12) END) AND gpuisnotnull(FLOOR((cast(((24000 + (FLOOR((cast(((((timestamp_year#776 * 12) + timestamp_month#740) - 24000) - month_y#937) as double) / 12.0)) * 12)) + cast((month_y#937 - 1) as bigint)) as double) / 12.0))))\n", + " : : : +- GpuGenerate false, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], [loan_id#1142L, quarter#1173, timestamp_month#740, timestamp_year#776, ever_30#693, ever_90#694, ever_180#695, delinquency_30#682, delinquency_90#684, delinquency_180#686], [month_y#937]\n", + " : : : +- GpuProject [loan_id#1142L, quarter#1173, timestamp_month#740, timestamp_year#776, ever_30#693, ever_90#694, ever_180#695, delinquency_30#682, delinquency_90#684, delinquency_180#686]\n", + " : : : +- GpuShuffledHashJoin [quarter#1173, loan_id#1142L], [quarter#922, loan_id#891L], LeftOuter, BuildRight\n", + " : : : :- GpuCoalesceBatches TargetSize(536870912)\n", + " : : : : +- GpuColumnarExchange gpuhashpartitioning(quarter#1173, loan_id#1142L, 160), true, [id=#322]\n", + " : : : : +- GpuProject [quarter#1173, loan_id#1142L, gpumonth(cast(cast(gpuunixtimestamp(monthly_reporting_period#1143, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date)) AS timestamp_month#740, gpuyear(cast(cast(gpuunixtimestamp(monthly_reporting_period#1143, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date)) AS timestamp_year#776]\n", + " : : : : +- GpuCoalesceBatches TargetSize(536870912)\n", + " : : : : +- GpuFilter ((NOT quarter#1173 INSET (2016Q1,2016Q2,2016Q3,2016Q4) AND gpuisnotnull(loan_id#1142L)) AND gpuisnotnull(quarter#1173))\n", + " : : : : +- GpuFileGpuScan parquet [loan_id#1142L,monthly_reporting_period#1143,quarter#1173] Batched: true, DataFilters: [NOT quarter#1173 IN (2016Q1,2016Q2,2016Q3,2016Q4), isnotnull(loan_id#1142L), isnotnull(quarter#1..., Format: Parquet, Location: InMemoryFileIndex[gs://dataproc-nv-demo/mortgage_parquet_gpu/perf], PartitionFilters: [], PushedFilters: [Not(In(quarter, [2016Q1,2016Q2,2016Q3,2016Q4])), IsNotNull(loan_id), IsNotNull(quarter)], ReadSchema: struct\n", + " : : : +- GpuCoalesceBatches RequireSingleBatch\n", + " : : : +- GpuHashAggregate(keys=[quarter#922, loan_id#891L], functions=[gpumax(current_loan_delinquency_status#901), gpumin(delinquency_30#664), gpumin(delinquency_90#665), gpumin(delinquency_180#666)]), filters=ArrayBuffer(None, None, None, None))\n", + " : : : +- GpuCoalesceBatches TargetSize(536870912)\n", + " : : : +- GpuColumnarExchange gpuhashpartitioning(quarter#922, loan_id#891L, 160), true, [id=#327]\n", + " : : : +- GpuHashAggregate(keys=[quarter#922, loan_id#891L], functions=[partial_gpumax(current_loan_delinquency_status#901), partial_gpumin(delinquency_30#664), partial_gpumin(delinquency_90#665), partial_gpumin(delinquency_180#666)]), filters=ArrayBuffer(None, None, None, None))\n", + " : : : +- GpuProject [quarter#922, loan_id#891L, current_loan_delinquency_status#901, CASE WHEN (current_loan_delinquency_status#901 >= 1) THEN cast(cast(gpuunixtimestamp(monthly_reporting_period#892, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date) END AS delinquency_30#664, CASE WHEN (current_loan_delinquency_status#901 >= 3) THEN cast(cast(gpuunixtimestamp(monthly_reporting_period#892, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date) END AS delinquency_90#665, CASE WHEN (current_loan_delinquency_status#901 >= 6) THEN cast(cast(gpuunixtimestamp(monthly_reporting_period#892, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date) END AS delinquency_180#666]\n", + " : : : +- GpuCoalesceBatches TargetSize(536870912)\n", + " : : : +- GpuFilter (gpuisnotnull(loan_id#891L) AND gpuisnotnull(quarter#922))\n", + " : : : +- GpuFileGpuScan parquet [loan_id#891L,monthly_reporting_period#892,current_loan_delinquency_status#901,quarter#922] Batched: true, DataFilters: [isnotnull(loan_id#891L), isnotnull(quarter#922)], Format: Parquet, Location: InMemoryFileIndex[gs://dataproc-nv-demo/mortgage_parquet_gpu/perf], PartitionFilters: [], PushedFilters: [IsNotNull(loan_id), IsNotNull(quarter)], ReadSchema: struct\n", + " : : +- GpuCoalesceBatches RequireSingleBatch\n", + " : : +- GpuColumnarExchange gpuhashpartitioning(quarter#1173, loan_id#1142L, timestamp_year#996L, timestamp_month#1025L, 160), true, [id=#339]\n", + " : : +- GpuHashAggregate(keys=[quarter#1173, loan_id#1142L, josh_mody_n#953L, ever_30#693, ever_90#694, ever_180#695, delinquency_30#682, delinquency_90#684, delinquency_180#686, month_y#937], functions=[]), filters=ArrayBuffer())\n", + " : : +- GpuHashAggregate(keys=[quarter#1173, loan_id#1142L, josh_mody_n#953L, ever_30#693, ever_90#694, ever_180#695, delinquency_30#682, delinquency_90#684, delinquency_180#686, month_y#937], functions=[]), filters=ArrayBuffer())\n", + " : : +- GpuProject [quarter#1173, FLOOR((cast(((((timestamp_year#776 * 12) + timestamp_month#740) - 24000) - month_y#937) as double) / 12.0)) AS josh_mody_n#953L, ever_30#693, ever_90#694, ever_180#695, delinquency_30#682, delinquency_90#684, delinquency_180#686, loan_id#1142L, month_y#937]\n", + " : : +- GpuCoalesceBatches TargetSize(536870912)\n", + " : : +- GpuFilter (gpuisnotnull(CASE WHEN ((((24000 + (FLOOR((cast(((((timestamp_year#776 * 12) + timestamp_month#740) - 24000) - month_y#937) as double) / 12.0)) * 12)) + cast(month_y#937 as bigint)) pmod 12) = 0) THEN 12 ELSE (((24000 + (FLOOR((cast(((((timestamp_year#776 * 12) + timestamp_month#740) - 24000) - month_y#937) as double) / 12.0)) * 12)) + cast(month_y#937 as bigint)) pmod 12) END) AND gpuisnotnull(FLOOR((cast(((24000 + (FLOOR((cast(((((timestamp_year#776 * 12) + timestamp_month#740) - 24000) - month_y#937) as double) / 12.0)) * 12)) + cast((month_y#937 - 1) as bigint)) as double) / 12.0))))\n", + " : : +- GpuGenerate false, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], [loan_id#1142L, quarter#1173, timestamp_month#740, timestamp_year#776, ever_30#693, ever_90#694, ever_180#695, delinquency_30#682, delinquency_90#684, delinquency_180#686], [month_y#937]\n", + " : : +- GpuProject [loan_id#1142L, quarter#1173, timestamp_month#740, timestamp_year#776, ever_30#693, ever_90#694, ever_180#695, delinquency_30#682, delinquency_90#684, delinquency_180#686]\n", + " : : +- GpuShuffledHashJoin [quarter#1173, loan_id#1142L], [quarter#922, loan_id#891L], LeftOuter, BuildRight\n", + " : : :- GpuCoalesceBatches TargetSize(536870912)\n", + " : : : +- GpuColumnarExchange gpuhashpartitioning(quarter#1173, loan_id#1142L, 160), true, [id=#322]\n", + " : : : +- GpuProject [quarter#1173, loan_id#1142L, gpumonth(cast(cast(gpuunixtimestamp(monthly_reporting_period#1143, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date)) AS timestamp_month#740, gpuyear(cast(cast(gpuunixtimestamp(monthly_reporting_period#1143, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date)) AS timestamp_year#776]\n", + " : : : +- GpuCoalesceBatches TargetSize(536870912)\n", + " : : : +- GpuFilter ((NOT quarter#1173 INSET (2016Q1,2016Q2,2016Q3,2016Q4) AND gpuisnotnull(loan_id#1142L)) AND gpuisnotnull(quarter#1173))\n", + " : : : +- GpuFileGpuScan parquet [loan_id#1142L,monthly_reporting_period#1143,quarter#1173] Batched: true, DataFilters: [NOT quarter#1173 IN (2016Q1,2016Q2,2016Q3,2016Q4), isnotnull(loan_id#1142L), isnotnull(quarter#1..., Format: Parquet, Location: InMemoryFileIndex[gs://dataproc-nv-demo/mortgage_parquet_gpu/perf], PartitionFilters: [], PushedFilters: [Not(In(quarter, [2016Q1,2016Q2,2016Q3,2016Q4])), IsNotNull(loan_id), IsNotNull(quarter)], ReadSchema: struct\n", + " : : +- GpuCoalesceBatches RequireSingleBatch\n", + " : : +- GpuHashAggregate(keys=[quarter#922, loan_id#891L], functions=[gpumax(current_loan_delinquency_status#901), gpumin(delinquency_30#664), gpumin(delinquency_90#665), gpumin(delinquency_180#666)]), filters=ArrayBuffer(None, None, None, None))\n", + " : : +- GpuCoalesceBatches TargetSize(536870912)\n", + " : : +- GpuColumnarExchange gpuhashpartitioning(quarter#922, loan_id#891L, 160), true, [id=#327]\n", + " : : +- GpuHashAggregate(keys=[quarter#922, loan_id#891L], functions=[partial_gpumax(current_loan_delinquency_status#901), partial_gpumin(delinquency_30#664), partial_gpumin(delinquency_90#665), partial_gpumin(delinquency_180#666)]), filters=ArrayBuffer(None, None, None, None))\n", + " : : +- GpuProject [quarter#922, loan_id#891L, current_loan_delinquency_status#901, CASE WHEN (current_loan_delinquency_status#901 >= 1) THEN cast(cast(gpuunixtimestamp(monthly_reporting_period#892, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date) END AS delinquency_30#664, CASE WHEN (current_loan_delinquency_status#901 >= 3) THEN cast(cast(gpuunixtimestamp(monthly_reporting_period#892, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date) END AS delinquency_90#665, CASE WHEN (current_loan_delinquency_status#901 >= 6) THEN cast(cast(gpuunixtimestamp(monthly_reporting_period#892, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date) END AS delinquency_180#666]\n", + " : : +- GpuCoalesceBatches TargetSize(536870912)\n", + " : : +- GpuFilter (gpuisnotnull(loan_id#891L) AND gpuisnotnull(quarter#922))\n", + " : : +- GpuFileGpuScan parquet [loan_id#891L,monthly_reporting_period#892,current_loan_delinquency_status#901,quarter#922] Batched: true, DataFilters: [isnotnull(loan_id#891L), isnotnull(quarter#922)], Format: Parquet, Location: InMemoryFileIndex[gs://dataproc-nv-demo/mortgage_parquet_gpu/perf], PartitionFilters: [], PushedFilters: [IsNotNull(loan_id), IsNotNull(quarter)], ReadSchema: struct\n", + " : +- GpuCoalesceBatches RequireSingleBatch\n", + " : +- GpuColumnarExchange gpuhashpartitioning(quarter#1173, loan_id#1142L, timestamp_year#996L, timestamp_month#1025L, 160), true, [id=#339]\n", + " : +- GpuHashAggregate(keys=[quarter#1173, loan_id#1142L, josh_mody_n#953L, ever_30#693, ever_90#694, ever_180#695, delinquency_30#682, delinquency_90#684, delinquency_180#686, month_y#937], functions=[]), filters=ArrayBuffer())\n", + " : +- GpuHashAggregate(keys=[quarter#1173, loan_id#1142L, josh_mody_n#953L, ever_30#693, ever_90#694, ever_180#695, delinquency_30#682, delinquency_90#684, delinquency_180#686, month_y#937], functions=[]), filters=ArrayBuffer())\n", + " : +- GpuProject [quarter#1173, FLOOR((cast(((((timestamp_year#776 * 12) + timestamp_month#740) - 24000) - month_y#937) as double) / 12.0)) AS josh_mody_n#953L, ever_30#693, ever_90#694, ever_180#695, delinquency_30#682, delinquency_90#684, delinquency_180#686, loan_id#1142L, month_y#937]\n", + " : +- GpuCoalesceBatches TargetSize(536870912)\n", + " : +- GpuFilter (gpuisnotnull(CASE WHEN ((((24000 + (FLOOR((cast(((((timestamp_year#776 * 12) + timestamp_month#740) - 24000) - month_y#937) as double) / 12.0)) * 12)) + cast(month_y#937 as bigint)) pmod 12) = 0) THEN 12 ELSE (((24000 + (FLOOR((cast(((((timestamp_year#776 * 12) + timestamp_month#740) - 24000) - month_y#937) as double) / 12.0)) * 12)) + cast(month_y#937 as bigint)) pmod 12) END) AND gpuisnotnull(FLOOR((cast(((24000 + (FLOOR((cast(((((timestamp_year#776 * 12) + timestamp_month#740) - 24000) - month_y#937) as double) / 12.0)) * 12)) + cast((month_y#937 - 1) as bigint)) as double) / 12.0))))\n", + " : +- GpuGenerate false, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], [loan_id#1142L, quarter#1173, timestamp_month#740, timestamp_year#776, ever_30#693, ever_90#694, ever_180#695, delinquency_30#682, delinquency_90#684, delinquency_180#686], [month_y#937]\n", + " : +- GpuProject [loan_id#1142L, quarter#1173, timestamp_month#740, timestamp_year#776, ever_30#693, ever_90#694, ever_180#695, delinquency_30#682, delinquency_90#684, delinquency_180#686]\n", + " : +- GpuShuffledHashJoin [quarter#1173, loan_id#1142L], [quarter#922, loan_id#891L], LeftOuter, BuildRight\n", + " : :- GpuCoalesceBatches TargetSize(536870912)\n", + " : : +- GpuColumnarExchange gpuhashpartitioning(quarter#1173, loan_id#1142L, 160), true, [id=#322]\n", + " : : +- GpuProject [quarter#1173, loan_id#1142L, gpumonth(cast(cast(gpuunixtimestamp(monthly_reporting_period#1143, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date)) AS timestamp_month#740, gpuyear(cast(cast(gpuunixtimestamp(monthly_reporting_period#1143, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date)) AS timestamp_year#776]\n", + " : : +- GpuCoalesceBatches TargetSize(536870912)\n", + " : : +- GpuFilter ((NOT quarter#1173 INSET (2016Q1,2016Q2,2016Q3,2016Q4) AND gpuisnotnull(loan_id#1142L)) AND gpuisnotnull(quarter#1173))\n", + " : : +- GpuFileGpuScan parquet [loan_id#1142L,monthly_reporting_period#1143,quarter#1173] Batched: true, DataFilters: [NOT quarter#1173 IN (2016Q1,2016Q2,2016Q3,2016Q4), isnotnull(loan_id#1142L), isnotnull(quarter#1..., Format: Parquet, Location: InMemoryFileIndex[gs://dataproc-nv-demo/mortgage_parquet_gpu/perf], PartitionFilters: [], PushedFilters: [Not(In(quarter, [2016Q1,2016Q2,2016Q3,2016Q4])), IsNotNull(loan_id), IsNotNull(quarter)], ReadSchema: struct\n", + " : +- GpuCoalesceBatches RequireSingleBatch\n", + " : +- GpuHashAggregate(keys=[quarter#922, loan_id#891L], functions=[gpumax(current_loan_delinquency_status#901), gpumin(delinquency_30#664), gpumin(delinquency_90#665), gpumin(delinquency_180#666)]), filters=ArrayBuffer(None, None, None, None))\n", + " : +- GpuCoalesceBatches TargetSize(536870912)\n", + " : +- GpuColumnarExchange gpuhashpartitioning(quarter#922, loan_id#891L, 160), true, [id=#327]\n", + " : +- GpuHashAggregate(keys=[quarter#922, loan_id#891L], functions=[partial_gpumax(current_loan_delinquency_status#901), partial_gpumin(delinquency_30#664), partial_gpumin(delinquency_90#665), partial_gpumin(delinquency_180#666)]), filters=ArrayBuffer(None, None, None, None))\n", + " : +- GpuProject [quarter#922, loan_id#891L, current_loan_delinquency_status#901, CASE WHEN (current_loan_delinquency_status#901 >= 1) THEN cast(cast(gpuunixtimestamp(monthly_reporting_period#892, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date) END AS delinquency_30#664, CASE WHEN (current_loan_delinquency_status#901 >= 3) THEN cast(cast(gpuunixtimestamp(monthly_reporting_period#892, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date) END AS delinquency_90#665, CASE WHEN (current_loan_delinquency_status#901 >= 6) THEN cast(cast(gpuunixtimestamp(monthly_reporting_period#892, MM/dd/yyyy, %m/%d/%Y, None) as timestamp) as date) END AS delinquency_180#666]\n", + " : +- GpuCoalesceBatches TargetSize(536870912)\n", + " : +- GpuFilter (gpuisnotnull(loan_id#891L) AND gpuisnotnull(quarter#922))\n", + " : +- GpuFileGpuScan parquet [loan_id#891L,monthly_reporting_period#892,current_loan_delinquency_status#901,quarter#922] Batched: true, DataFilters: [isnotnull(loan_id#891L), isnotnull(quarter#922)], Format: Parquet, Location: InMemoryFileIndex[gs://dataproc-nv-demo/mortgage_parquet_gpu/perf], PartitionFilters: [], PushedFilters: [IsNotNull(loan_id), IsNotNull(quarter)], ReadSchema: struct\n

Introduction to XGBoost Spark with GPU

\n

Mortgage is an example of xgboost classifier to do binary classification. This notebook will show you how to load data, train the xgboost model and use this model to predict if a mushroom is “poisonous”. Camparing to original XGBoost Spark code, there’re only one API difference.

\n

Load libraries

\n

First load some common libraries will be used by both GPU version and CPU version xgboost.

\n\n" + } + ] + }, + "apps": [], + "runtimeInfos": {}, + "progressUpdateIntervalMs": 500, + "jobName": "paragraph_1594528580281_1080045385", + "id": "20200712-043620_382811823", + "dateCreated": "2020-07-12T04:36:20+0000", + "dateStarted": "2020-07-13T02:18:45+0000", + "dateFinished": "2020-07-13T02:18:45+0000", + "status": "FINISHED", + "focus": true, + "$$hashKey": "object:11086" + }, + { + "text": "import ml.dmlc.xgboost4j.scala.spark.{XGBoostClassifier, XGBoostClassificationModel}\nimport org.apache.spark.sql.SparkSession\nimport org.apache.spark.ml.evaluation.MulticlassClassificationEvaluator\nimport org.apache.spark.sql.types.{DoubleType, IntegerType, StructField, StructType}\nimport org.apache.spark.SparkConf", + "user": "anonymous", + "dateUpdated": "2020-07-13T02:18:45+0000", + "config": { + "editorMode": "ace/mode/scala", + "editorHide": false, + "colWidth": 12, + "fontSize": 9, + "enabled": true, + "results": {}, + "editorSetting": { + "language": "scala", + "editOnDblClick": false, + "completionSupport": true, + "completionKey": "TAB" + } + }, + "settings": { + "params": {}, + "forms": {} + }, + "results": { + "code": "SUCCESS", + "msg": [ + { + "type": "TEXT", + "data": "import ml.dmlc.xgboost4j.scala.spark.{XGBoostClassifier, XGBoostClassificationModel}\nimport org.apache.spark.sql.SparkSession\nimport org.apache.spark.ml.evaluation.MulticlassClassificationEvaluator\nimport org.apache.spark.sql.types.{DoubleType, IntegerType, StructField, StructType}\nimport org.apache.spark.SparkConf\n" + } + ] + }, + "apps": [], + "runtimeInfos": {}, + "progressUpdateIntervalMs": 500, + "jobName": "paragraph_1594528580282_314340064", + "id": "20200712-043620_1400821320", + "dateCreated": "2020-07-12T04:36:20+0000", + "dateStarted": "2020-07-13T02:18:45+0000", + "dateFinished": "2020-07-13T02:18:46+0000", + "status": "FINISHED", + "$$hashKey": "object:11087" + }, + { + "text": "%md\nBesides CPU version requires some extra libraries, such as:\n\n```scala\nimport org.apache.spark.ml.feature.VectorAssembler\nimport org.apache.spark.sql.DataFrame\nimport org.apache.spark.sql.functions._\nimport org.apache.spark.sql.types.FloatType\n```", + "user": "anonymous", + "dateUpdated": "2020-07-13T02:18:46+0000", + "config": { + "editorMode": "ace/mode/markdown", + "editorHide": true, + "editorSetting": { + "language": "markdown", + "editOnDblClick": true + }, + "colWidth": 12, + "fontSize": 9, + "enabled": true, + "results": {} + }, + "settings": { + "params": {}, + "forms": {} + }, + "results": { + "code": "SUCCESS", + "msg": [ + { + "type": "HTML", + "data": "
\n

Besides CPU version requires some extra libraries, such as:

\n
import org.apache.spark.ml.feature.VectorAssembler\nimport org.apache.spark.sql.DataFrame\nimport org.apache.spark.sql.functions._\nimport org.apache.spark.sql.types.FloatType\n
\n\n
" + } + ] + }, + "apps": [], + "runtimeInfos": {}, + "progressUpdateIntervalMs": 500, + "jobName": "paragraph_1594528580282_1068889472", + "id": "20200712-043620_1625961573", + "dateCreated": "2020-07-12T04:36:20+0000", + "dateStarted": "2020-07-13T02:18:46+0000", + "dateFinished": "2020-07-13T02:18:46+0000", + "status": "FINISHED", + "$$hashKey": "object:11088" + }, + { + "title": "Set the dataset path", + "text": "// Update all path with your Dataproc Environment\nval trainPath = \"gs://dataproc-nv-demo/mortgage_full/train/\"\nval evalPath = \"gs://dataproc-nv-demo/mortgage_full/test/\"\nval transPath = \"gs://dataproc-nv-demo/mortgage_full/test/\"\nval modelPath = \"gs://dataproc-nv-demo/mortgage_full/model/mortgage\"", + "user": "anonymous", + "dateUpdated": "2020-07-13T02:18:46+0000", + "config": { + "editorMode": "ace/mode/scala", + "editorHide": false, + "colWidth": 12, + "fontSize": 9, + "enabled": true, + "results": {}, + "editorSetting": { + "language": "scala", + "editOnDblClick": false, + "completionSupport": true, + "completionKey": "TAB" + }, + "title": true + }, + "settings": { + "params": {}, + "forms": {} + }, + "results": { + "code": "SUCCESS", + "msg": [ + { + "type": "TEXT", + "data": "\u001b[1m\u001b[34mtrainPath\u001b[0m: \u001b[1m\u001b[32mString\u001b[0m = gs://dataproc-nv-demo/mortgage_full/train/\n\u001b[1m\u001b[34mevalPath\u001b[0m: \u001b[1m\u001b[32mString\u001b[0m = gs://dataproc-nv-demo/mortgage_full/test/\n\u001b[1m\u001b[34mtransPath\u001b[0m: \u001b[1m\u001b[32mString\u001b[0m = gs://dataproc-nv-demo/mortgage_full/test/\n\u001b[1m\u001b[34mmodelPath\u001b[0m: \u001b[1m\u001b[32mString\u001b[0m = gs://dataproc-nv-demo/mortgage_full/model/mortgage\n" + } + ] + }, + "apps": [], + "runtimeInfos": {}, + "progressUpdateIntervalMs": 500, + "jobName": "paragraph_1594528580282_1437224612", + "id": "20200712-043620_1955827407", + "dateCreated": "2020-07-12T04:36:20+0000", + "dateStarted": "2020-07-13T02:18:46+0000", + "dateFinished": "2020-07-13T02:18:46+0000", + "status": "FINISHED", + "$$hashKey": "object:11089" + }, + { + "text": "%md\n## Build the schema and parameters\nThe mortgage data has 27 columns: 26 features and 1 label. \"deinquency_12\" is the label column. The schema will be used to load data in the future.\n\nThe next block also defines some key parameters used in xgboost training process.", + "user": "anonymous", + "dateUpdated": "2020-07-13T02:18:46+0000", + "config": { + "editorMode": "ace/mode/markdown", + "editorHide": true, + "editorSetting": { + "language": "markdown", + "editOnDblClick": true + }, + "colWidth": 12, + "fontSize": 9, + "enabled": true, + "results": {} + }, + "settings": { + "params": {}, + "forms": {} + }, + "results": { + "code": "SUCCESS", + "msg": [ + { + "type": "HTML", + "data": "
\n

Build the schema and parameters

\n

The mortgage data has 27 columns: 26 features and 1 label. “deinquency_12” is the label column. The schema will be used to load data in the future.

\n

The next block also defines some key parameters used in xgboost training process.

\n\n
" + } + ] + }, + "apps": [], + "runtimeInfos": {}, + "progressUpdateIntervalMs": 500, + "jobName": "paragraph_1594528580282_433144999", + "id": "20200712-043620_2043825692", + "dateCreated": "2020-07-12T04:36:20+0000", + "dateStarted": "2020-07-13T02:18:46+0000", + "dateFinished": "2020-07-13T02:18:46+0000", + "status": "FINISHED", + "$$hashKey": "object:11090" + }, + { + "text": "val labelColName = \"delinquency_12\"\nval schema = StructType(List(\n StructField(\"orig_channel\", DoubleType),\n StructField(\"first_home_buyer\", DoubleType),\n StructField(\"loan_purpose\", DoubleType),\n StructField(\"property_type\", DoubleType),\n StructField(\"occupancy_status\", DoubleType),\n StructField(\"property_state\", DoubleType),\n StructField(\"product_type\", DoubleType),\n StructField(\"relocation_mortgage_indicator\", DoubleType),\n StructField(\"seller_name\", DoubleType),\n StructField(\"mod_flag\", DoubleType),\n StructField(\"orig_interest_rate\", DoubleType),\n StructField(\"orig_upb\", IntegerType),\n StructField(\"orig_loan_term\", IntegerType),\n StructField(\"orig_ltv\", DoubleType),\n StructField(\"orig_cltv\", DoubleType),\n StructField(\"num_borrowers\", DoubleType),\n StructField(\"dti\", DoubleType),\n StructField(\"borrower_credit_score\", DoubleType),\n StructField(\"num_units\", IntegerType),\n StructField(\"zip\", IntegerType),\n StructField(\"mortgage_insurance_percent\", DoubleType),\n StructField(\"current_loan_delinquency_status\", IntegerType),\n StructField(\"current_actual_upb\", DoubleType),\n StructField(\"interest_rate\", DoubleType),\n StructField(\"loan_age\", DoubleType),\n StructField(\"msa\", DoubleType),\n StructField(\"non_interest_bearing_upb\", DoubleType),\n StructField(labelColName, IntegerType)))\n\nval featureNames = schema.filter(_.name != labelColName).map(_.name)", + "user": "anonymous", + "dateUpdated": "2020-07-13T02:18:46+0000", + "config": { + "editorMode": "ace/mode/scala", + "editorHide": false, + "colWidth": 12, + "fontSize": 9, + "enabled": true, + "results": {}, + "editorSetting": { + "language": "scala", + "editOnDblClick": false, + "completionSupport": true, + "completionKey": "TAB" + } + }, + "settings": { + "params": {}, + "forms": {} + }, + "results": { + "code": "SUCCESS", + "msg": [ + { + "type": "TEXT", + "data": "\u001b[1m\u001b[34mlabelColName\u001b[0m: \u001b[1m\u001b[32mString\u001b[0m = delinquency_12\n\u001b[1m\u001b[34mschema\u001b[0m: \u001b[1m\u001b[32morg.apache.spark.sql.types.StructType\u001b[0m = StructType(StructField(orig_channel,DoubleType,true), StructField(first_home_buyer,DoubleType,true), StructField(loan_purpose,DoubleType,true), StructField(property_type,DoubleType,true), StructField(occupancy_status,DoubleType,true), StructField(property_state,DoubleType,true), StructField(product_type,DoubleType,true), StructField(relocation_mortgage_indicator,DoubleType,true), StructField(seller_name,DoubleType,true), StructField(mod_flag,DoubleType,true), StructField(orig_interest_rate,DoubleType,true), StructField(orig_upb,IntegerType,true), StructField(orig_loan_term,IntegerType,true), StructField(orig_ltv,DoubleType,true), StructField(orig_cltv...\n" + } + ] + }, + "apps": [], + "runtimeInfos": {}, + "progressUpdateIntervalMs": 500, + "jobName": "paragraph_1594528580282_-318188050", + "id": "20200712-043620_542099397", + "dateCreated": "2020-07-12T04:36:20+0000", + "dateStarted": "2020-07-13T02:18:46+0000", + "dateFinished": "2020-07-13T02:18:46+0000", + "status": "FINISHED", + "$$hashKey": "object:11091" + }, + { + "text": "%md\n## Create a new spark session and load data\n\nA new spark session should be created to continue all the following spark operations.\n\nNOTE: in this notebook, the dependency jars have been loaded when installing toree kernel. Alternatively the jars can be loaded into notebook by [%AddJar magic](https://toree.incubator.apache.org/docs/current/user/faq/). However, there's one restriction for `%AddJar`: the jar uploaded can only be available when `AddJar` is called just after a new spark session is created. Do it as below:\n\n```scala\nimport org.apache.spark.sql.SparkSession\nval spark = SparkSession.builder().appName(\"mortgage-GPU\").getOrCreate\n%AddJar file:/data/libs/cudf-XXX-cuda10.jar\n%AddJar file:/data/libs/rapids-4-spark-XXX.jar\n%AddJar file:/data/libs/xgboost4j_3.0-XXX.jar\n%AddJar file:/data/libs/xgboost4j-spark_3.0-XXX.jar\n// ...\n```\n\n##### Please note the new jar \"rapids-4-spark-XXX.jar\" is only needed for GPU version, you can not add it to dependence list for CPU version.", + "user": "anonymous", + "dateUpdated": "2020-07-13T02:18:47+0000", + "config": { + "editorMode": "ace/mode/markdown", + "editorHide": true, + "editorSetting": { + "language": "markdown", + "editOnDblClick": true + }, + "colWidth": 12, + "fontSize": 9, + "enabled": true, + "results": {} + }, + "settings": { + "params": {}, + "forms": {} + }, + "results": { + "code": "SUCCESS", + "msg": [ + { + "type": "HTML", + "data": "
\n

Create a new spark session and load data

\n

A new spark session should be created to continue all the following spark operations.

\n

NOTE: in this notebook, the dependency jars have been loaded when installing toree kernel. Alternatively the jars can be loaded into notebook by %AddJar magic. However, there’s one restriction for %AddJar: the jar uploaded can only be available when AddJar is called just after a new spark session is created. Do it as below:

\n
import org.apache.spark.sql.SparkSession\nval spark = SparkSession.builder().appName("mortgage-GPU").getOrCreate\n%AddJar file:/data/libs/cudf-XXX-cuda10.jar\n%AddJar file:/data/libs/rapids-4-spark-XXX.jar\n%AddJar file:/data/libs/xgboost4j_3.0-XXX.jar\n%AddJar file:/data/libs/xgboost4j-spark_3.0-XXX.jar\n// ...\n
\n
Please note the new jar “rapids-4-spark-XXX.jar” is only needed for GPU version, you can not add it to dependence list for CPU version.
\n\n
" + } + ] + }, + "apps": [], + "runtimeInfos": {}, + "progressUpdateIntervalMs": 500, + "jobName": "paragraph_1594528580283_-1107372761", + "id": "20200712-043620_889594738", + "dateCreated": "2020-07-12T04:36:20+0000", + "dateStarted": "2020-07-13T02:18:47+0000", + "dateFinished": "2020-07-13T02:18:47+0000", + "status": "FINISHED", + "$$hashKey": "object:11092" + }, + { + "text": "// Build the spark session and data reader as usual\nval conf = new SparkConf()\nconf.set(\"spark.executor.instances\", \"20\")\nconf.set(\"spark.executor.cores\", \"7\")\nconf.set(\"spark.task.cpus\", \"7\")\nconf.set(\"spark.executor.memory\", \"24g\")\nconf.set(\"spark.rapids.memory.pinnedPool.size\", \"2G\")\nconf.set(\"spark.executor.memoryOverhead\", \"16G\")\nconf.set(\"spark.executor.extraJavaOptions\", \"-Dai.rapids.cudf.prefer-pinned=true\")\nconf.set(\"spark.locality.wait\", \"0s\")\nconf.set(\"spark.sql.files.maxPartitionBytes\", \"512m\")\nconf.set(\"spark.executor.resource.gpu.amount\", \"1\")\nconf.set(\"spark.task.resource.gpu.amount\", \"1\")\nconf.set(\"spark.plugins\", \"com.nvidia.spark.SQLPlugin\")\nconf.set(\"spark.rapids.sql.hasNans\", \"false\")\nconf.set(\"spark.rapids.sql.batchSizeBytes\", \"512M\")\nconf.set(\"spark.rapids.sql.reader.batchSizeBytes\", \"768M\")\nconf.set(\"spark.rapids.sql.variableFloatAgg.enabled\", \"true\")\nconf.set(\"spark.rapids.memory.gpu.pooling.enabled\", \"false\")\n// conf.set(\"spark.rapids.memory.gpu.allocFraction\", \"0.1\")\nval spark = SparkSession.builder.appName(\"mortgage-gpu\")\n .enableHiveSupport()\n .config(conf)\n .getOrCreate\nval reader = spark.read.option(\"header\", true).schema(schema)", + "user": "anonymous", + "dateUpdated": "2020-07-13T02:18:47+0000", + "config": { + "editorMode": "ace/mode/scala", + "editorHide": false, + "colWidth": 12, + "fontSize": 9, + "enabled": true, + "results": {}, + "editorSetting": { + "language": "scala", + "editOnDblClick": false, + "completionSupport": true, + "completionKey": "TAB" + } + }, + "settings": { + "params": {}, + "forms": {} + }, + "results": { + "code": "SUCCESS", + "msg": [ + { + "type": "TEXT", + "data": "\u001b[1m\u001b[34mconf\u001b[0m: \u001b[1m\u001b[32morg.apache.spark.SparkConf\u001b[0m = org.apache.spark.SparkConf@1aab0102\n\u001b[1m\u001b[34mspark\u001b[0m: \u001b[1m\u001b[32morg.apache.spark.sql.SparkSession\u001b[0m = org.apache.spark.sql.SparkSession@1239890f\n\u001b[1m\u001b[34mreader\u001b[0m: \u001b[1m\u001b[32morg.apache.spark.sql.DataFrameReader\u001b[0m = org.apache.spark.sql.DataFrameReader@7a9bb956\n" + } + ] + }, + "apps": [], + "runtimeInfos": {}, + "progressUpdateIntervalMs": 500, + "jobName": "paragraph_1594528580283_-892064929", + "id": "20200712-043620_622739089", + "dateCreated": "2020-07-12T04:36:20+0000", + "dateStarted": "2020-07-13T02:18:47+0000", + "dateFinished": "2020-07-13T02:18:53+0000", + "status": "FINISHED", + "$$hashKey": "object:11093" + }, + { + "text": "val trainSet = reader.parquet(trainPath)\nval evalSet = reader.parquet(evalPath)\nval transSet = reader.parquet(transPath)", + "user": "anonymous", + "dateUpdated": "2020-07-13T02:18:53+0000", + "config": { + "editorMode": "ace/mode/scala", + "editorHide": false, + "colWidth": 12, + "fontSize": 9, + "enabled": true, + "results": {}, + "editorSetting": { + "language": "scala", + "editOnDblClick": false, + "completionSupport": true, + "completionKey": "TAB" + } + }, + "settings": { + "params": {}, + "forms": {} + }, + "results": { + "code": "SUCCESS", + "msg": [ + { + "type": "TEXT", + "data": "\u001b[1m\u001b[34mtrainSet\u001b[0m: \u001b[1m\u001b[32morg.apache.spark.sql.DataFrame\u001b[0m = [orig_channel: double, first_home_buyer: double ... 26 more fields]\n\u001b[1m\u001b[34mevalSet\u001b[0m: \u001b[1m\u001b[32morg.apache.spark.sql.DataFrame\u001b[0m = [orig_channel: double, first_home_buyer: double ... 26 more fields]\n\u001b[1m\u001b[34mtransSet\u001b[0m: \u001b[1m\u001b[32morg.apache.spark.sql.DataFrame\u001b[0m = [orig_channel: double, first_home_buyer: double ... 26 more fields]\n" + } + ] + }, + "apps": [], + "runtimeInfos": {}, + "progressUpdateIntervalMs": 500, + "jobName": "paragraph_1594528580283_1108385932", + "id": "20200712-043620_562533619", + "dateCreated": "2020-07-12T04:36:20+0000", + "dateStarted": "2020-07-13T02:18:53+0000", + "dateFinished": "2020-07-13T02:18:54+0000", + "status": "FINISHED", + "$$hashKey": "object:11094" + }, + { + "text": "%md\n## Set xgboost parameters and build a XGBoostClassifier\n\nFor CPU version, `num_workers` is recommended being equal to the number of CPU cores, while for GPU version, it should be set to the number of GPUs in Spark cluster.\n\nBesides the `tree_method` for CPU version is also different from that for GPU version. Now only \"gpu_hist\" is supported for training on GPU.\n\n```scala\n// difference in parameters\n \"num_workers\" -> 12,\n \"tree_method\" -> \"hist\",\n```", + "user": "anonymous", + "dateUpdated": "2020-07-13T02:18:54+0000", + "config": { + "editorMode": "ace/mode/markdown", + "editorHide": true, + "editorSetting": { + "language": "markdown", + "editOnDblClick": true + }, + "colWidth": 12, + "fontSize": 9, + "enabled": true, + "results": {} + }, + "settings": { + "params": {}, + "forms": {} + }, + "results": { + "code": "SUCCESS", + "msg": [ + { + "type": "HTML", + "data": "
\n

Set xgboost parameters and build a XGBoostClassifier

\n

For CPU version, num_workers is recommended being equal to the number of CPU cores, while for GPU version, it should be set to the number of GPUs in Spark cluster.

\n

Besides the tree_method for CPU version is also different from that for GPU version. Now only “gpu_hist” is supported for training on GPU.

\n
// difference in parameters\n  "num_workers" -> 12,\n  "tree_method" -> "hist",\n
\n\n
" + } + ] + }, + "apps": [], + "runtimeInfos": {}, + "progressUpdateIntervalMs": 500, + "jobName": "paragraph_1594528580283_-880026833", + "id": "20200712-043620_1948369426", + "dateCreated": "2020-07-12T04:36:20+0000", + "dateStarted": "2020-07-13T02:18:54+0000", + "dateFinished": "2020-07-13T02:18:54+0000", + "status": "FINISHED", + "$$hashKey": "object:11095" + }, + { + "text": "val commParamMap = Map(\n \"eta\" -> 0.1,\n \"gamma\" -> 0.1,\n \"missing\" -> 0.0,\n \"max_depth\" -> 10,\n \"max_leaves\" -> 256,\n \"objective\" -> \"binary:logistic\",\n \"grow_policy\" -> \"depthwise\",\n \"min_child_weight\" -> 30,\n \"lambda\" -> 1,\n \"scale_pos_weight\" -> 2,\n \"subsample\" -> 1,\n \"num_round\" -> 100)\n \nval xgbParamFinal = commParamMap ++ Map(\"tree_method\" -> \"gpu_hist\", \"num_workers\" -> 20, \"nthread\" -> 7)", + "user": "anonymous", + "dateUpdated": "2020-07-13T02:18:54+0000", + "config": { + "editorMode": "ace/mode/scala", + "editorHide": false, + "colWidth": 12, + "fontSize": 9, + "enabled": true, + "results": {}, + "editorSetting": { + "language": "scala", + "editOnDblClick": false, + "completionSupport": true, + "completionKey": "TAB" + } + }, + "settings": { + "params": {}, + "forms": {} + }, + "results": { + "code": "SUCCESS", + "msg": [ + { + "type": "TEXT", + "data": "\u001b[1m\u001b[34mcommParamMap\u001b[0m: \u001b[1m\u001b[32mscala.collection.immutable.Map[String,Any]\u001b[0m = Map(min_child_weight -> 30, grow_policy -> depthwise, scale_pos_weight -> 2, subsample -> 1, lambda -> 1, max_depth -> 10, objective -> binary:logistic, num_round -> 100, missing -> 0.0, eta -> 0.1, max_leaves -> 256, gamma -> 0.1)\n\u001b[1m\u001b[34mxgbParamFinal\u001b[0m: \u001b[1m\u001b[32mscala.collection.immutable.Map[String,Any]\u001b[0m = Map(min_child_weight -> 30, grow_policy -> depthwise, scale_pos_weight -> 2, num_workers -> 20, subsample -> 1, lambda -> 1, max_depth -> 10, objective -> binary:logistic, num_round -> 100, missing -> 0.0, tree_method -> gpu_hist, eta -> 0.1, max_leaves -> 256, gamma -> 0.1, nthread -> 7)\n" + } + ] + }, + "apps": [], + "runtimeInfos": {}, + "progressUpdateIntervalMs": 500, + "jobName": "paragraph_1594528580283_312126552", + "id": "20200712-043620_726034129", + "dateCreated": "2020-07-12T04:36:20+0000", + "dateStarted": "2020-07-13T02:18:54+0000", + "dateFinished": "2020-07-13T02:18:54+0000", + "status": "FINISHED", + "$$hashKey": "object:11096" + }, + { + "text": "%md\nHere comes the only API difference,`setFeaturesCol` in CPU version vs `setFeaturesCols` in GPU version.\n\nIn previous block, it said that CPU version needs `VectorAssembler` to assemble multiple feature columns into one column, because `setFeaturesCol` only accepts one feature column with the type of `vector`.\n\nBut `setFeaturesCols` supports multiple columns directly, so set the feautres column names directly to `XGBoostClassifier`. \n\nCPU version:\n\n```scala\nval xgbClassifier = new XGBoostClassifier(paramMap)\n .setLabelCol(labelName)\n .setFeaturesCol(\"features\")\n```", + "user": "anonymous", + "dateUpdated": "2020-07-13T02:18:54+0000", + "config": { + "editorMode": "ace/mode/markdown", + "editorHide": true, + "editorSetting": { + "language": "markdown", + "editOnDblClick": true + }, + "colWidth": 12, + "fontSize": 9, + "enabled": true, + "results": {} + }, + "settings": { + "params": {}, + "forms": {} + }, + "results": { + "code": "SUCCESS", + "msg": [ + { + "type": "HTML", + "data": "
\n

Here comes the only API difference,setFeaturesCol in CPU version vs setFeaturesCols in GPU version.

\n

In previous block, it said that CPU version needs VectorAssembler to assemble multiple feature columns into one column, because setFeaturesCol only accepts one feature column with the type of vector.

\n

But setFeaturesCols supports multiple columns directly, so set the feautres column names directly to XGBoostClassifier.

\n

CPU version:

\n
val xgbClassifier  = new XGBoostClassifier(paramMap)\n  .setLabelCol(labelName)\n  .setFeaturesCol("features")\n
\n\n
" + } + ] + }, + "apps": [], + "runtimeInfos": {}, + "progressUpdateIntervalMs": 500, + "jobName": "paragraph_1594528580283_1889609272", + "id": "20200712-043620_531120952", + "dateCreated": "2020-07-12T04:36:20+0000", + "dateStarted": "2020-07-13T02:18:54+0000", + "dateFinished": "2020-07-13T02:18:54+0000", + "status": "FINISHED", + "$$hashKey": "object:11097" + }, + { + "text": "val xgbClassifier = new XGBoostClassifier(xgbParamFinal)\n .setLabelCol(labelColName)\n // === diff ===\n .setFeaturesCols(featureNames)", + "user": "anonymous", + "dateUpdated": "2020-07-13T02:18:55+0000", + "config": { + "editorMode": "ace/mode/scala", + "editorHide": false, + "colWidth": 12, + "fontSize": 9, + "enabled": true, + "results": {}, + "editorSetting": { + "language": "scala", + "editOnDblClick": false, + "completionSupport": true, + "completionKey": "TAB" + } + }, + "settings": { + "params": {}, + "forms": {} + }, + "results": { + "code": "SUCCESS", + "msg": [ + { + "type": "TEXT", + "data": "\u001b[1m\u001b[34mxgbClassifier\u001b[0m: \u001b[1m\u001b[32mml.dmlc.xgboost4j.scala.spark.XGBoostClassifier\u001b[0m = xgbc_2ce07ee0b6cb\n" + } + ] + }, + "apps": [], + "runtimeInfos": {}, + "progressUpdateIntervalMs": 500, + "jobName": "paragraph_1594528580283_-1143522441", + "id": "20200712-043620_427072123", + "dateCreated": "2020-07-12T04:36:20+0000", + "dateStarted": "2020-07-13T02:18:55+0000", + "dateFinished": "2020-07-13T02:18:55+0000", + "status": "FINISHED", + "$$hashKey": "object:11098" + }, + { + "text": "%md\n## Benchmark and train\nThe object `benchmark` is used to compute the elapsed time of some operations.\n\nTraining with evaluation sets is also supported in 2 ways, the same as CPU version's behavior:\n\n* Call API `setEvalSets` after initializing an XGBoostClassifier\n\n```scala\nxgbClassifier.setEvalSets(Map(\"eval\" -> evalSet))\n\n```\n\n* Use parameter `eval_sets` when initializing an XGBoostClassifier\n\n```scala\nval paramMapWithEval = paramMap + (\"eval_sets\" -> Map(\"eval\" -> evalSet))\nval xgbClassifierWithEval = new XGBoostClassifier(paramMapWithEval)\n```\n\nHere chooses the API way to set evaluation sets.", + "user": "anonymous", + "dateUpdated": "2020-07-13T02:18:55+0000", + "config": { + "editorMode": "ace/mode/markdown", + "editorHide": true, + "editorSetting": { + "language": "markdown", + "editOnDblClick": true + }, + "colWidth": 12, + "fontSize": 9, + "enabled": true, + "results": {} + }, + "settings": { + "params": {}, + "forms": {} + }, + "results": { + "code": "SUCCESS", + "msg": [ + { + "type": "HTML", + "data": "
\n

Benchmark and train

\n

The object benchmark is used to compute the elapsed time of some operations.

\n

Training with evaluation sets is also supported in 2 ways, the same as CPU version’s behavior:

\n
    \n
  • Call API setEvalSets after initializing an XGBoostClassifier
  • \n
\n
xgbClassifier.setEvalSets(Map("eval" -> evalSet))\n\n
\n
    \n
  • Use parameter eval_sets when initializing an XGBoostClassifier
  • \n
\n
val paramMapWithEval = paramMap + ("eval_sets" -> Map("eval" -> evalSet))\nval xgbClassifierWithEval = new XGBoostClassifier(paramMapWithEval)\n
\n

Here chooses the API way to set evaluation sets.

\n\n
" + } + ] + }, + "apps": [], + "runtimeInfos": {}, + "progressUpdateIntervalMs": 500, + "jobName": "paragraph_1594528580283_-268123036", + "id": "20200712-043620_1915241764", + "dateCreated": "2020-07-12T04:36:20+0000", + "dateStarted": "2020-07-13T02:18:55+0000", + "dateFinished": "2020-07-13T02:18:55+0000", + "status": "FINISHED", + "$$hashKey": "object:11099" + }, + { + "text": "xgbClassifier.setEvalSets(Map(\"eval\" -> evalSet))", + "user": "anonymous", + "dateUpdated": "2020-07-13T02:18:55+0000", + "config": { + "editorMode": "ace/mode/scala", + "editorHide": false, + "colWidth": 12, + "fontSize": 9, + "enabled": true, + "results": {}, + "editorSetting": { + "language": "scala", + "editOnDblClick": false, + "completionSupport": true, + "completionKey": "TAB" + } + }, + "settings": { + "params": {}, + "forms": {} + }, + "results": { + "code": "SUCCESS", + "msg": [ + { + "type": "TEXT", + "data": "\u001b[1m\u001b[34mres86\u001b[0m: \u001b[1m\u001b[32mxgbClassifier.type\u001b[0m = xgbc_2ce07ee0b6cb\n" + } + ] + }, + "apps": [], + "runtimeInfos": {}, + "progressUpdateIntervalMs": 500, + "jobName": "paragraph_1594528580283_-1163292247", + "id": "20200712-043620_324775014", + "dateCreated": "2020-07-12T04:36:20+0000", + "dateStarted": "2020-07-13T02:18:55+0000", + "dateFinished": "2020-07-13T02:18:55+0000", + "status": "FINISHED", + "$$hashKey": "object:11100" + }, + { + "text": "def benchmark[R](phase: String)(block: => R): (R, Float) = {\n val t0 = System.currentTimeMillis\n val result = block // call-by-name\n val t1 = System.currentTimeMillis\n println(\"Elapsed time [\" + phase + \"]: \" + ((t1 - t0).toFloat / 1000) + \"s\")\n (result, (t1 - t0).toFloat / 1000)\n}", + "user": "anonymous", + "dateUpdated": "2020-07-13T02:18:55+0000", + "config": { + "editorMode": "ace/mode/scala", + "editorHide": false, + "colWidth": 12, + "fontSize": 9, + "enabled": true, + "results": {}, + "editorSetting": { + "language": "scala", + "editOnDblClick": false, + "completionSupport": true, + "completionKey": "TAB" + } + }, + "settings": { + "params": {}, + "forms": {} + }, + "results": { + "code": "SUCCESS", + "msg": [ + { + "type": "TEXT", + "data": "\u001b[1m\u001b[34mbenchmark\u001b[0m: \u001b[1m\u001b[32m[R](phase: String)(block: => R)(R, Float)\u001b[0m\n" + } + ] + }, + "apps": [], + "runtimeInfos": {}, + "progressUpdateIntervalMs": 500, + "jobName": "paragraph_1594528580284_-196014933", + "id": "20200712-043620_1233757982", + "dateCreated": "2020-07-12T04:36:20+0000", + "dateStarted": "2020-07-13T02:18:55+0000", + "dateFinished": "2020-07-13T02:18:55+0000", + "status": "FINISHED", + "$$hashKey": "object:11101" + }, + { + "text": "%md\nCPU version reqires an extra step before fitting data to classifier, using `VectorAssembler` to assemble all feature columns into one column. The following code snip shows how to do the vectorizing.\n\n```scala\nobject Vectorize {\n def apply(df: DataFrame, featureNames: Seq[String], labelName: String): DataFrame = {\n val toFloat = df.schema.map(f => col(f.name).cast(FloatType))\n new VectorAssembler()\n .setInputCols(featureNames.toArray)\n .setOutputCol(\"features\")\n .transform(df.select(toFloat:_*))\n .select(col(\"features\"), col(labelName))\n }\n}\n\ntrainSet = Vectorize(trainSet, featureCols, labelName)\nevalSet = Vectorize(evalSet, featureCols, labelName)\ntransSet = Vectorize(transSet, featureCols, labelName)\n\n```\n\n`VectorAssembler` is not needed for GPU version. Just fit the loaded data directly to XGBoostClassifier.", + "user": "anonymous", + "dateUpdated": "2020-07-13T02:18:56+0000", + "config": { + "editorMode": "ace/mode/text", + "editorHide": false, + "editorSetting": { + "language": "text", + "editOnDblClick": false + }, + "colWidth": 12, + "fontSize": 9, + "enabled": true, + "results": {}, + "tableHide": false + }, + "settings": { + "params": {}, + "forms": {} + }, + "results": { + "code": "SUCCESS", + "msg": [ + { + "type": "HTML", + "data": "
\n

CPU version reqires an extra step before fitting data to classifier, using VectorAssembler to assemble all feature columns into one column. The following code snip shows how to do the vectorizing.

\n
object Vectorize {\n  def apply(df: DataFrame, featureNames: Seq[String], labelName: String): DataFrame = {\n    val toFloat = df.schema.map(f => col(f.name).cast(FloatType))\n    new VectorAssembler()\n      .setInputCols(featureNames.toArray)\n      .setOutputCol("features")\n      .transform(df.select(toFloat:_*))\n      .select(col("features"), col(labelName))\n  }\n}\n\ntrainSet = Vectorize(trainSet, featureCols, labelName)\nevalSet = Vectorize(evalSet, featureCols, labelName)\ntransSet = Vectorize(transSet, featureCols, labelName)\n\n
\n

VectorAssembler is not needed for GPU version. Just fit the loaded data directly to XGBoostClassifier.

\n\n
" + } + ] + }, + "apps": [], + "runtimeInfos": {}, + "progressUpdateIntervalMs": 500, + "jobName": "paragraph_1594528580284_-1513881670", + "id": "20200712-043620_618156060", + "dateCreated": "2020-07-12T04:36:20+0000", + "dateStarted": "2020-07-13T02:18:56+0000", + "dateFinished": "2020-07-13T02:18:56+0000", + "status": "FINISHED", + "$$hashKey": "object:11102" + }, + { + "text": "// Start training\nprintln(\"\\n------ Training ------\")\nval (xgbClassificationModel, _) = benchmark(\"train\") {\n xgbClassifier.fit(trainSet)\n}", + "user": "anonymous", + "dateUpdated": "2020-07-13T02:18:56+0000", + "config": { + "editorMode": "ace/mode/scala", + "editorHide": false, + "colWidth": 12, + "fontSize": 9, + "enabled": true, + "results": {}, + "editorSetting": { + "language": "scala", + "editOnDblClick": false, + "completionSupport": true, + "completionKey": "TAB" + } + }, + "settings": { + "params": {}, + "forms": {} + }, + "apps": [], + "runtimeInfos": {}, + "progressUpdateIntervalMs": 500, + "jobName": "paragraph_1594528580284_-695049679", + "id": "20200712-043620_1418358219", + "dateCreated": "2020-07-12T04:36:20+0000", + "dateStarted": "2020-07-13T02:18:56+0000", + "dateFinished": "2020-07-13T02:26:51+0000", + "status": "FINISHED", + "$$hashKey": "object:11103", + "results": { + "code": "SUCCESS", + "msg": [ + { + "type": "TEXT", + "data": "\n------ Training ------\nTracker started, with env={DMLC_NUM_SERVER=0, DMLC_TRACKER_URI=10.164.0.17, DMLC_TRACKER_PORT=9091, DMLC_NUM_WORKER=20}\nElapsed time [train]: 475.008s\n\u001b[1m\u001b[34mxgbClassificationModel\u001b[0m: \u001b[1m\u001b[32mml.dmlc.xgboost4j.scala.spark.XGBoostClassificationModel\u001b[0m = xgbc_2ce07ee0b6cb\n" + } + ] + } + }, + { + "text": "%md\n## Transformation and evaluation\nHere uses `transSet` to evaluate our model and prints some useful columns to show our prediction result. After that `MulticlassClassificationEvaluator` is used to calculate an overall accuracy of our predictions.", + "user": "anonymous", + "dateUpdated": "2020-07-13T02:26:51+0000", + "config": { + "editorMode": "ace/mode/markdown", + "editorHide": true, + "editorSetting": { + "language": "markdown", + "editOnDblClick": true + }, + "colWidth": 12, + "fontSize": 9, + "enabled": true, + "results": {} + }, + "settings": { + "params": {}, + "forms": {} + }, + "results": { + "code": "SUCCESS", + "msg": [ + { + "type": "HTML", + "data": "
\n

Transformation and evaluation

\n

Here uses transSet to evaluate our model and prints some useful columns to show our prediction result. After that MulticlassClassificationEvaluator is used to calculate an overall accuracy of our predictions.

\n\n
" + } + ] + }, + "apps": [], + "runtimeInfos": {}, + "progressUpdateIntervalMs": 500, + "jobName": "paragraph_1594528580284_1090201866", + "id": "20200712-043620_470610364", + "dateCreated": "2020-07-12T04:36:20+0000", + "dateStarted": "2020-07-13T02:26:51+0000", + "dateFinished": "2020-07-13T02:26:51+0000", + "status": "FINISHED", + "$$hashKey": "object:11104" + }, + { + "text": "println(\"\\n------ Transforming ------\")\nval (results, _) = benchmark(\"transform\") {\n val ret = xgbClassificationModel.transform(transSet).cache()\n ret\n}\nz.show(results.select(\"orig_channel\", labelColName,\"rawPrediction\",\"probability\",\"prediction\").limit(10))\n\nprintln(\"\\n------Accuracy of Evaluation------\")\nval evaluator = new MulticlassClassificationEvaluator().setLabelCol(labelColName)\nval accuracy = evaluator.evaluate(results)\nprintln(accuracy)", + "user": "anonymous", + "dateUpdated": "2020-07-13T02:26:51+0000", + "config": { + "editorMode": "ace/mode/scala", + "editorHide": false, + "colWidth": 12, + "fontSize": 9, + "enabled": true, + "results": { + "1": { + "graph": { + "mode": "table", + "height": 300, + "optionOpen": false, + "setting": { + "table": { + "tableGridState": {}, + "tableColumnTypeState": { + "names": { + "orig_channel": "string", + "delinquency_12": "string", + "rawPrediction": "string", + "probability": "string", + "prediction": "string" + }, + "updated": false + }, + "tableOptionSpecHash": "[{\"name\":\"useFilter\",\"valueType\":\"boolean\",\"defaultValue\":false,\"widget\":\"checkbox\",\"description\":\"Enable filter for columns\"},{\"name\":\"showPagination\",\"valueType\":\"boolean\",\"defaultValue\":false,\"widget\":\"checkbox\",\"description\":\"Enable pagination for better navigation\"},{\"name\":\"showAggregationFooter\",\"valueType\":\"boolean\",\"defaultValue\":false,\"widget\":\"checkbox\",\"description\":\"Enable a footer for displaying aggregated values\"}]", + "tableOptionValue": { + "useFilter": false, + "showPagination": false, + "showAggregationFooter": false + }, + "updated": false, + "initialized": false + } + }, + "commonSetting": {} + } + } + }, + "editorSetting": { + "language": "scala", + "editOnDblClick": false, + "completionSupport": true, + "completionKey": "TAB" + } + }, + "settings": { + "params": {}, + "forms": {} + }, + "results": { + "code": "SUCCESS", + "msg": [ + { + "type": "TEXT", + "data": "\n------ Transforming ------\nElapsed time [transform]: 0.143s\n" + }, + { + "type": "TABLE", + "data": "orig_channel\tdelinquency_12\trawPrediction\tprobability\tprediction\n4.9E-324\t0\t[5.001231670379639,-5.001231670379639]\t[0.9933153325691819,0.006684667430818081]\t0.0\n1.0E-323\t0\t[6.777693748474121,-6.777693748474121]\t[0.9988623971585184,0.0011376028414815664]\t0.0\n4.9E-324\t0\t[7.609184741973877,-7.609184741973877]\t[0.999504369799979,4.956302000209689E-4]\t0.0\n1.0E-323\t0\t[8.442628860473633,-8.442628860473633]\t[0.9997845634934492,2.1543650655075908E-4]\t0.0\n1.0E-323\t0\t[8.08891773223877,-8.08891773223877]\t[0.9996931724308524,3.068275691475719E-4]\t0.0\n4.9E-324\t0\t[8.863614082336426,-8.863614082336426]\t[0.999858577051782,1.4142294821795076E-4]\t0.0\n1.0E-323\t0\t[8.85793399810791,-8.85793399810791]\t[0.9998577715887222,1.422284112777561E-4]\t0.0\n4.9E-324\t0\t[7.265506744384766,-7.265506744384766]\t[0.9993012417689897,6.98758231010288E-4]\t0.0\n4.9E-324\t0\t[5.615269184112549,-5.615269184112549]\t[0.9963713854085654,0.003628614591434598]\t0.0\n4.9E-324\t0\t[6.023037910461426,-6.023037910461426]\t[0.997583553660661,0.002416446339339018]\t0.0\n" + }, + { + "type": "TEXT", + "data": "\n------Accuracy of Evaluation------\n0.9982550045083602\n\u001b[1m\u001b[34mresults\u001b[0m: \u001b[1m\u001b[32morg.apache.spark.sql.Dataset[org.apache.spark.sql.Row]\u001b[0m = [orig_channel: double, first_home_buyer: double ... 29 more fields]\n\u001b[1m\u001b[34mevaluator\u001b[0m: \u001b[1m\u001b[32morg.apache.spark.ml.evaluation.MulticlassClassificationEvaluator\u001b[0m = MulticlassClassificationEvaluator: uid=mcEval_62ee3ceb950d, metricName=f1, metricLabel=0.0, beta=1.0, eps=1.0E-15\n\u001b[1m\u001b[34maccuracy\u001b[0m: \u001b[1m\u001b[32mDouble\u001b[0m = 0.9982550045083602\n" + } + ] + }, + "apps": [], + "runtimeInfos": {}, + "progressUpdateIntervalMs": 500, + "jobName": "paragraph_1594528580284_-218421974", + "id": "20200712-043620_775095654", + "dateCreated": "2020-07-12T04:36:20+0000", + "dateStarted": "2020-07-13T02:26:51+0000", + "dateFinished": "2020-07-13T02:27:20+0000", + "status": "FINISHED", + "$$hashKey": "object:11105" + }, + { + "title": "Example to save/load the model, predict with the model", + "text": "xgbClassificationModel.write.overwrite.save(modelPath)\n\nval modelFromDisk = XGBoostClassificationModel.load(modelPath)\n\nval (results2, _) = benchmark(\"transform2\") {\n modelFromDisk.transform(transSet)\n}\nz.show(results2.limit(5))", + "user": "anonymous", + "dateUpdated": "2020-07-13T02:27:20+0000", + "config": { + "editorMode": "ace/mode/scala", + "editorHide": false, + "colWidth": 12, + "fontSize": 9, + "enabled": true, + "results": { + "1": { + "graph": { + "mode": "table", + "height": 300, + "optionOpen": false, + "setting": { + "table": { + "tableGridState": {}, + "tableColumnTypeState": { + "names": { + "orig_channel": "string", + "first_home_buyer": "string", + "loan_purpose": "string", + "property_type": "string", + "occupancy_status": "string", + "property_state": "string", + "product_type": "string", + "relocation_mortgage_indicator": "string", + "seller_name": "string", + "mod_flag": "string", + "orig_interest_rate": "string", + "orig_upb": "string", + "orig_loan_term": "string", + "orig_ltv": "string", + "orig_cltv": "string", + "num_borrowers": "string", + "dti": "string", + "borrower_credit_score": "string", + "num_units": "string", + "zip": "string", + "mortgage_insurance_percent": "string", + "current_loan_delinquency_status": "string", + "current_actual_upb": "string", + "interest_rate": "string", + "loan_age": "string", + "msa": "string", + "non_interest_bearing_upb": "string", + "delinquency_12": "string", + "rawPrediction": "string", + "probability": "string", + "prediction": "string" + }, + "updated": false + }, + "tableOptionSpecHash": "[{\"name\":\"useFilter\",\"valueType\":\"boolean\",\"defaultValue\":false,\"widget\":\"checkbox\",\"description\":\"Enable filter for columns\"},{\"name\":\"showPagination\",\"valueType\":\"boolean\",\"defaultValue\":false,\"widget\":\"checkbox\",\"description\":\"Enable pagination for better navigation\"},{\"name\":\"showAggregationFooter\",\"valueType\":\"boolean\",\"defaultValue\":false,\"widget\":\"checkbox\",\"description\":\"Enable a footer for displaying aggregated values\"}]", + "tableOptionValue": { + "useFilter": false, + "showPagination": false, + "showAggregationFooter": false + }, + "updated": false, + "initialized": false + } + }, + "commonSetting": {} + } + } + }, + "editorSetting": { + "language": "scala", + "editOnDblClick": false, + "completionSupport": true, + "completionKey": "TAB" + }, + "title": true + }, + "settings": { + "params": {}, + "forms": {} + }, + "results": { + "code": "SUCCESS", + "msg": [ + { + "type": "TEXT", + "data": "Elapsed time [transform2]: 0.058s\n" + }, + { + "type": "TABLE", + "data": "orig_channel\tfirst_home_buyer\tloan_purpose\tproperty_type\toccupancy_status\tproperty_state\tproduct_type\trelocation_mortgage_indicator\tseller_name\tmod_flag\torig_interest_rate\torig_upb\torig_loan_term\torig_ltv\torig_cltv\tnum_borrowers\tdti\tborrower_credit_score\tnum_units\tzip\tmortgage_insurance_percent\tcurrent_loan_delinquency_status\tcurrent_actual_upb\tinterest_rate\tloan_age\tmsa\tnon_interest_bearing_upb\tdelinquency_12\trawPrediction\tprobability\tprediction\n4.9E-324\t4.9E-324\t1.0E-323\t4.9E-324\t1.0E-323\t1.24E-322\tnull\t4.9E-324\t4.9E-324\t4.9E-324\t2.75\t278000\t120\t56.0\t56.0\t1.0\t46.0\t624.0\t1\t295\t0.0\t0\t148441.15\t2.75\t13.0\t34820.0\t0.0\t0\t[5.001231670379639,-5.001231670379639]\t[0.9933153325691819,0.006684667430818081]\t0.0\n1.0E-323\t4.9E-324\t1.5E-323\t4.9E-324\t4.9E-324\t4.9E-324\tnull\t4.9E-324\t6.9E-323\t4.9E-324\t4.25\t579000\t360\t72.0\t72.0\t2.0\t44.0\t714.0\t1\t949\t0.0\t0\t568406.57\t4.25\t13.0\t41860.0\t0.0\t0\t[6.777693748474121,-6.777693748474121]\t[0.9988623971585184,0.0011376028414815664]\t0.0\n4.9E-324\t4.9E-324\t1.5E-323\t4.9E-324\t4.9E-324\t4.4E-323\tnull\t4.9E-324\t4.9E-324\t4.9E-324\t4.0\t240000\t360\t80.0\t80.0\t1.0\t18.0\t820.0\t1\t282\t0.0\t0\t236132.18\t4.0\t10.0\t16740.0\t0.0\t0\t[7.609184741973877,-7.609184741973877]\t[0.999504369799979,4.956302000209689E-4]\t0.0\n1.0E-323\t4.9E-324\t1.0E-323\t4.9E-324\t4.9E-324\t1.04E-322\tnull\t4.9E-324\t3.0E-323\t4.9E-324\t3.0\t241000\t180\t44.0\t44.0\t2.0\t44.0\t787.0\t1\t650\t0.0\t0\t230092.59\t3.0\t9.0\t0.0\t0.0\t0\t[8.442628860473633,-8.442628860473633]\t[0.9997845634934492,2.1543650655075908E-4]\t0.0\n1.0E-323\t4.9E-324\t4.9E-324\t1.5E-323\t4.9E-324\t1.0E-323\tnull\t4.9E-324\t4.9E-324\t4.9E-324\t4.25\t177000\t360\t75.0\t75.0\t2.0\t26.0\t792.0\t1\t787\t0.0\t0\t172387.22\t4.25\t18.0\t12420.0\t0.0\t0\t[8.08891773223877,-8.08891773223877]\t[0.9996931724308524,3.068275691475719E-4]\t0.0\n" + }, + { + "type": "TEXT", + "data": "\u001b[1m\u001b[34mmodelFromDisk\u001b[0m: \u001b[1m\u001b[32mml.dmlc.xgboost4j.scala.spark.XGBoostClassificationModel\u001b[0m = xgbc_2ce07ee0b6cb\n\u001b[1m\u001b[34mresults2\u001b[0m: \u001b[1m\u001b[32morg.apache.spark.sql.DataFrame\u001b[0m = [orig_channel: double, first_home_buyer: double ... 29 more fields]\n" + } + ] + }, + "apps": [], + "runtimeInfos": {}, + "progressUpdateIntervalMs": 500, + "jobName": "paragraph_1594528580284_1907963406", + "id": "20200712-043620_1435219490", + "dateCreated": "2020-07-12T04:36:20+0000", + "dateStarted": "2020-07-13T02:27:20+0000", + "dateFinished": "2020-07-13T02:27:23+0000", + "status": "FINISHED", + "$$hashKey": "object:11106" + }, + { + "user": "anonymous", + "dateUpdated": "2020-07-12T04:50:45+0000", + "config": { + "colWidth": 12, + "fontSize": 9, + "enabled": true, + "results": {}, + "editorSetting": { + "language": "scala", + "editOnDblClick": false, + "completionKey": "TAB", + "completionSupport": true + }, + "editorMode": "ace/mode/scala" + }, + "settings": { + "params": {}, + "forms": {} + }, + "apps": [], + "runtimeInfos": {}, + "progressUpdateIntervalMs": 500, + "jobName": "paragraph_1594528930033_-558128424", + "id": "paragraph_1594528930033_-558128424", + "dateCreated": "2020-07-12T04:42:10+0000", + "status": "FINISHED", + "$$hashKey": "object:11107" + } + ], + "name": "mortgage-gpu-scala", + "id": "2FCHJHDT3", + "defaultInterpreterGroup": "spark", + "version": "0.9.0-preview1", + "noteParams": {}, + "noteForms": {}, + "angularObjects": {}, + "config": { + "isZeppelinNotebookCronEnable": false, + "looknfeel": "default", + "personalizedMode": "false" + }, + "info": { + "isRunning": true + }, + "path": "/mortgage-gpu-scala" +} \ No newline at end of file diff --git a/docs/demo/gpu-mortgage_accelerated.ipynb b/docs/demo/gpu-mortgage_accelerated.ipynb new file mode 100644 index 00000000000..2ce911b3a6b --- /dev/null +++ b/docs/demo/gpu-mortgage_accelerated.ipynb @@ -0,0 +1 @@ +{"cells":[{"cell_type":"code","source":["%sh\n \nwget http://rapidsai-data.s3-website.us-east-2.amazonaws.com/notebook-mortgage-data/mortgage_2000.tgz -P /Users//\n \nmkdir -p /dbfs/FileStore/tables/mortgage\nmkdir -p /dbfs/FileStore/tables/mortgage_parquet_gpu/perf\nmkdir /dbfs/FileStore/tables/mortgage_parquet_gpu/acq\nmkdir /dbfs/FileStore/tables/mortgage_parquet_gpu/output\n \ntar xfvz /Users//mortgage_2000.tgz --directory /dbfs/FileStore/tables/mortgage\n"],"metadata":{},"outputs":[],"execution_count":1},{"cell_type":"code","source":["import time\nfrom pyspark import broadcast\nfrom pyspark.sql import SparkSession\nfrom pyspark.sql.functions import *\nfrom pyspark.sql.types import *\n\ndef _get_quarter_from_csv_file_name():\n return substring_index(substring_index(input_file_name(), '.', 1), '_', -1)\n\n_csv_perf_schema = StructType([\n StructField('loan_id', LongType()),\n StructField('monthly_reporting_period', StringType()),\n StructField('servicer', StringType()),\n StructField('interest_rate', DoubleType()),\n StructField('current_actual_upb', DoubleType()),\n StructField('loan_age', DoubleType()),\n StructField('remaining_months_to_legal_maturity', DoubleType()),\n StructField('adj_remaining_months_to_maturity', DoubleType()),\n StructField('maturity_date', StringType()),\n StructField('msa', DoubleType()),\n StructField('current_loan_delinquency_status', IntegerType()),\n StructField('mod_flag', StringType()),\n StructField('zero_balance_code', StringType()),\n StructField('zero_balance_effective_date', StringType()),\n StructField('last_paid_installment_date', StringType()),\n StructField('foreclosed_after', StringType()),\n StructField('disposition_date', StringType()),\n StructField('foreclosure_costs', DoubleType()),\n StructField('prop_preservation_and_repair_costs', DoubleType()),\n StructField('asset_recovery_costs', DoubleType()),\n StructField('misc_holding_expenses', DoubleType()),\n StructField('holding_taxes', DoubleType()),\n StructField('net_sale_proceeds', DoubleType()),\n StructField('credit_enhancement_proceeds', DoubleType()),\n StructField('repurchase_make_whole_proceeds', StringType()),\n StructField('other_foreclosure_proceeds', DoubleType()),\n StructField('non_interest_bearing_upb', DoubleType()),\n StructField('principal_forgiveness_upb', StringType()),\n StructField('repurchase_make_whole_proceeds_flag', StringType()),\n StructField('foreclosure_principal_write_off_amount', StringType()),\n StructField('servicing_activity_indicator', StringType())])\n_csv_acq_schema = StructType([\n StructField('loan_id', LongType()),\n StructField('orig_channel', StringType()),\n StructField('seller_name', StringType()),\n StructField('orig_interest_rate', DoubleType()),\n StructField('orig_upb', IntegerType()),\n StructField('orig_loan_term', IntegerType()),\n StructField('orig_date', StringType()),\n StructField('first_pay_date', StringType()),\n StructField('orig_ltv', DoubleType()),\n StructField('orig_cltv', DoubleType()),\n StructField('num_borrowers', DoubleType()),\n StructField('dti', DoubleType()),\n StructField('borrower_credit_score', DoubleType()),\n StructField('first_home_buyer', StringType()),\n StructField('loan_purpose', StringType()),\n StructField('property_type', StringType()),\n StructField('num_units', IntegerType()),\n StructField('occupancy_status', StringType()),\n StructField('property_state', StringType()),\n StructField('zip', IntegerType()),\n StructField('mortgage_insurance_percent', DoubleType()),\n StructField('product_type', StringType()),\n StructField('coborrow_credit_score', DoubleType()),\n StructField('mortgage_insurance_type', DoubleType()),\n StructField('relocation_mortgage_indicator', StringType())])\n\ndef read_perf_csv(spark, path):\n return spark.read.format('csv') \\\n .option('nullValue', '') \\\n .option('header', 'false') \\\n .option('delimiter', '|') \\\n .schema(_csv_perf_schema) \\\n .load(path) \\\n .withColumn('quarter', _get_quarter_from_csv_file_name())\n\ndef read_acq_csv(spark, path):\n return spark.read.format('csv') \\\n .option('nullValue', '') \\\n .option('header', 'false') \\\n .option('delimiter', '|') \\\n .schema(_csv_acq_schema) \\\n .load(path) \\\n .withColumn('quarter', _get_quarter_from_csv_file_name())\n\ndef _parse_dates(perf):\n return perf \\\n .withColumn('monthly_reporting_period', to_date(col('monthly_reporting_period'), 'MM/dd/yyyy')) \\\n .withColumn('monthly_reporting_period_month', month(col('monthly_reporting_period'))) \\\n .withColumn('monthly_reporting_period_year', year(col('monthly_reporting_period'))) \\\n .withColumn('monthly_reporting_period_day', dayofmonth(col('monthly_reporting_period'))) \\\n .withColumn('last_paid_installment_date', to_date(col('last_paid_installment_date'), 'MM/dd/yyyy')) \\\n .withColumn('foreclosed_after', to_date(col('foreclosed_after'), 'MM/dd/yyyy')) \\\n .withColumn('disposition_date', to_date(col('disposition_date'), 'MM/dd/yyyy')) \\\n .withColumn('maturity_date', to_date(col('maturity_date'), 'MM/yyyy')) \\\n .withColumn('zero_balance_effective_date', to_date(col('zero_balance_effective_date'), 'MM/yyyy'))\n\ndef _create_perf_deliquency(spark, perf):\n aggDF = perf.select(\n col(\"quarter\"),\n col(\"loan_id\"),\n col(\"current_loan_delinquency_status\"),\n when(col(\"current_loan_delinquency_status\") >= 1, col(\"monthly_reporting_period\")).alias(\"delinquency_30\"),\n when(col(\"current_loan_delinquency_status\") >= 3, col(\"monthly_reporting_period\")).alias(\"delinquency_90\"),\n when(col(\"current_loan_delinquency_status\") >= 6, col(\"monthly_reporting_period\")).alias(\"delinquency_180\")) \\\n .groupBy(\"quarter\", \"loan_id\") \\\n .agg(\n max(\"current_loan_delinquency_status\").alias(\"delinquency_12\"),\n min(\"delinquency_30\").alias(\"delinquency_30\"),\n min(\"delinquency_90\").alias(\"delinquency_90\"),\n min(\"delinquency_180\").alias(\"delinquency_180\")) \\\n .select(\n col(\"quarter\"),\n col(\"loan_id\"),\n (col(\"delinquency_12\") >= 1).alias(\"ever_30\"),\n (col(\"delinquency_12\") >= 3).alias(\"ever_90\"),\n (col(\"delinquency_12\") >= 6).alias(\"ever_180\"),\n col(\"delinquency_30\"),\n col(\"delinquency_90\"),\n col(\"delinquency_180\"))\n joinedDf = perf \\\n .withColumnRenamed(\"monthly_reporting_period\", \"timestamp\") \\\n .withColumnRenamed(\"monthly_reporting_period_month\", \"timestamp_month\") \\\n .withColumnRenamed(\"monthly_reporting_period_year\", \"timestamp_year\") \\\n .withColumnRenamed(\"current_loan_delinquency_status\", \"delinquency_12\") \\\n .withColumnRenamed(\"current_actual_upb\", \"upb_12\") \\\n .select(\"quarter\", \"loan_id\", \"timestamp\", \"delinquency_12\", \"upb_12\", \"timestamp_month\", \"timestamp_year\") \\\n .join(aggDF, [\"loan_id\", \"quarter\"], \"left_outer\")\n\n # calculate the 12 month delinquency and upb values\n months = 12\n monthArray = [lit(x) for x in range(0, 12)]\n # explode on a small amount of data is actually slightly more efficient than a cross join\n testDf = joinedDf \\\n .withColumn(\"month_y\", explode(array(monthArray))) \\\n .select(\n col(\"quarter\"),\n floor(((col(\"timestamp_year\") * 12 + col(\"timestamp_month\")) - 24000) / months).alias(\"josh_mody\"),\n floor(((col(\"timestamp_year\") * 12 + col(\"timestamp_month\")) - 24000 - col(\"month_y\")) / months).alias(\"josh_mody_n\"),\n col(\"ever_30\"),\n col(\"ever_90\"),\n col(\"ever_180\"),\n col(\"delinquency_30\"),\n col(\"delinquency_90\"),\n col(\"delinquency_180\"),\n col(\"loan_id\"),\n col(\"month_y\"),\n col(\"delinquency_12\"),\n col(\"upb_12\")) \\\n .groupBy(\"quarter\", \"loan_id\", \"josh_mody_n\", \"ever_30\", \"ever_90\", \"ever_180\", \"delinquency_30\", \"delinquency_90\", \"delinquency_180\", \"month_y\") \\\n .agg(max(\"delinquency_12\").alias(\"delinquency_12\"), min(\"upb_12\").alias(\"upb_12\")) \\\n .withColumn(\"timestamp_year\", floor((lit(24000) + (col(\"josh_mody_n\") * lit(months)) + (col(\"month_y\") - 1)) / lit(12))) \\\n .selectExpr('*', 'pmod(24000 + (josh_mody_n * {}) + month_y, 12) as timestamp_month_tmp'.format(months)) \\\n .withColumn(\"timestamp_month\", when(col(\"timestamp_month_tmp\") == lit(0), lit(12)).otherwise(col(\"timestamp_month_tmp\"))) \\\n .withColumn(\"delinquency_12\", ((col(\"delinquency_12\") > 3).cast(\"int\") + (col(\"upb_12\") == 0).cast(\"int\")).alias(\"delinquency_12\")) \\\n .drop(\"timestamp_month_tmp\", \"josh_mody_n\", \"month_y\")\n\n return perf.withColumnRenamed(\"monthly_reporting_period_month\", \"timestamp_month\") \\\n .withColumnRenamed(\"monthly_reporting_period_year\", \"timestamp_year\") \\\n .join(testDf, [\"quarter\", \"loan_id\", \"timestamp_year\", \"timestamp_month\"], \"left\") \\\n .drop(\"timestamp_year\", \"timestamp_month\")\n\n_name_mapping = [\n (\"WITMER FUNDING, LLC\", \"Witmer\"),\n (\"WELLS FARGO CREDIT RISK TRANSFER SECURITIES TRUST 2015\", \"Wells Fargo\"),\n (\"WELLS FARGO BANK, NA\" , \"Wells Fargo\"),\n (\"WELLS FARGO BANK, N.A.\" , \"Wells Fargo\"),\n (\"WELLS FARGO BANK, NA\" , \"Wells Fargo\"),\n (\"USAA FEDERAL SAVINGS BANK\" , \"USAA\"),\n (\"UNITED SHORE FINANCIAL SERVICES, LLC D\\\\/B\\\\/A UNITED WHOLESALE MORTGAGE\" , \"United Seq(e\"),\n (\"U.S. BANK N.A.\" , \"US Bank\"),\n (\"SUNTRUST MORTGAGE INC.\" , \"Suntrust\"),\n (\"STONEGATE MORTGAGE CORPORATION\" , \"Stonegate Mortgage\"),\n (\"STEARNS LENDING, LLC\" , \"Stearns Lending\"),\n (\"STEARNS LENDING, INC.\" , \"Stearns Lending\"),\n (\"SIERRA PACIFIC MORTGAGE COMPANY, INC.\" , \"Sierra Pacific Mortgage\"),\n (\"REGIONS BANK\" , \"Regions\"),\n (\"RBC MORTGAGE COMPANY\" , \"RBC\"),\n (\"QUICKEN LOANS INC.\" , \"Quicken Loans\"),\n (\"PULTE MORTGAGE, L.L.C.\" , \"Pulte Mortgage\"),\n (\"PROVIDENT FUNDING ASSOCIATES, L.P.\" , \"Provident Funding\"),\n (\"PROSPECT MORTGAGE, LLC\" , \"Prospect Mortgage\"),\n (\"PRINCIPAL RESIDENTIAL MORTGAGE CAPITAL RESOURCES, LLC\" , \"Principal Residential\"),\n (\"PNC BANK, N.A.\" , \"PNC\"),\n (\"PMT CREDIT RISK TRANSFER TRUST 2015-2\" , \"PennyMac\"),\n (\"PHH MORTGAGE CORPORATION\" , \"PHH Mortgage\"),\n (\"PENNYMAC CORP.\" , \"PennyMac\"),\n (\"PACIFIC UNION FINANCIAL, LLC\" , \"Other\"),\n (\"OTHER\" , \"Other\"),\n (\"NYCB MORTGAGE COMPANY, LLC\" , \"NYCB\"),\n (\"NEW YORK COMMUNITY BANK\" , \"NYCB\"),\n (\"NETBANK FUNDING SERVICES\" , \"Netbank\"),\n (\"NATIONSTAR MORTGAGE, LLC\" , \"Nationstar Mortgage\"),\n (\"METLIFE BANK, NA\" , \"Metlife\"),\n (\"LOANDEPOT.COM, LLC\" , \"LoanDepot.com\"),\n (\"J.P. MORGAN MADISON AVENUE SECURITIES TRUST, SERIES 2015-1\" , \"JP Morgan Chase\"),\n (\"J.P. MORGAN MADISON AVENUE SECURITIES TRUST, SERIES 2014-1\" , \"JP Morgan Chase\"),\n (\"JPMORGAN CHASE BANK, NATIONAL ASSOCIATION\" , \"JP Morgan Chase\"),\n (\"JPMORGAN CHASE BANK, NA\" , \"JP Morgan Chase\"),\n (\"JP MORGAN CHASE BANK, NA\" , \"JP Morgan Chase\"),\n (\"IRWIN MORTGAGE, CORPORATION\" , \"Irwin Mortgage\"),\n (\"IMPAC MORTGAGE CORP.\" , \"Impac Mortgage\"),\n (\"HSBC BANK USA, NATIONAL ASSOCIATION\" , \"HSBC\"),\n (\"HOMEWARD RESIDENTIAL, INC.\" , \"Homeward Mortgage\"),\n (\"HOMESTREET BANK\" , \"Other\"),\n (\"HOMEBRIDGE FINANCIAL SERVICES, INC.\" , \"HomeBridge\"),\n (\"HARWOOD STREET FUNDING I, LLC\" , \"Harwood Mortgage\"),\n (\"GUILD MORTGAGE COMPANY\" , \"Guild Mortgage\"),\n (\"GMAC MORTGAGE, LLC (USAA FEDERAL SAVINGS BANK)\" , \"GMAC\"),\n (\"GMAC MORTGAGE, LLC\" , \"GMAC\"),\n (\"GMAC (USAA)\" , \"GMAC\"),\n (\"FREMONT BANK\" , \"Fremont Bank\"),\n (\"FREEDOM MORTGAGE CORP.\" , \"Freedom Mortgage\"),\n (\"FRANKLIN AMERICAN MORTGAGE COMPANY\" , \"Franklin America\"),\n (\"FLEET NATIONAL BANK\" , \"Fleet National\"),\n (\"FLAGSTAR CAPITAL MARKETS CORPORATION\" , \"Flagstar Bank\"),\n (\"FLAGSTAR BANK, FSB\" , \"Flagstar Bank\"),\n (\"FIRST TENNESSEE BANK NATIONAL ASSOCIATION\" , \"Other\"),\n (\"FIFTH THIRD BANK\" , \"Fifth Third Bank\"),\n (\"FEDERAL HOME LOAN BANK OF CHICAGO\" , \"Fedral Home of Chicago\"),\n (\"FDIC, RECEIVER, INDYMAC FEDERAL BANK FSB\" , \"FDIC\"),\n (\"DOWNEY SAVINGS AND LOAN ASSOCIATION, F.A.\" , \"Downey Mortgage\"),\n (\"DITECH FINANCIAL LLC\" , \"Ditech\"),\n (\"CITIMORTGAGE, INC.\" , \"Citi\"),\n (\"CHICAGO MORTGAGE SOLUTIONS DBA INTERFIRST MORTGAGE COMPANY\" , \"Chicago Mortgage\"),\n (\"CHICAGO MORTGAGE SOLUTIONS DBA INTERBANK MORTGAGE COMPANY\" , \"Chicago Mortgage\"),\n (\"CHASE HOME FINANCE, LLC\" , \"JP Morgan Chase\"),\n (\"CHASE HOME FINANCE FRANKLIN AMERICAN MORTGAGE COMPANY\" , \"JP Morgan Chase\"),\n (\"CHASE HOME FINANCE (CIE 1)\" , \"JP Morgan Chase\"),\n (\"CHASE HOME FINANCE\" , \"JP Morgan Chase\"),\n (\"CASHCALL, INC.\" , \"CashCall\"),\n (\"CAPITAL ONE, NATIONAL ASSOCIATION\" , \"Capital One\"),\n (\"CALIBER HOME LOANS, INC.\" , \"Caliber Funding\"),\n (\"BISHOPS GATE RESIDENTIAL MORTGAGE TRUST\" , \"Bishops Gate Mortgage\"),\n (\"BANK OF AMERICA, N.A.\" , \"Bank of America\"),\n (\"AMTRUST BANK\" , \"AmTrust\"),\n (\"AMERISAVE MORTGAGE CORPORATION\" , \"Amerisave\"),\n (\"AMERIHOME MORTGAGE COMPANY, LLC\" , \"AmeriHome Mortgage\"),\n (\"ALLY BANK\" , \"Ally Bank\"),\n (\"ACADEMY MORTGAGE CORPORATION\" , \"Academy Mortgage\"),\n (\"NO CASH-OUT REFINANCE\" , \"OTHER REFINANCE\"),\n (\"REFINANCE - NOT SPECIFIED\" , \"OTHER REFINANCE\"),\n (\"Other REFINANCE\" , \"OTHER REFINANCE\")]\n\ndef _create_acquisition(spark, acq):\n nameMapping = spark.createDataFrame(_name_mapping, [\"from_seller_name\", \"to_seller_name\"])\n return acq.join(nameMapping, col(\"seller_name\") == col(\"from_seller_name\"), \"left\") \\\n .drop(\"from_seller_name\") \\\n .withColumn(\"old_name\", col(\"seller_name\")) \\\n .withColumn(\"seller_name\", coalesce(col(\"to_seller_name\"), col(\"seller_name\"))) \\\n .drop(\"to_seller_name\") \\\n .withColumn(\"orig_date\", to_date(col(\"orig_date\"), \"MM/yyyy\")) \\\n .withColumn(\"first_pay_date\", to_date(col(\"first_pay_date\"), \"MM/yyyy\")) \\\n\ndef run_mortgage(spark, perf, acq):\n parsed_perf = _parse_dates(perf)\n perf_deliqency = _create_perf_deliquency(spark, parsed_perf)\n cleaned_acq = _create_acquisition(spark, acq)\n return perf_deliqency.join(cleaned_acq, [\"loan_id\", \"quarter\"], \"inner\").drop(\"quarter\")"],"metadata":{},"outputs":[],"execution_count":2},{"cell_type":"code","source":["orig_perf_path='dbfs:///FileStore/tables/mortgage/perf/*'\norig_acq_path='dbfs:///FileStore/tables/mortgage/acq/*'\ntmp_perf_path='dbfs:///FileStore/tables/mortgage_parquet_gpu/perf/'\ntmp_acq_path='dbfs:///FileStore/tables/mortgage_parquet_gpu/acq/'\noutput_path='dbfs:///FileStore/tables/mortgage_parquet_gpu/output/'\n\nspark.conf.set('spark.rapids.sql.enabled','true')\nspark.conf.set('spark.rapids.sql.explain', 'ALL')\nspark.conf.set('spark.rapids.sql.incompatibleOps.enabled', 'true')\nspark.conf.set('spark.rapids.sql.batchSizeBytes', '512M')\nspark.conf.set('spark.rapids.sql.reader.batchSizeBytes', '768M')"],"metadata":{},"outputs":[],"execution_count":3},{"cell_type":"code","source":["# Lets transcode the data first\nstart = time.time()\n# we want a few big files instead of lots of small files\nspark.conf.set('spark.sql.files.maxPartitionBytes', '200G')\nacq = read_acq_csv(spark, orig_acq_path)\nacq.repartition(12).write.parquet(tmp_acq_path, mode='overwrite')\nperf = read_perf_csv(spark, orig_perf_path)\nperf.coalesce(96).write.parquet(tmp_perf_path, mode='overwrite')\nend = time.time()\nprint(end - start)"],"metadata":{},"outputs":[],"execution_count":4},{"cell_type":"code","source":["# Now lets actually process the data\\n\",\nstart = time.time()\nspark.conf.set('spark.sql.files.maxPartitionBytes', '1G')\nspark.conf.set('spark.sql.shuffle.partitions', '192')\nperf = spark.read.parquet(tmp_perf_path)\nacq = spark.read.parquet(tmp_acq_path)\nout = run_mortgage(spark, perf, acq)\nout.write.parquet(output_path, mode='overwrite')\nend = time.time()\nprint(end - start)\n"],"metadata":{},"outputs":[],"execution_count":5},{"cell_type":"code","source":[""],"metadata":{},"outputs":[],"execution_count":6}],"metadata":{"name":"gpu-mortgage_kr","notebookId":2710846968050572},"nbformat":4,"nbformat_minor":0} diff --git a/docs/examples.md b/docs/examples.md new file mode 100644 index 00000000000..8cdc8d3c033 --- /dev/null +++ b/docs/examples.md @@ -0,0 +1,15 @@ +--- +layout: page +title: Demos +nav_order: 4 +--- +# Demos + +Example notebooks allow users to test drive "RAPIDS Accelerator for Apache Spark" with public datasets. + +##### [Mortgage ETL Notebook](demo/gpu-mortgage_accelerated.ipynb) [(Dataset)](https://docs.rapids.ai/datasets/mortgage-data) + +##### About the Mortgage Dataset: +Dataset is derived from [Fannie Mae’s Single-Family Loan Performance Data](http://www.fanniemae.com/portal/funding-the-market/data/loan-performance-data.html) with all rights reserved by Fannie Mae. This processed dataset is redistributed with permission and consent from Fannie Mae. + +For the full raw dataset visit [Fannie Mae](http://www.fanniemae.com/portal/funding-the-market/data/loan-performance-data.html) to register for an account and to download. diff --git a/docs/get-started/getting-started-gcp.md b/docs/get-started/getting-started-gcp.md new file mode 100644 index 00000000000..f210134a55e --- /dev/null +++ b/docs/get-started/getting-started-gcp.md @@ -0,0 +1,115 @@ +--- +layout: page +title: GCP Dataproc +nav_order: 2 +parent: Getting-Started +--- + +# Getting started with RAPIDS Accelerator on GCP Dataproc + [Google Cloud Dataproc](https://cloud.google.com/dataproc) is Google Cloud's fully managed Apache Spark and Hadoop service. This guide will walk through the steps to show: + +* [How to spin up a Dataproc Cluster Accelerated by GPU](getting-started-gcp#how-to-spin-up-a-dataproc-cluster-accelerated-by-gpu) +* [Run a sample Pyspark or Scala ETL and XGBoost training Notebooks on a Dataproc Cluster Accelerated by GPU](getting-started-gcp#run-pyspark-and-scala-notebook-a-dataproc-cluster-accelerated-by-gpu) +* [Submit the same sample ETL application as a Spark job to a Dataproc Cluster Accelerated by GPU](getting-started-gcp#submit-spark-jobs-to-a-dataproc-cluster-accelerated-by-gpu) + + + +## How to spin up a Dataproc Cluster Accelerated by GPU + + You can use [Cloud Shell](https://cloud.google.com/shell) to execute shell commands that will create a Dataproc cluster. Cloud Shell contains command line tools for interacting with Google Cloud Platform, including gcloud and gsutil. Alternatively, you can install [GCloud SDK](https://cloud.google.com/sdk/install) on your laptop. From the Cloud Shell, users will need to enable services within your project. Enable the Compute and Dataproc APIs in order to access Dataproc, and enable the Storage API as you’ll need a Google Cloud Storage bucket to house your data. This may take several minutes. +```bash +gcloud services enable compute.googleapis.com +gcloud services enable dataproc.googleapis.com +gcloud services enable storage-api.googleapis.com +``` + +After command line environment is setup, log in to your GCP account. We can now create a Dataproc cluster with configuration mentioned below. +The configuration will allow users to run any of the [notebooks demo](../demo/GCP) on GCP. Alternatively, users can also start a 2*2T4 worker nodes. +* [GPU Driver](https://github.com/GoogleCloudDataproc/initialization-actions/tree/master/gpu) and [RAPIDS Acclerator for Apache Spark](https://github.com/GoogleCloudDataproc/initialization-actions/tree/master/rapids) through initialization actions +* One 8-core master node and 5 32-core worker nodes +* Four NVIDIA T4 to each worker nodes +* [Local SSDs](https://cloud.google.com/dataproc/docs/concepts/compute/dataproc-local-ssds) is recommended to improve IO for Spark scratch places +* Component gateway enabled for accessing Web UIs hosted on the cluster +* Configuration for [GPU scheduling and isolation](/get-started/yarn-gpu.html) + + +```bash + export REGION=[Your Prefer GCP Region] + export GCS_BUCKET=[Your GCS Bucket] + export CLUSTER_NAME=[Your Cluster Name] + export NUM_GPUS=4 + export NUM_WORKERS=5 + +gcloud dataproc clusters create $CLUSTER_NAME \ + --region $REGION \ + --image-version=preview-ubuntu \ + --master-machine-type n1-standard-16 \ + --num-workers $NUM_WORKERS \ + --worker-accelerator type=nvidia-tesla-t4,count=$NUM_GPUS \ + --worker-machine-type n1-highmem-32\ + --num-worker-local-ssds 4 \ + --initialization-actions gs://dataproc-initialization-actions/gpu/install_gpu_driver.sh,gs://dataproc-initialization-actions/rapids/rapids.sh \ + --optional-components=ANACONDA,JUPYTER,ZEPPELIN \ + --metadata gpu-driver-provider="NVIDIA" \ + --metadata rapids-runtime=SPARK \ + --bucket $GCS_BUCKET \ + --enable-component-gateway \ + --properties="^#^spark:spark.yarn.unmanagedAM.enabled=false"` +``` +This may take around 5-15 minutes to complete. You can navigate to Dataproc clusters tab in the Google Cloud Console to see the progress. + +![Dataproc Cluster](../img/dataproc-cluster.png) + +## Run Pyspark and Scala Notebook a Dataproc Cluster Accelerated by GPU +To use notebooks with Dataproc cluster, click on the cluster name under Dataproc cluster tab and navigate to the "Web Interfaces" Tab. Under the "Web Interfaces", click on JupyterLab or Jupyter link to start to use sample [Mortgage ETL on GPU Jupyter Notebook](../demo/GCP/Mortgage-ETL-GPU.ipynb) to process full 17 years [Mortgage data](https://rapidsai.github.io/demos/datasets/mortgage-data). + +![Dataproc Web Interfaces](../img/dataproc-service.png) + +The notebook will first transcode CSV files into Parquet Files and then run a ETL query to prepare the dataset for Training. In the sample notebook, we use 2016 data as evaluation set and the rest as training set, saving to respective GCS location. +First stage with default configuration in notebook should take ~110 seconds (1/3 of CPU execution time with same config) whereas second stage takes ~170 seconds (1/7 of CPU execution time with same config). The notebook depends on pre-compiled [Spark RAPIDS SQL plugin](https://mvnrepository.com/artifact/com.nvidia/rapids-4-spark-parent) and [cuDF](https://mvnrepository.com/artifact/ai.rapids/cudf/0.14), which pre-downloaded by GCP Dataproc [RAPIDS init script](). + +Once data is prepared, we use [Mortgage XGBoost4j Scala Notebook](../demo/GCP/mortgage-xgboost4j-gpu-scala.zpln) in Dataproc Zeppelin service to execute the training job on GPU. NVIDIA Spark team also ship [Spark XGBoost4j](https://github.com/NVIDIA/spark-xgboost) which is based on [DMLC xgboost](https://github.com/dmlc/xgboost). Precompiled [XGBoost4j]() and [XGBoost4j Spark](https://repo1.maven.org/maven2/com/nvidia/xgboost4j-spark_3.0/1.0.0-0.1.0/) library could be downloaded from maven, it is pre downloaded by GCP [RAPIDS init action](https://github.com/GoogleCloudDataproc/initialization-actions/tree/master/rapids). Since GITHUB cannot render zeppelin notebook, we prepared a [Jupyter Notebook with Scala code](../demo/GCP/mortgage-xgboost4j-gpu-scala.ipynb) for you to view code content. + +The training time should be around 480 seconds (1/10 of CPU execution time with same config). Which is shown under cell: +```scala +// Start training +println("\n------ Training ------") +val (xgbClassificationModel, _) = benchmark("train") { + xgbClassifier.fit(trainSet) +} +``` + +## Submit Spark jobs to a Dataproc Cluster Accelerated by GPU +Similar to spark-submit for on-prem clusters, Dataproc supports a Spark applicaton job to be submitted as a dataproc job. The mortgage examples we use above is also available as [spark application](https://github.com/NVIDIA/spark-xgboost-examples/tree/spark-3/examples/apps/scala). After [build the jar files](https://github.com/NVIDIA/spark-xgboost-examples/blob/spark-3/getting-started-guides/building-sample-apps/scala.md) through maven `mvn package -Dcuda.classifier=cuda10-2` + +Then place the jar file `sample_xgboost_apps-0.2.2.jar` under the `gs://$GCS_BUCKET/scala/` folder by `gsutil cp target/sample_xgboost_apps-0.2.2.jar gs://$GCS_BUCKET/scala/`. To do this you can either drag and drop files from your local machine into the GCP storage browser, or use the gsutil cp as shown before to do this from a command line. In the end, we can thereby submit the jar by: +```bash +export GCS_BUCKET= +export CLUSTER_NAME= +export REGION= +export SPARK_NUM_EXECUTORS=20 +export SPARK_EXECUTOR_MEMORY=20G +export SPARK_EXECUTOR_MEMORYOVERHEAD=16G +export SPARK_NUM_CORES_PER_EXECUTOR=7 +export DATA_PATH=gs://${GCS_BUCKET}/mortgage_full + +gcloud dataproc jobs submit spark \ + --cluster=$CLUSTER_NAME \ + --region=$REGION \ + --class=com.nvidia.spark.examples.mortgage.GPUMain \ + --jars=gs://${GCS_BUCKET}/scala/sample_xgboost_apps-0.2.2.jar \ + --properties=spark.executor.cores=${SPARK_NUM_CORES_PER_EXECUTOR},spark.task.cpus=${SPARK_NUM_CORES_PER_EXECUTOR},spark.executor.memory=${SPARK_EXECUTOR_MEMORY},spark.executor.memoryOverhead=${SPARK_EXECUTOR_MEMORYOVERHEAD},spark.executor.resource.gpu.amount=1,spark.task.resource.gpu.amount=1,spark.rapids.sql.hasNans=false,spark.rapids.sql.batchSizeBytes=512M,spark.rapids.sql.reader.batchSizeBytes=768M,spark.rapids.sql.variableFloatAgg.enabled=true,spark.rapids.memory.gpu.pooling.enabled=false \ + -- \ + -dataPath=train::${DATA_PATH}/train \ + -dataPath=trans::${DATA_PATH}/test \ + -format=parquet \ + -numWorkers=${SPARK_NUM_EXECUTORS} \ + -treeMethod=gpu_hist \ + -numRound=100 \ + -maxDepth=8 +``` + +## Dataproc Hub in AI Platform Notebook to Dataproc cluster +With the integration between AI Platform Notebooks and Dataproc. Users can create a [Dataproc Hub notebook](https://cloud.google.com/blog/products/data-analytics/administering-jupyter-notebooks-for-spark-workloads-on-dataproc) from AI platform will can connect to Dataproc cluster through a yaml configuration. + +In future, user will be able to provision a dataproc cluster through DataprocHub notebook. Please use example [pyspark notebooks](../demo/GCP/Mortgage-ETL-GPU.ipynb) to experiment. diff --git a/docs/get-started/getting-started-menu.md b/docs/get-started/getting-started-menu.md new file mode 100644 index 00000000000..b1e60faf3a0 --- /dev/null +++ b/docs/get-started/getting-started-menu.md @@ -0,0 +1,57 @@ +--- +layout: page +title: Getting-Started +nav_order: 2 +has_children: true +permalink: /Getting-Started/ +--- +# Getting Started with the RAPIDS Accelerator for Apache Spark + +Apache Spark 3.0+ lets users provide a plugin that can replace the backend for SQL and DataFrame +operations. This requires no API changes from the user. The plugin will replace SQL operations it +supports with GPU accelerated versions. If an operation is not supported it will fall back to using +the Spark CPU version. Note that the plugin cannot accelerate operations that manipulate RDDs +directly. + +The accelerator library also provides an implementation of Spark's shuffle that can leverage +[UCX](https://www.openucx.org/) to optimize GPU data transfers keeping as much data on the GPU as +possible and bypassing the CPU to do GPU to GPU transfers. + +The GPU accelerated processing plugin does not require the accelerated shuffle implementation. +However, if accelerated SQL processing is not enabled, the shuffle implementation falls back to the +default `SortShuffleManager`. + +To enable GPU processing acceleration you will need: +- Apache Spark 3.0+ +- A spark cluster configured with GPUs that comply with the requirements for the version of + [cudf](https://github.com/rapidsai/cudf). + - One GPU per executor. +- Add the following jars: + - A cudf jar that corresponds to the version of CUDA available on your cluster. + - RAPIDS Spark accelerator plugin jar. +- Set the config `spark.plugins` to `com.nvidia.spark.SQLPlugin` + +## Spark GPU Scheduling Overview +Apache Spark 3.0 now supports GPU scheduling as long as you are using a cluster manager that +supports it. You can have Spark request GPUs and assign them to tasks. The exact configs you use +will vary depending on your cluster manager. Here are a few of the configs: +- Request your executor to have GPUs: + - `--conf spark.executor.resource.gpu.amount=1` +- Specify the number of GPUs per task: + - `--conf spark.task.resource.gpu.amount=1` +- Specify a GPU discovery script (required on YARN and K8S): + - `--conf spark.executor.resource.gpu.discoveryScript=./getGpusResources.sh` + +See the deployment specific sections for more details and restrictions. Note that +`spark.task.resource.gpu.amount` can be a decimal amount, so if you want multiple tasks to be run +on an executor at the same time and assigned to the same GPU you can set this to a decimal value +less than 1. You would want this setting to correspond to the `spark.executor.cores` setting. For +instance, if you have `spark.executor.cores=2` which would allow 2 tasks to run on each executor +and you want those 2 tasks to run on the same GPU then you would set +`spark.task.resource.gpu.amount=0.5`. + +You can also refer to the official Apache Spark documentation. +- [Overview](https://github.com/apache/spark/blob/master/docs/configuration.md#custom-resource-scheduling-and-configuration-overview) +- [Kubernetes specific documentation](https://github.com/apache/spark/blob/master/docs/running-on-kubernetes.md#resource-allocation-and-configuration-overview) +- [Yarn specific documentation](https://github.com/apache/spark/blob/master/docs/running-on-yarn.md#resource-allocation-and-configuration-overview) +- [Standalone specific documentation](https://github.com/apache/spark/blob/master/docs/spark-standalone.md#resource-allocation-and-configuration-overview) \ No newline at end of file diff --git a/docs/get-started/getting-started-with-rapids-accelerator-on-databricks.md b/docs/get-started/getting-started-with-rapids-accelerator-on-databricks.md new file mode 100644 index 00000000000..18bf7b0f8ca --- /dev/null +++ b/docs/get-started/getting-started-with-rapids-accelerator-on-databricks.md @@ -0,0 +1,80 @@ +--- +layout: page +title: Databricks +nav_order: 3 +parent: Getting-Started +--- + +# Getting started with RAPIDS Accelerator on Databricks +This guide will run through how to set up the RAPIDS Accelerator for Apache Spark 3.0 on Databricks. At the end of this guide, the reader will be able to run a sample Apache Spark application that runs on NVIDIA GPUs on Databricks. + +## Prerequisites +* Apache Spark 3.0 running in DataBricks Runtime 7.0 ML with GPU + * AWS: 7.0 ML (includes Apache Spark 3.0.0, GPU, Scala 2.12) + * Azure: 7.0 ML (GPU, Scala 2.12, Spark 3.0.0) + +The number of GPUs per node dictates the number of Spark executors that can run in that node. + +## Start a Databricks Cluster +Create a Databricks cluster by going to Clusters, then clicking “+ Create Cluster”. Ensure the cluster meets the prerequisites above by configuring it as follows: +1. On AWS, make sure to use 7.0 ML (includes Apache Spark 3.0.0, GPU, Scala 2.12), or for Azure, choose 7.0 ML (GPU, Scala 2.12, Spark 3.0.0). +2. Under Autopilot Options, disable auto scaling. +3. Choose the number of workers that matches the number of GPUs you want to use. +4. Select a worker type. On AWS, use nodes with 1 GPU each such as p3.xlarge or g4dn.xlarge. p2 nodes do not meet the architecture requirements for the Spark worker (although they can be used for the driver node). For Azure, choose GPU nodes such as Standard_NC6s_v3 +5. Select the driver type. Generally this can be set to be the same as the worker. + +## Advance Cluster Configuration + +We will need to create an initialization script for the cluster that installs the RAPIDS jars to the cluster. + +1. To create the initialization script, import the initialization script notebook from the repo [generate-init-script.ipynb](../demo/Databricks/) to your workspace. See [Managing Notebooks](https://docs.databricks.com/user-guide/notebooks/notebook-manage.html) on how to import a notebook, then open the notebook. +2. Once you are in the notebook, click the “Run All” button. +3. Ensure that the newly created init.sh script is present in the output from cell 2 and that the contents of the script are correct.. +4. Go back and edit your cluster to configure it to use the init script. To do this, click the “Clusters” button on the left panel, then select your cluster. +5. Click the “Edit” button, then navigate down to the “Advanced Options” section. +Select the “Init Scripts” tab in the advanced options section, and paste the initialization script: `dbfs:/databricks/init_scripts/init.sh`, then click “Add” + +![Init Script](../img/initscript.png) + +6. Now select the “Spark” tab, and paste the following config options into the Spark Config section: + ```bash + spark.plugins com.nvidia.spark.SQLPlugin + spark.sql.parquet.filterPushdown false + spark.rapids.sql.incompatibleOps.enabled true + spark.rapids.memory.pinnedPool.size 2G + spark.locality.wait 0s + spark.hadoop.mapreduce.fileoutputcommitter.algorithm.version 2 + spark.executor.extraJavaOptions "-Dai.rapids.cudf.prefer-pinned=true" + ``` + +![Spark Config](../img/sparkconfig.png) + +7. Once you’ve added the Spark config, click “Confirm and Restart”. +8. Once the cluster comes back up, it is now enabled for GPU-accelerated Spark with RAPIDS and cuDF. + +## Import the GPU Mortgage Example Notebook +Import the example [notebook](../demo/gpu-mortgage_accelerated.ipynb) from the repo into your workspace, then open the notebook. +Modify the first cell to point to your workspace, and download a larger dataset if needed. You can find the links to the datasets at [docs.rapids.ai](https://docs.rapids.ai/datasets/mortgage-data) + +```bash +%sh + +wget http://rapidsai-data.s3-website.us-east-2.amazonaws.com/notebook-mortgage-data/mortgage_2000.tgz -P /Users// + +mkdir -p /dbfs/FileStore/tables/mortgage +mkdir -p /dbfs/FileStore/tables/mortgage_parquet_gpu/perf +mkdir /dbfs/FileStore/tables/mortgage_parquet_gpu/acq +mkdir /dbfs/FileStore/tables/mortgage_parquet_gpu/output + +tar xfvz /Users//mortgage_2000.tgz --directory /dbfs/FileStore/tables/mortgage +``` + +In Cell 3, update the data paths if necessary. The example notebook merges the columns and prepares the data for XGoost training. The temp and final output results are written back to the dbfs +```bash +orig_perf_path='dbfs:///FileStore/tables/mortgage/perf/*' +orig_acq_path='dbfs:///FileStore/tables/mortgage/acq/*' +tmp_perf_path='dbfs:///FileStore/tables/mortgage_parquet_gpu/perf/' +tmp_acq_path='dbfs:///FileStore/tables/mortgage_parquet_gpu/acq/' +output_path='dbfs:///FileStore/tables/mortgage_parquet_gpu/output/' +``` +Run the notebook by clicking “Run All” diff --git a/docs/getting-started.md b/docs/get-started/getting-started.md similarity index 83% rename from docs/getting-started.md rename to docs/get-started/getting-started.md index 0da71c9c7a9..43bf17ef79d 100644 --- a/docs/getting-started.md +++ b/docs/get-started/getting-started.md @@ -1,42 +1,21 @@ --- -layout: default -title: Getting Started -nav_order: 2 +layout: page +title: On-Prem +nav_order: 1 +parent: Getting-Started --- +# Getting Started with RAPIDS Accelerator with on premise cluster or local mode +## Spark Deployment Methods +The way you decide to deploy Spark affects the steps you must take to install and setup Spark and +the RAPIDS Accelerator for Apache Spark. The primary methods of deploy Spark are: +- Local mode - this is for dev/testing only, not for production +- Standalone Mode +- On a YARN cluster +- On a Kubernetes cluster -# Getting Started with the RAPIDS Accelerator for Apache Spark - -## Overview -The RAPIDS Accelerator for Apache Spark leverages GPUs to accelerate processing via the -[RAPIDS libraries](http://rapids.ai). - -Apache Spark 3.0+ lets users provide a plugin that can replace the backend for SQL and DataFrame -operations. This requires no API changes from the user. The plugin will replace SQL operations it -supports with GPU accelerated versions. If an operation is not supported it will fall back to using -the Spark CPU version. Note that the plugin cannot accelerate operations that manipulate RDDs -directly. - -The accelerator library also provides an implementation of Spark's shuffle that can leverage -[UCX](https://www.openucx.org/) to optimize GPU data transfers keeping as much data on the GPU as -possible and bypassing the CPU to do GPU to GPU transfers. - -The GPU accelerated processing plugin does not require the accelerated shuffle implementation. -However, if accelerated SQL processing is not enabled, the shuffle implementation falls back to the -default `SortShuffleManager`. - -To enable GPU processing acceleration you will need: -- Apache Spark 3.0+ -- A spark cluster configured with GPUs that comply with the requirements for the version of - [cudf](https://github.com/rapidsai/cudf). - - One GPU per executor. -- Add the following jars: - - A cudf jar that corresponds to the version of CUDA available on your cluster. - - RAPIDS Spark accelerator plugin jar. -- Set the config `spark.plugins` to `com.nvidia.spark.SQLPlugin` - -## Prerequisites -Each node where you are running Spark needs to have the following installed. If you are running +## Apache Spark Setup for GPU +Each GPU node where you are running Spark needs to have the following installed. If you are running with Docker on Kubernetes then skip these as you will do this as part of the docker build. - Install Java 8 - note jdk11 is supported by Spark, but we have been building and testing with jdk8, so we suggest using that for now. @@ -53,39 +32,6 @@ with Docker on Kubernetes then skip these as you will do this as part of the doc - `sudo apt-get update` - `sudo apt-get -y install cuda` -## Spark GPU Scheduling Overview -Apache Spark 3.0 now supports GPU scheduling as long as you are using a cluster manager that -supports it. You can have Spark request GPUs and assign them to tasks. The exact configs you use -will vary depending on your cluster manager. Here are a few of the configs: -- Request your executor to have GPUs: - - `--conf spark.executor.resource.gpu.amount=1` -- Specify the number of GPUs per task: - - `--conf spark.task.resource.gpu.amount=1` -- Specify a GPU discovery script (required on YARN and K8S): - - `--conf spark.executor.resource.gpu.discoveryScript=./getGpusResources.sh` - -See the deployment specific sections for more details and restrictions. Note that -`spark.task.resource.gpu.amount` can be a decimal amount, so if you want multiple tasks to be run -on an executor at the same time and assigned to the same GPU you can set this to a decimal value -less than 1. You would want this setting to correspond to the `spark.executor.cores` setting. For -instance, if you have `spark.executor.cores=2` which would allow 2 tasks to run on each executor -and you want those 2 tasks to run on the same GPU then you would set -`spark.task.resource.gpu.amount=0.5`. - -You can also refer to the official Apache Spark documentation. -- [Overview](https://github.com/apache/spark/blob/master/docs/configuration.md#custom-resource-scheduling-and-configuration-overview) -- [Kubernetes specific documentation](https://github.com/apache/spark/blob/master/docs/running-on-kubernetes.md#resource-allocation-and-configuration-overview) -- [Yarn specific documentation](https://github.com/apache/spark/blob/master/docs/running-on-yarn.md#resource-allocation-and-configuration-overview) -- [Standalone specific documentation](https://github.com/apache/spark/blob/master/docs/spark-standalone.md#resource-allocation-and-configuration-overview) - -## Spark Deployment Methods -The way you decide to deploy Spark affects the steps you must take to install and setup Spark and -the RAPIDS Accelerator for Apache Spark. The primary methods of deploy Spark are: -- Local mode - this is for dev/testing only, not for production -- Standalone Mode -- On a YARN cluster -- On a Kubernetes cluster - Below are sections on installing Spark and the RAPIDS Accelerator on a single node, you may want to read the deployment method sections before doing any installations. @@ -96,8 +42,8 @@ scala version 2.12 is currently supported by the accelerator. ## Download the RAPIDS jars The [accelerator](https://mvnrepository.com/artifact/com.nvidia/rapids-4-spark_2.12) and -[cudf](https://mvnrepository.com/artifact/ai.rapids/cudf) jars are available in -[maven central](https://mvnrepository.com/search?q=ai.rapids) +[cudf](https://mvnrepository.com/artifact/ai.rapids/cudf) jars are available in the +[download](/docs/version/stable-release#download) section. Download the RAPIDS Accelerator for Apache Spark plugin jar. Then download the version of the cudf jar that your version of the accelerator depends on. Each cudf jar is for a specific version of @@ -132,7 +78,7 @@ directory as the plugin jars (`/opt/sparkRapidsPlugin` in the example). This is for testing/dev setup only. It is not to be used in production. In this mode Spark runs everything in a single process on a single node. - [Install Spark](#install-spark) -- [Install the RAPIDS jars](#install-the-rapids-jars) +- [Install the RAPIDS jars](#download-the-rapids-jars) - Launch your Spark shell session Default configs usually work fine in local mode. The required changes are setting the config @@ -164,7 +110,7 @@ Spark Standalone mode requires starting the Spark master and worker(s). You can machine or multiple machines for distributed setup. The first step is to [Install Spark](#install-spark), the -[RAPIDS Accelerator for Spark jars](#install-the-rapids-jars), and the +[RAPIDS Accelerator for Spark jars](#download-the-rapids-jars), and the [GPU discovery script](#install-the-gpu-discovery-script) on all the nodes you want to use. After that choose one of the nodes to be your master node and start the master. Note that the master process does **not** need a GPU to function properly. @@ -227,7 +173,7 @@ $SPARK_HOME/bin/spark-shell \ ## Running on YARN YARN requires you to [Install Spark](#install-spark), the -[RAPIDS Accelerator for Spark jars](#install-the-rapids-jars), and the +[RAPIDS Accelerator for Spark jars](#download-the-rapids-jars), and the [GPU discovery script](#install-the-gpu-discovery-script) on a launcher node. YARN handles shipping them to the cluster nodes as needed. If you want to use the GPU scheduling feature in Spark it requires YARN version >= 2.10 or >= 3.1.1 and ideally you would use >= 3.1.3 in order to @@ -249,7 +195,7 @@ use - either 3.x or 2.x. - Configure YARN to support [GPU scheduling and isolation](https://hadoop.apache.org/docs/r3.1.3/hadoop-yarn/hadoop-yarn-site/UsingGpus.html). - Install [Spark](#install-spark), the - [RAPIDS Accelerator for Spark jars](#install-the-rapids-jars), and the + [RAPIDS Accelerator for Spark jars](#download-the-rapids-jars), and the [GPU discovery script](#install-the-gpu-discovery-script) on the node from which you are launching your Spark application. - Use the following configuration settings when running Spark on YARN, changing the amounts as @@ -278,7 +224,7 @@ $SPARK_HOME/bin/spark-shell \ - Configure YARN to support [GPU scheduling and isolation](https://hadoop.apache.org/docs/r2.10.0/hadoop-yarn/hadoop-yarn-site/ResourceProfiles.html) - Install [Spark](#install-spark), the - [RAPIDS Accelerator for Spark jars](#install-the-rapids-jars), and the + [RAPIDS Accelerator for Spark jars](#download-the-rapids-jars), and the [GPU discovery script](#install-the-gpu-discovery-script) on the node from which you are launching your Spark application. - Use the following configs when running Spark on YARN, changing the amounts as necessary: @@ -311,7 +257,7 @@ accessing a GPU at once. Note it does not matter if GPU scheduling support is en - Foreach GPU index set it to `EXCLUSIVE_PROCESS` mode: - `nvidia-smi -c EXCLUSIVE_PROCESS -i $index` - Install [Spark](#install-spark), the - [RAPIDS Accelerator for Spark jars](#install-the-rapids-jars), and the + [RAPIDS Accelerator for Spark jars](#download-the-rapids-jars), and the [GPU discovery script](#install-the-gpu-discovery-script) on the node from which you are launching your Spark application. - Use the following configs when running Spark on YARN. Note that we are configuring a resource @@ -349,7 +295,7 @@ This assumes you have Kubernetes already installed and setup. These instruction to setup a Kubernetes cluster. - Install [Spark](#install-spark), the - [RAPIDS Accelerator for Spark jars](#install-the-rapids-jars), and the + [RAPIDS Accelerator for Spark jars](#download-the-rapids-jars), and the [GPU discovery script](#install-the-gpu-discovery-script) on the node from which you are going to build your Docker image. Note that you can download these into a local directory and untar the Spark `.tar.gz` rather than installing into a location on the machine. @@ -382,7 +328,7 @@ $SPARK_HOME/bin/spark-shell \ ``` ## RAPIDS Accelerator Configuration and Tuning -Most of what you need you can get from [tuning guide](./tuning-guide.md). +Most of what you need you can get from [tuning guide](../tuning-guide). The following configs will hep you to get started but must be configured based on your cluster and application. @@ -427,7 +373,7 @@ operation “count at ...”, you should see the graph of Spark Execs and some o the label Gpu... For instance, in the screenshot below you will see `GpuRowToColumn`, `GpuFilter`, and `GpuColumnarExchange`. Those correspond to operations that run on the GPU. -![Join Example on Spark SQL UI](img/join-sql-ui-example.png) +![Join Example on Spark SQL UI](../img/join-sql-ui-example.png) ## Advanced Configuration diff --git a/docs/get-started/yarn-gpu.md b/docs/get-started/yarn-gpu.md new file mode 100644 index 00000000000..462b9dc593b --- /dev/null +++ b/docs/get-started/yarn-gpu.md @@ -0,0 +1,120 @@ +--- +layout: page +title: yarn-gpu +nav_exclude: true +--- + +## Spark3 GPU Configuration Guide on Yarn 3.2.1 + +Following files recommended to be configured to enable GPU scheduling on Yarn 3.2.1 and later. + +GPU resource discovery script - `/usr/lib/spark/scripts/gpu/getGpusResources.sh`: +```bash +mkdir -p /usr/lib/spark/scripts/gpu/ +cd /usr/lib/spark/scripts/gpu/ +wget https://raw.githubusercontent.com/apache/spark/master/examples/src/main/scripts/getGpusResources.sh +chmod a+rwx -R /usr/lib/spark/scripts/gpu/ +``` + +Spark config - `/etc/spark/conf/spark-default.conf`: +```bash +spark.rapids.sql.concurrentGpuTasks=2 +spark.executor.resource.gpu.amount=1 +spark.executor.cores=8 +spark.task.cpus=1 +spark.task.resource.gpu.amount=0.125 +spark.rapids.memory.pinnedPool.size=2G +spark.executor.memoryOverhead=2G +spark.plugins=com.nvidia.spark.SQLPlugin +spark.executor.extraJavaOptions='-Dai.rapids.cudf.prefer-pinned=true' +spark.locality.wait=0s +spark.executor.resource.gpu.discoveryScript=/usr/lib/spark/scripts/gpu/getGpusResources.sh # this match the location of discovery script +spark.sql.shuffle.partitions=40 +spark.sql.files.maxPartitionBytes=512m +``` + +Yarn Scheduler config - `/etc/hadoop/conf/capacity-scheduler.xml`: +```xml + + + yarn.scheduler.capacity.resource-calculator + org.apache.hadoop.yarn.util.resource.DominantResourceCalculator + + +``` + +Yarn config - `/etc/hadoop/conf/yarn-site.xml`: +```xml + + + yarn.nodemanager.resource-plugins + yarn.io/gpu + + + yarn.resource-types + yarn.io/gpu + + + yarn.nodemanager.resource-plugins.gpu.allowed-gpu-devices + auto + + + yarn.nodemanager.resource-plugins.gpu.path-to-discovery-executables + /usr/bin + + + yarn.nodemanager.linux-container-executor.cgroups.mount + true + + + yarn.nodemanager.linux-container-executor.cgroups.mount-path + /sys/fs/cgroup + + + yarn.nodemanager.linux-container-executor.cgroups.hierarchy + yarn + + + yarn.nodemanager.container-executor.class + org.apache.hadoop.yarn.server.nodemanager.LinuxContainerExecutor + + + yarn.nodemanager.linux-container-executor.group + yarn + + +``` + +`/etc/hadoop/conf/container-executor.cfg` - user yarn as service account: +```bash +yarn.nodemanager.linux-container-executor.group=yarn + +#--Original container-exectuor.cfg Content-- + +[gpu] +module.enabled=true +[cgroups] +root=/sys/fs/cgroup +yarn-hierarchy=yarn +``` + +Need to share node manager local dir to all user, run below in bash: +```bash +chmod a+rwx -R /sys/fs/cgroup/cpu,cpuacct +chmod a+rwx -R /sys/fs/cgroup/devices +local_dirs=$(bdconfig get_property_value \ + --configuration_file /etc/hadoop/conf/yarn-site.xml \ + --name yarn.nodemanager.local-dirs 2>/dev/null) +mod_local_dirs=${local_dirs//\,/ } +chmod a+rwx -R ${mod_local_dirs} +``` + +In the end, restart node manager and resource manager service: +On all workers: +```bash +sudo systemctl restart hadoop-yarn-nodemanager.service +``` +On all masters: +```bash +sudo systemctl restart hadoop-yarn-resourcemanager.service +``` diff --git a/docs/img/dataproc-cluster.png b/docs/img/dataproc-cluster.png new file mode 100644 index 0000000000000000000000000000000000000000..87f3ea409138903302fb4326017165efb0855c95 GIT binary patch literal 47130 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 xG6@Zl6pj~Z>N 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¨C@S6txd<6CqYw znrLi`C$8;jfh{81I}Bln6@Pp-@ zGfD&@^}FCMgke~zgllfq{qD4fy%~tL_%Zh+`R&{FA^uC8mybxOw!Jk`r;khS`ZwDz ze4S%6R(kNGo1j2I;a?8GCQ>Kr3FQ-Bd$EXEt%dXT-xR`SmdyA;No+oN3L9vS@3Qzc zsy}GR=dijDA62Y2Xc0)JtdX;~Py884VU-L5c;KjV_3AE*kMSBw!7Qd@nL5gaoKWu{ z5=C0_V)a-=de1uZvtriFGTnM(orXiYA*FY65SbAXC?|w-1T)1%*3VX20Vqs|xJ>`2 z>%%1yJv%ytfw2F;i|9CX<=Umi`b>tLkCz*0X;SqR|$wloC^U)#Vbq3p1`|&K;HhsZ%D^_GyX7avq<7=K17f>*eyjVM=;=VOyo=PjYV{ zg}SNFm`oyC(^^u+NwST-(*k{ASH?WFd0PY5AE5EkZx%Vy^5%FcL*oPn&wADL4RdH9 zT}=WaGRO7Vf!M*Iz;<1Xu$+C~0HD7g`jJ*AQCplw2d+|(#aKw?QAGj8ld=dbRGruo z68fHme0C91^>v|j;po22AsqFRV=J5YGeCYNe>&faeevhW6E<#$6*#XU=|_7o$T{(O zSXjY_iQ%08<{VcSbDhoY#KegHwyq#Ix9jaULo|rm)vD~b!F4Qn;l1(5Hl1?Zx=UyG zcolio?VU(*fEW!?SK*!OdjQ{V_;)A{kn2$*n^-JHV9^e|^d~xC`WW{*B6qu5rn*Ih zBm@jd=-uY?den?4e5LH9+_p-fHcz65?VA~SDA78oTm?c6=}Sn3>Q;E!yH3(AZJbH7 z7jJv;oA;-^?YlCU(y!525VnjDqZ#QGeO^vZby*a>G<{NZG&YKO%)TauQ$L=wi*Due zn)O>{F*yGTMeobd9s0pf+W;nn@>iKvW zH)ww~6pS?HQ&FwZBqQ=vCgrr?jkQe>Tkiwx92lv@Od~g3PX|0Q^Msp)irS0cHq?Uo zZqugXQRy2)_Z}3jbXc3fHfUAmfvs7z^BM|GGgQq2Oq*9xyvKGuNEh;i>AF@y zSx~+yuI2`~;TE*1s%$mMIOt3O1EOo+N8*30FM;kUN>TyL+2hF!pkNT~I@5CtBApQF zslC4sONg9~_pH0%afoic{T9kX*$^WMmxBeVVle9tSXsZGv+4O?*&~bdwH5afc5u@w zDES%9G2~g9h#X6A*3Qcq25UGVbTFKe5jsgoEIGkCy*w5jpxcmRe-Hgj*BQ@5g+o(Y4_GV`Cc*J=J%e^mu+;C1Cekw!NoPQ!JF)7; zl{=>*&8JZCNO&(hm|M&;{{~HVTfxCJ*e08{0>PYq3{2fRAk*iE7)e)F#u~QjABM@1 z>Nx2MEp!g4QLbHG7)9xLQXZb+e3M*SD3vMkKtZicnyTcfO;T(wohRMGAt}2uZL~mr zCg6PYQ?{+=<3&y*X6Vfh#R!twr7fEq(yVVUDkKJo2^1I-2vU^}pGC1x49Rx-osTs+ ztL_`4WLDO2Z$BYFY08#ukVD|nNq7gRSVmDOjPS08EOPV9Oc0Uc=G zIgLC3f)SmETyFDf8#Z@(a5%d^m|`=*Ln5pDqs39WE-cu+`yNeSfUS>RpO6Zz4!zkT#@|y-Rrb!>-2J5z`Obd(1}+0O?M79* zUz@sna=bxO8XSDzM70L9`J`X{t$QCqd2P1rD^mQ#sqJZ$Gu^Eqo5qFv@Ml3VwAp?E zWdgLByH2PT)BI_sjDB7L0tflbgAM3n|Ezf}v{@QmJ&SW@0mS};S)jI&pJ+*&eddbY z#jQ;1SE)Q&)paTIx|kiMr#3T&uC7LDXi!t8k67h4Fo3Mc!L8PYtNwv)u`IMKQ~ztI zde!DNF(5}u+(2(pK(j3p2%{g$4MGdUlfY3kq;Cx7?Vlihdnh-cw6sL_uX`1A89e91 zgyhe@UnwT%T_F&uJ^QOzXy?rs^raF(ke;XhZ`HPr0XntJ?KeIbcKSf&Uf4B;@IhD) zP?;RvYFaZbFgabwNn^;YA9EQL(B-TiA|<~$X=}WP?Xt|TKjYGr|K~L#`X)sR$%0!r zQd$~RZWo~3Y)bz8OJp|tie!9pz$$(u=t*xK?Am(p=#-JfzIzeI!Qr~RQ~mc$>3_@R zfTM>KN-jeV5Jp~z8X*VTI`P2wbyRm=geI6-{8g?0EA9+v`oJhRrKUkoMER%!kjFZ}2I#z}NQa!??pnEY?e z_kaE;#R)l*>jrY6DiiqUoBp~~--bv)x^8%S(LDLx@fQq?r9E&JO`5z<8M@9&S9DOD?~moFXu>%>y*kT$6;*SiyBGp-tL z|IrlxQ8rc(5UhB*2-#YR|9W`f)wSVnp{xI^BmT!*gE};YI{FVZ-z@$3`>TfjdBalg zfl&Iunn}t3BklipVE~C~30*Mcu4=)*om$BL)uwvSC~Nb7qs`w)sxVRdKQgEz)EDLq zQdkss|1cMTrj$!weMiJ>D0cDLkOJ?oZt<_15-Jt$V5^jV{Cv`SlW7eEY?Rd1lc$6E zHrb^SAwmw8Jx-1UGJ7bKrj-6qR9#3*Ji8k=vEfg%#Z;kmG$FszeEnK?@K9y@^L#N2 z?0bCbm6w<6Q7G*&Qmby*w;xo5hT)lhg;(T~Ccl~553`#6tk_fc(KMns8Om@JN4%3g zJU5vPM&$zrQw0QB7^yH~_UOvVTIHPSZYHk-l-%v;#Ud~3(hU2I?Ps+a_|F%|zv_QB zq%ynY4-5!Yl)ry`x#6YUGUBE8QTZzR0Y*`IiaewE z$Vu7_!@+toU)mX%9B4LvS+WkNZ|K)`-%3=Qe>L8J9oEQRtJAa$eAX6C85H+LYN2t- zlZdn~ub;I)21NV!jY^jXAkHP@sX|b#Q51LKu2t!o9}v2j2JA7ezH(06<;DB!Bi_ER z1k~vrKnB^5ijyge0REcyJCzHxCfNzdEu7Z7i< za`F<@b_7)Mg;+^K3*|z&YQR0=>`_zE&a`d4O5z7Zo@*fUxB$d<1s1TsJJuGZ+lK+} zt=Bb>n4-#H*j3NDs_S}3tA4WF8ouw~ezkA%DiZNuO)I+%)lACJ&H-z1DQ+^ zrr|2)l-+x`8(FXp$VdOFGU#p@>6;o!X6}}Vz%~FTI|0l)w*cg_7wdP%Hgnk~uyBrJ zmTmxe5x=}1&-$DsZh`o_)=(1tQ5bDS71VpK?9sc=$}pFA(SpxS6SEi`+MVozPWvjq zHsfTifh1-lAg+>l6#2s-0bhiDEd<{ZN?XD2e%YTCawBIBPsVVCvfhyf0Zp-gSUc9> zd^C^q&fF$2DoRk=0NVTMN{wuv^idHRNRl@rUk7ewt5`sPDuVxsXF)6zPT%#YEvdnLo!j1vK zp92Wwc&z%uS_9L>8+d1Cw`ukxAU0vD^V6~VRn$V#$94k3z59c7ZacFMI_;Gtm6F2R zMv?4?uNjOfu!^Qu#r42BblH!&A9?~$ngC?aya0`;CW)U9YV8rQU~DpYoCbBHze5aJ zej)fI>A3p}+C*W4u_e0RMb&Zy}r{&o;&ap0k}vTbntGsxB%h~CkGO_DTvsbqcG6=9^ci9An* zPiS?$u0DG_U4aR}KvZy@kd>>OH|rCu>(Hk-)O&(?_ZXn52rgiG0XnKP@b5uS-C2l- zj}!o*8u|!5tfSx+i*Eqzwx?F^huOW@y~wd`e+-EO9l^lO;aB=Ga>8GBFFA*u!G}8QOXU%gS zJ4sdHvazm&7@Hn=jJ8g{Hh}9|&g#w)fwi+)ZNb>nw?5y7Ujj>l-LUfo+x854U6La-e?gnjV!{N_x$xODP$h>zW_nlvDz`hUql<&|7>6$m=Qg(fBHWVfIz+#!*a%{{a zV()}ZfvpP$#0;2I%%OhBeZWi$$ekj5LpUj5DZ8V(C_Xg-#^sjitv|d)kG-yHb#(`OyQE&ty!B@S`Z4$3$>BS3GQwpOuZ&?i8k(I!PHCBRCcSRoJfX-KZd$1RiRyQPh5Rn*u7kR&7MZ;n*8F+ zD~KCLtAz9;1LG?fDGm1fB}LmKyzd~c+@nR{STA{7COJgC*Vt3lADSi#L3r&%_w@73 zJ5#+0Qf}wWscaTUG%V&1uEGo9BG)_AF7vDeIO#3rO52}RHGXIH0j=04%0Bp9?fd|6 zIJU-^j2xQAsBt?U;4-&d`8V;}!N8yA?v?L{fx&a-f^WY#FP-x!#aUbsm1c16WWysx zbeti%eJcvoe3f3Q_wGWVjY`up-hhxGvwrcJN2&O6IgbKcz$O0)h>YauR@6D;V4n?o zh6>PyW%n~xoMYkOu*L>YoW$-#or}q1wA;fXEDyR*xscRzBnWZ&Ivmj0qP9IrHb?r4<=;yBs3 zi=wvXLdW^V5>8hmwO!Ty{-R~_K4tv2&Uav=PNCSI=jkHf8h$= zK?(no1>|$`ast z5xgp<5GPP$Z%9;JjjNKo;D*dl_9Gnv=8dE!T?L*WR$hLZ;T^kDiYy?5KVMi0RJ`1c z`9!cE#MbN{p4HV*A|BU0^v7)IhI>A$R}%4QYNKmtdEGeQ7nrXfxmC3>rW(5uoO$Y> zMcrV;e(gUM3UKmMpS}5GgzWQN^;2?CKJrTL!&}9Vv7JUy>y-Q+mx-=Jr-(|kz;q4l z8f1~Sc>!pG*qBZ&7yxJI!7)~MEpfM}b#}gbW&~36D(f8d{)*F@qaz-#j7$(knRVQn zuS0xU9-A}sAeCt{3lF0pZ9MHz`5{Xqk05iSj+su6A0v#G-nJM1-e;cH$c)WRVK~l% zLOaSkj2iM7Vr{;TnIcnB)58#n>5e67s&GB-B<1~{Yt$aH1~?SV9=Wo1e@knVdS8UZ+)x`V9VaGXb#h`Z8{zf}zce~bZqGWjdDCnH zi0sP(|A8yeXsiasjnR+dp1GAqAJ0V=D7=h};hZbUo^TGz$c!>?VvQZQQ_SvpoO6+| zYjG+=c}RW)31D;{$O^)x0eH!BbitFXW#wg70>K#76O#vLKKzX&j#OXV+ule|G@56D z-Zl2VQducZFJ%-Cp8~l>mzU=!U}H!5vu+8t2 zM0hNc9=ZA5O=g)>0+Pi5;e^g_zH~KRrtcIx|1QiXIM6VR31ueCXu zxO}r{@7SG`db56K;Cq8@g5j};Ai09ig%-l_$|eVeJ;W8s1QT?;{UWc`BOz@?$nHe% z43VriGj2>6sRJXd>JTz*DMNu>!5rlx3<8u%>wZ^36WbsTsVQViL%f`Cftr~*#!Z>O zZN3{sI10R$TQKD_z2GKaNk$u^D(C+_wb{nFnX>Jcdo-y=dgdnj#XIqy`#kl|o3zs| z?nIy@*mJ{WvVIzB1LQio;idlN-lk!$cL7?4B;HJ`v=${m$k)^_SSjKMQPOA2+O$ZG-Gj!zN;w@u8?saGX>16d6_2-MN zYwJ=_JrlgQf!=UIv9ZFIQn{tg7{Zx|vf!gOxH0;YVx*o`HEK9vXqYgIT12qZnP=2d z^C3XKQu8e>NxUqbUs-2(muhVW2`{%qj)4Z7`b(Z2R=12=y#7~Y7^um~GiJMh0XYy@ zZOAPF7Y3%K_!J3^4^wzfGPYm@Y>blQ6;JtY20;TS9&>;W^0ys@{kN;oOHKpU=G57t zYQ?vH!hWIetOnIj`g`8^<6U)=Q@0VunE4YBOhH3^YBcXc3w*je{(-%*|0^@)!$j|? z?rD0^0RPr{N*`2sFfHP6PMO74_KImuU|&+b4)xh3EcKTe^2@}-=>ga7o|vm1CX*xT zF+L+5PcNKBD|cOkOtv6qVfj)j$|l!atGK!r8m!DA&n_1`LFt3EZfIT$IpIC{xY^9E zyL_-==3f3m=@#};bTJd3D7GTXY*=p7>PWb3+gTcqjHT?MrW}7>#5OvgpDW`WdE9fX zAR?LTy}i$8QoZ&7Uw($W`-AzqA=hQ>71y>9N_`~WcRWF>mVkRYEE{0nqRR zhn=iD$NEbAiPvuMUf!Bgaey1tN|vfi1kL6Ukr(HL(=?e8vL7>=csjpQv0#MqX5ut5 zhGvBf2n+Fz_4@B;+b8+JSh7!Qs&VaSJwnXbwyLV--ugvEvd@D!@zlreIo za9{OnRF6d9;Nq2A%GBR3h$lI<@H-~U)unu!RIIIj6OYt15jv4V1)oXOW%MbegtJTa zr#QMD4?j?Ah;4Nau14g<`81C?{YtO^typi%C()YCWxzj5HI0l1Q!NY+MU_ba!w9@M z$EN73NmcKIcv?}0QF*UJ5Sqx+^z_PVj+pOOvwm*W6+rG!^8Egi3SxI4JhLp_kSs(wj9aKhofCAAakbfNz7ut)XXa z>a9z`7U&_L$P7Pw1Z^~hJU`Fog5SEoTcL(ztyvaVdHpWGo@#Pcx~uj(-V@5Xyhq{2 zo!W)Reoz*{X3-(s0o8g0%BRe;#jo5ew;(M;BhK80PeRPe#A5DDW=3u(M|_<23{_^& z61aTHm+Y=@Ez(Go$aTl=?h9h{Tt~oqQx)dl7dhLDQF5_G7D`HV4FA8@t~xBL^;-ji z(w)*sj3O;PbV-LE>6Y#kB&3lN1qP57Q4G4In?Z&c1f{#X5svsEbnPi^c|P(%m$~~gv-6|YCS489DSTOcp^eWSuF%5w zEy9=6ALsV@1Zw9FhQ%fMXsoL0SyRDNDr!TCe95@`jw9tlA@xkRJKA<4Fc=G6zPH&0 zU~$aP+kSp+VB!|Rr#YW;BlYO<9p%c2`YnO7`|=Oy8S;Gc5!ZPc6o<0Hvj?NL-F2~r z*=_U`kB#|;9=8{&h8vl_w@ali_YM=32@@}wr!$cfs{>fZ1V@>kB@TVN4uUn!6+s-B z*d2aI?USY_*S(N_=3ub=B3BCkBAMqH^p)co-(7)OIdn^P3-yqM=m9vIq7+=7cg*Yt ztp#%7$~-1n`4u8)|0A}C5@wRKqm}~-0sN4mM-l>2^P@_9Rv0Qx(YdWh{4ZH?uM)A4 zUEgB6YaptZ5KI+*m=QL-du`C3?07cVI=6cvu_{=bNe%k`iRAv-;N?I*sdJ|00KCNi zP~LDpo{xx!Rz)o#Z&BTF$-uk+p%Ec-OpUKA5!5nIAy~#&iI*}TII+-yF)}+n+9>oe zNq%lYiNW29Z)Xf`Qph_9_HG|)4sSq`Yqx#sKQHVhk4d2@mV0yV3$?uStC0bl0fxjd z*N6BJ>IbV1TKF&HOZyn2hEXPn@V5WCAd*IfZLxJ-^+a0?&nZQ|Vdh0UliHKMv&dx{ zHi|3cw`(|{iBP1^gioIc>-Z%a_fCVOYk22G(>Bv!hPp# z-q#j8aJH^{5$1;HT~TNxQ)4AdKUBY*rTHU6C}QzrzHDb-MZH~l_`%}I09)M6nxm9r ziA7q?fvnYuvybNjCato`JHXEw93y?f{8gLTgL6z`|EUqy?IXYaL)98D-$U1(`Wtx3jTEJb&Uz}gU{^hydIdeiIoud5laqZ z^5hlYG5SaJFbPEXd2n@qzSRe21F}P#oq469s8Z`9D8q zCL~O;uo}E|BIHw{iv=5xrK%ErN(beWO1xw<;t-=);=_;>m=(4N;SOCS0W7*p$!=LP zSj^94Iq(JEDLi7QzU*zdR>T;#!@{vTZxr^^pnrd)cQLICHMlQoKh%fN6FQV@;|<$d zW`1zwueJLLp$1TO@M9J&8>EBY{Pm%d2&5qFuYnT|Tdu6K`r`H1(EK?-|M}nR1{2a@ z@_5z$-`7E1szy4eFKf6)3vLh)4lS;1eH-&vZ~xov99Epq`vwW$a%H1_X>bsBJI>dW zeD~Jt!zB@d{?DE$51c-iTr~=yPZx2s2(WtN|Le7+F_)Nw#W;)iOEv@py~aTfw%TjV z-`o2}GbeYrUd5N|{OUW>=wI$C&5T*GR7tF&a^vqs@ZX;DYT|qqbrb=iNe8{Q<+QC^ zU`1v2#r$#s)Su8|`zycSmrYaJ!9=w&`o8pU1BLEu5@UM>DRGoh2sAy10OXc?Q61r+ zD#MOUbv{>`wn-96P4$Vi*Fd4%pkF9=(M zcdLh3{fY)Uh8!p1Fr#qdVR_YMg&Z-QdJyye4!nM=OMBWloy-Hz;X~ya0Em|YQfhZ2 zV5PP@D#bH6ou3|kLd67-n(0El7yH?l)J@Sl05oJZc^%54Wr)#qc~R%JKGfTIw%0vo zt-U);A9y_b9dJ{1&jQx2(mrbjIG3H*#rup1&MfyL9*p5MZvGwCpo9uug-o}Hi$?@@>iQC1EANO#0 z-v?ftEEBv|QQrg5=h!tye=}4rnz}OQ+8JP&+JSz0D@-OjTW^sbZ+@E2tM4;j*k2lF zpt*cJ#X}gqULaWd$!~0SUP;-vS5=)uA?FA7+3|dQ6`;qCv85R41PB+4bJJje=GRJq zunFp=IGUi!y{hVq(g<-$L5bC-?4v>?K)h>OXxe|@v1WI`84$jUcC3lk;;?(JU{uV4 z$eC{Do*0qVIw$Azpw!xJl);gO)Z_~K;Z=La4 zA;`g4b#LT^5|#nt@RzB8BjbEtK<2Fj=uWvj2=9oCgDBA^0E0`q5;;!&T1N??JJJBF zMdIUafxbE`(Yb{IcDp&lnxa9NCkU&Q2_T_^->08E5eL881c*CwDf2;uV+ih(D|IcQ z*Xo3c15u%wX}(x9NspzT+rfe7KWaE4t^m2RWYcTg0Eq7ygn~?mp-(QR#hPmrRoGtM zAj@MMWQ0t{gmOei-F;rcAGW{vBYLlP#3IIbH^%tXwCJe7J%s_i-q7cswh_tq*CT*5 zCy^8|*BNsKV=x}&7$O6i~>Zpza zBDB~z7m#yl@t*Y3b;+l7s(3L8(AvNYkTzQ7(I?tz@_3ca(C!V)pMlpBjxT<3JU>}d z_G9hiX?2@O2=7&Tudmuel@7WNqh)VsA4*>O57j^8vrTuZ+TGR%GBOep9^oJWTBNKzORae1oXWrgcv#D@+wUMiz%Q=^nw+kQ%Kr z!Rq&nmaDa{;j%PK3ji(IZCma8pGGY3wzXX^vF;Opl0!_lBOK&uq9vH!u8P?OQjcv8VPa*sz-b zGjNsTuxtkrw^jINU#9q}mppckmLwq4e+L58<6sNTDkhf*B{`tPfa<`bEzZ?)&&FSl zxBofAB8equi1{Hnw-oG(=}wlt7Lk}7>DR3M$-4odH6a9aBK^pYOFpGpD*jZ5oQEC~ zC#0keqt@xY-o0RoooF3PWV~-GLm7{A>RTg;1BcSCNkY~ORFzKN7(p&g0}f%P&)iW0 z0LKmHK}#m7_gYAb1=aZIn5gr#T2I=vrAKK#vHdlOQ7(A#Rl0RJa`=w77f@ z>7>*%3*K0E&5(S+g5kv`9j0;meRHx|%@1FZWQ;yU_W($+9es~fay?m0d1O@phzL`X z+6L*uE?aiHNu+$zwD6J1_xCtxg&b3}=cft9H)g(E^-TI{lK@yS;&2u6X<2_R=*dH4}nsLvMTG-j>vq~|AVvbw*WV|y+ zu=LT2jf?CGFYax3b#lp!x7F@h4y+v{&2#Y`M0ih(q9?zRa&nqO!w9jM>#xOAAzX`y z2in32tRSW|b1I(LN{HT%6H;W?W7*Qs?{Gs>@pn3~lTBrlLU`XZF|I|*Na?=2R=s!+t%@kCP*^k!cYC>xOA&0&bES{ci3!_Ei0U-kAyiQr@ss{!sg}$ zwBtrB)Vxn>D~i_)f32Q{`r*8vAFqqK(L#;}#KAPWw)eZrxFLV*^#jHJ4oD@{vrvkwp8lqZK<%8Xbr#&8fFBx*{o znkdN5?ZKFh47-X;+V+*{d3VUt+8@)fS2^BkZ|;+R#*5y}0!oISekG%{xN15?M01F}!|7L_w%@UAK(Ho-=?Ng{ z!h5f_Js$Cq6l}1OY|RMWWr7sf442?XOSSr(aKpQa5iu-rWj$FW5G1b!7q^2~3`Jvh z4J9*Thh4M2%O`+sQ4_808j^DJ<#On@o>mikXO;&=@+483?mbGyVbeX&iT)0 zjqYFtu*ZfU(&FE~a8-CExIst_bt_nA%1f02dgrHxQ&5~Y%#7aDtn!gwEP8ICJG>rQ z!9g-X1fI|Rt+0n5{NNN9ZH>qbpKW;-)nd{4!%WDvb}`v-LN3t-z(#16SJLmACFwcW zEc&aH4b3ryg_U#T5OJ-WD2Fb9L9e1S)sGCH#pFRx#2n%)9a3h&@JN)d`@D}VnhE1F z@#q!Y`qqL6f0jo|l4^*_`>^bS-0B4%&1+n^DmfpyxNO8|(oqK1$1MBiG2hTn1VTDS|wL z)P_lvi$8I~+~!mfwRB9&kuQfQSC-4mz3OSbHoII{&GC#+GemnwCx0=;lMagxOeC45 zWX4Th{{oF#jZQ=;+F=*nGx}P-v~nV~*Y8Mr?G+Z?h_F%;w6KP#zvhQsd!_df@D?Py z8TQhkmbJ#>TiWxVOxwitglsJ0IA68yRbSQd@?#^93}*fs@R?x!MknqhFJ?Dqx>!#0 zRdWfBD{P@;MEsdv33)K)n@(&Dq4WhFa$&xKvx?{BECt%RQ*#-msRF*%J8!tLGpz;^ zIPI)HtLr*v^EJ=JaVMGAOlBhtB{6-HeXn|)j_uW4fmKZ4^dsjzhD5rb1{H0x_c4+c2+VfOmt*D3iwt1M1LIc_Dm*dvh;Yes#rvMbBQ~?$9R|V?!oLet`JK z+LOv&x#4eWXfC!1tOP8|tF5K1;gF1ZK~tOT2NB1IurtXxdZY`V3KcxmKSLC0`e&a- z=`C}$@!Q;Mg<+NT*b9C_-Rm0n$K2VZrLv2QHFbe8uY6i+jVgv>n5`af1&bBF;*4hvE8;9(ui8s~Djh&< zMi%04E_S#}kGLU)E~eG0H^;Dhrn^$`7YakJ$#nM6a94K?m*kxq1}<$;&*N{#zd|0; z3M9{$D|0{G6aEc-fGGoW8VIUxsr(HX{SBeqiVjK|j{cxA8T)U*CkXpKJNnIHn0|3B z=dXanI|zo33FikfFM(fS3ayuzdG!yh8`g?`0~vC$@A?+LTf3c|egc?%fOzN({Dg|V zo1Qo+2Y?v%36%m27)dFl+*XTJo8Zw}ieky_Dt5-wSfcdk=0yJmHr!?B1vD{~N8t#B z42GBx>!6;Fe*#=S?ueA+GaJe;@tv6feUZ1 z)(*rN^qSrRbw_V7*fxW&L}q7i6b}^|j)NL1wkVZ@?B!Z8BvWIR4$HoWo8!Y5XZxB` zou^MOPp7M<9$hUU&gu15Af*9S5X3l zp;86!;{lzpH_LBJl$O^l=p0N=V1^jJJNU`CfkUAcaKH#6NlkJ5m|4P?BWxTuMoObr zJ+=PX6(2ICf&b@U6gwAPVf!Wb0yb>jo7USRx;jD^<(V^ulY{*#7A3)oa>2#d3(7Zu zLWDP#8{pi!9{FJlC@AM;1&ky^= zw-3rp-MiSngM;JUJWU(EfEC$*f}c)nKw9Ya?9;>bWn8&4Yi*%p4feyui3eI^sC4=! zK@jsK-a;{ejkWcG!HrKjArOI<%2m6PTa=nWh=s#R7R{wXp%?*pu01HfTUe+7&?Eyl zfj1I;oImCBTzJA&j=T7A@HUu_&H7+;K;l4fw3bUtnBSKn=|JuH)U)S;WZ&hfh{fF!%>Z@9K#QH>0!@;KFP zR;6=+GC`7GtOpu5tHx_(mAiKCZZ;fEncOA+3IMs$hF~!4&x#GLTNyEl)&R(|JiHB9 zE#HB2eEJ^X8r7{;07a=0t^!*{$Z@2^_2nk8K&wzbIxc6ya|v%iMy}fnigZVLTOH_Z z$x`+Di>y9VW|36sJ5#`+rbXZ~6Bg)p;5B|`iK)iuXz*U?Z)tb~wz2w(#W;N(Uu!=3-JX|bk}BKJ~_|tX-a&Pi~KZZ&zb#@Y|f{hL@DgH zwI5r-G0@^Vv{Y-27hR%01=CHSic>d@l28~u*mVyJ&Cm2sD<+eFsi>7EC&G^VNK|=$ zsh7Zoj`k?0+Ogt`Vi9%2$x?dJ*W3aYAD!K&WJ1@epk*L0znoJ8s8kejRrJeNfgg;c z6u&f+1LE_a??Wme_F=^3egY=b?%&O9TuPE%X4FKu&0DDZp0YD#P%mcp`(&Z71%1X8 z(u>A3xlcZtCE@pDEWpPiYy{A0=ex?bQ4Cz+yCrY4#h5%9E{r0XSs;Zis_6~9k3;!m z`BnWoQ<+JA0-RG5(NxLZ;9jc(Z@@m^@lqpZd!vq4O!n%1*am-BXL>X*4o7>cBC2rC z@zNb1d>rFm3fVhA>cvSaHqst!5@GfO>@2-{-IK7)Htfuf(3q5D1mow%>;W2o2tN{@swM5*{i6z$)F9Q1oE2<`~@R8Fhl^JCDf( zgUn|Do2e?@xwfn3`_`m5YggmIMJeW9J(G_UNTb_63;?<|HiNrYUuzg)8^dSr4T_B( z3qI!gCrI&4KBz&FyWv2`QnHh-rf)ovbn9gWGuiATY-X>TklYG@sV_4OE!U_8DT}{q zcNC|ePKqj-0l@LVI^j06ij#kcX6gOyK4DbJ=iqsU)P3Iy%Zb{6Jx>{uNt*h>;4bDnX6>?Y)-VU4p zO5~JO6-z9p36YTUYTN3CEoY}gFpY$rcGci zBMuu^o;~+@4WEw9BCOX+>wb#9^~=$w%}c4>H*U;aoq6@}_dRt- z1#*k|adYBm^Kq^FksP2ytuG`zt~XxrBN#(Mrj# zzV-P&2Fj5bssT*$lxC^TA61@0*X?3R_HqevX!99a_n0eUEcUbw{;}}hd19a>D2=Dh zGEP%SWJzshPa5q$ zpVMbCO6UqKDj6aUzn_qe7S9m7tGA3>dJd^Ch>67;o;hs00(sAfvGcIOy@*sf6?fgD z?W+E+%j>C~`Xv)G&BSd9hdSS?5cf=;!oHvF+a6R@@uTzu?%*`?Jk}11>pDhw4rCBX zI!ZIU*R94@^e26M3OfdF*u) zxfNHwPMq$oYw#y)Z~aw@5`GEkB?$x@L=uz_2|f~dTf$wCI)BzKFZZ-Hf;QyC z-tWOLIkO>W_Wh;0!@{2*$$x#ErXi`Th1|bYR|UtqT^{(7?uQ3VpdMuWS4MY%-$0=X}Q`7c%nmuGRTzP5%`s z<|cW*Czc|;?(pkL(wO#|z)jd3g)PD&83U_PNy1k8-V_G^zD7|0n=`w8f}3^sxX`t@yqWj0lz%8S80RsI|N{QC=m%nW#Om7{9B_(%Y)mcpSr0%7^t zB%4*@V_>N`H3y-41Ism8LEi0B#u1Ir22)GPx9J-#7P==KF5-i~cIU2YL9g0$rC z^Qan7g*8iQRUig621-+!p+Ia#MlsKKn;;`*2xwl-+q?h|Fc(xU#O!%-TSri3v$BKI zum==Kbb4~O8+o`o*om_F49&wSHu4fR%3ccCJbrv(t`FWTFngBCzuEL ze+keh8wUm6jBy&k%M=w#be>(As40&F`80Yw;pcp!UvnlHSp4(pKSv6ZT%}F zlp*!b2Qz*Z1VCJX8J5ij5Propjx3*6*bo+#QUBl_kZp#1v@wFpI#`J2of=mc8f}jt zpk1;%j?}3I79%REwyeU%Fbr~D8HaCLPN(@8-CFoU3etsUHHi{TF@te^yE7f6olr4pl?5$j?O!#;KvR=wiRD8LJ z#I1dxHC>6vQ{RuuV*nn6S1~7ZgR-pNHb`k(6%XJlZ6_51B`S$7)m36XCGA+W#-Z#f zO;Ylu-TBTsEGtm6tIwnspygx05#9D}1UHGu7yb;)ih{V;82AnUdgMsMh;0Y*qLj=) z9CQ*T=%=5rkqMk?_el_&{Si@i4EC47P9A(aMesw4k$V)%xDBL6+NPl(#P8smKGb}( z?LK#LF4alNjg$I;6XN%5P?f7P$uAJcatipOXV7(beI-@fW-xf0Q**A&%zX=$CDjXI1Yf=?T`j$3~TjXlAd1mbSMM1IP80;&nf}08`C(+?cZg{B) z1(w_K&TJ7Ysyb|7RxfO)RU->JD#cUwnI({bLHF6Ko`?$8W8fK{Jua#Nca1v;gDm5k ze|FpoI}E$})IFe$KzKw$d~-qBm!8ie?9y!p*vb{C_>NqP$NqrLFY6A$j&k6CT!@{K zMkfs;iX3!FwaK*=N9%E{D6L>#MPc}_N9J}nfKz&YSp1|C)IaQxGFz0kTY!0$_-)nX zZ|`)}j({Ayn#d%;1!G}f2nVXe9*7%&gpZY70tSYxHYBY zO{qaDWF~u}Mk-`CSDORPEhu{{$j~YdD#7Z8>~4VJL^j^Mcjm9tNcWnLw0jCnfoMYi z?R}W4W^6?~qCxUe(nQvEXwallp3&KP< z#ptPivVOt4=Wi@2^W!502)}vbFV9?b5?crWo17tK2;F}#3e?V-!Un7n7YOXdufWk$ zX*uwU8Pj?QEB^gZ132{meAc^_X^_f4}lAP^6pNd~bf45^y+m9e`+kUJE~D|Gn11+yz_Ud{rGOkqwLKC_4DPFCD}H z0Hiih;rz$2|LaG*ngD*wOe_j* z#_#JR2?H#GH(GeNLVxe134loV=e{WauMJ$RB)6Bb`fDZpv?V{ISPv#pv75impB63{ z&SY7xcliHw=kE^sf=TF&QR4WA4fyv1LM0eQILlr^H<9kodkk~ae1wWskcl`xV{Pv{8LuYkS~%o3;7=>Qq^(* literal 0 HcmV?d00001 diff --git a/docs/img/dataproc-service.png b/docs/img/dataproc-service.png new file mode 100644 index 0000000000000000000000000000000000000000..79899dc848fb70d8902fbb623b86c9432c5fc780 GIT binary patch literal 75408 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 literal 0 HcmV?d00001 diff --git a/docs/img/spark3cluster.png b/docs/img/spark3cluster.png new file mode 100644 index 0000000000000000000000000000000000000000..73050c63451bc4ebc1a8a99b9ff9656c67256c61 GIT binary patch literal 46767 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 literal 0 HcmV?d00001 diff --git a/docs/index.md b/docs/index.md index aed4afce6d9..e4c30e20749 100644 --- a/docs/index.md +++ b/docs/index.md @@ -5,7 +5,29 @@ nav_order: 1 permalink: / description: This site serves as a collection of documentation about the RAPIDS accelerator for Apache Spark --- +# Overview +The RAPIDS Accelerator for Apache Spark leverages GPUs to accelerate processing via the +[RAPIDS libraries](http://rapids.ai). + As data scientists shift from using traditional analytics to leveraging AI applications that better model complex market demands, traditional CPU-based processing can no longer keep up without compromising either speed or cost. The growing adoption of AI in analytics has created the need for a new framework to process data quickly and cost efficiently with GPUs. The RAPIDS Accelerator for Apache Spark combines the power of the RAPIDS cuDF library and the scale of the Spark distributed computing framework. The RAPIDS Accelerator library also has a built-in accelerated shuffle based on UCX that can be configured to leverage GPU-to-GPU communication and RDMA capabilities. +## Perfomance & Cost Benefits +Rapids Accelerator for Apache Spark reaps the benefit of GPU perfomance while saving infrastructure costs. +![Perf-cost](/img/Perf-cost.png) +*ETL for FannieMae Mortgage Dataset (~200GB) as shown in our [demo](https://databricks.com/session_na20/deep-dive-into-gpu-support-in-apache-spark-3-x). Costs based on Cloud T4 GPU instance market price & V100 GPU price on Databricks Standard edition + + +## Ease of Use +Run your existing Apache Spark applications with no code change. Learn more on how to [get started](/Getting-Started/). + +`spark.conf.set('spark.rapids.sql.enabled','true')` + +![ease-of-use](/img/ease-of-use.png) + +## An unified AI framework for ETL + ML/DL +A single pipeline, from ingest to data preparation to model training +![spark3cluster](/img/spark3cluster.png) + + diff --git a/docs/version/stable-release.md b/docs/version/stable-release.md new file mode 100644 index 00000000000..19726294cd5 --- /dev/null +++ b/docs/version/stable-release.md @@ -0,0 +1,36 @@ +--- +layout: page +title: Stable Version +nav_order: 1 +parent: Version +--- + +## Stable Release - v0.1.0 +This is the first public release of the RAPIDS Accelerator for Apache Spark. +The list of supported operations is provided [here](../configs.html#supported-gpu-operators-and-fine-tuning) + +Hardware Requirements: + + GPU Architecture: NVIDIA Pascal™ or better (Tested on V100 and T4 GPU) + +Software Requirements: + + OS: Ubuntu 16.04 & gcc 5.4 OR Ubuntu 18.04/CentOS 7 & gcc 7.3 + (RHEL 7 support is provided through CentOS 7 builds/installs) + + CUDA & NVIDIA Drivers: 10.1.2 & v418.87+ or 10.2 & v440.33+ + + Apache Spark 3.0 + + Apache Hadoop 2.10+ or 3.1.1+ (3.1.1 for nvidia-docker version 2) + + Python 3.x, Scala 2.12, Java 8 + + +## Download +* [RAPIDS Spark Package](https://repo1.maven.org/maven2/com/nvidia/rapids-4-spark_2.12/0.1.0/rapids-4-spark_2.12-0.1.0.jar) +* [cuDF 10.2 Package](https://repo1.maven.org/maven2/ai/rapids/cudf/0.14/cudf-0.14-cuda10-2.jar) +* [cuDF 10.1 Package](https://repo1.maven.org/maven2/ai/rapids/cudf/0.14/cudf-0.14-cuda10-1.jar) + + + diff --git a/docs/version/version.md b/docs/version/version.md new file mode 100644 index 00000000000..fb5c5b62d7c --- /dev/null +++ b/docs/version/version.md @@ -0,0 +1,7 @@ +--- +layout: page +title: Version +nav_order: 10 +has_children: true +permalink: /Version/ +---

_z#~={>Rh9{Ee;PjvCKj~9i%jTr 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ʙ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 literal 0 HcmV?d00001 diff --git a/docs/img/initscript.png b/docs/img/initscript.png new file mode 100644 index 0000000000000000000000000000000000000000..01111a5235a408da9d613fabbe7bd94d865ed870 GIT binary patch literal 12946 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 wW=hJ&79`{^=zW>(M- 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�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