|
50 | 50 | import java.util.Set; |
51 | 51 | import java.util.concurrent.TimeUnit; |
52 | 52 |
|
| 53 | +import static org.apache.iotdb.ainode.utils.AINodeTestUtils.BUILTIN_LTSM_MAP; |
53 | 54 | import static org.apache.iotdb.ainode.utils.AINodeTestUtils.BUILTIN_MODEL_MAP; |
54 | 55 | import static org.apache.iotdb.ainode.utils.AINodeTestUtils.checkHeader; |
55 | 56 | import static org.apache.iotdb.ainode.utils.AINodeTestUtils.checkModelNotOnSpecifiedDevice; |
@@ -90,6 +91,10 @@ public class AINodeSharedClusterIT { |
90 | 91 | "CALL INFERENCE(%s, \"SELECT s%d FROM root.AI LIMIT 256\")"; |
91 | 92 | private static final int DEFAULT_INPUT_LENGTH = 256; |
92 | 93 | private static final int DEFAULT_OUTPUT_LENGTH = 48; |
| 94 | + private static final int LOADED_MODEL_SMOKE_INPUT_LENGTH = 32; |
| 95 | + private static final int LOADED_MODEL_SMOKE_OUTPUT_LENGTH = 1; |
| 96 | + private static final List<String> LTSM_LOAD_DEVICE_COMBINATIONS = |
| 97 | + Arrays.asList("cpu", "0", "cpu,0"); |
93 | 98 |
|
94 | 99 | private static final String FORECAST_TABLE_FUNCTION_SQL_TEMPLATE = |
95 | 100 | "SELECT * FROM FORECAST(" |
@@ -438,6 +443,84 @@ public static void forecastTableFunctionErrorTest( |
438 | 443 |
|
439 | 444 | // ========== Concurrent forecast tests ========== |
440 | 445 |
|
| 446 | + @Test |
| 447 | + public void largeTimeSeriesModelLoadInferenceAndForecastTest() |
| 448 | + throws SQLException, InterruptedException { |
| 449 | + try (Connection treeConnection = EnvFactory.getEnv().getConnection(BaseEnv.TREE_SQL_DIALECT); |
| 450 | + Statement treeStatement = treeConnection.createStatement(); |
| 451 | + Connection tableConnection = EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT); |
| 452 | + Statement tableStatement = tableConnection.createStatement()) { |
| 453 | + for (FakeModelInfo modelInfo : BUILTIN_LTSM_MAP.values()) { |
| 454 | + for (String devices : LTSM_LOAD_DEVICE_COMBINATIONS) { |
| 455 | + loadRunAndUnloadModelOnDevices( |
| 456 | + treeStatement, tableStatement, modelInfo.getModelId(), devices); |
| 457 | + } |
| 458 | + } |
| 459 | + } |
| 460 | + } |
| 461 | + |
| 462 | + private void loadRunAndUnloadModelOnDevices( |
| 463 | + Statement treeStatement, Statement tableStatement, String modelId, String devices) |
| 464 | + throws SQLException, InterruptedException { |
| 465 | + boolean loadSubmitted = false; |
| 466 | + try { |
| 467 | + treeStatement.execute(String.format("LOAD MODEL %s TO DEVICES '%s'", modelId, devices)); |
| 468 | + loadSubmitted = true; |
| 469 | + checkModelOnSpecifiedDevice(treeStatement, modelId, devices); |
| 470 | + assertLoadedModelCallInferenceSucceeds(treeStatement, modelId); |
| 471 | + assertLoadedModelForecastSucceeds(tableStatement, modelId); |
| 472 | + } finally { |
| 473 | + if (loadSubmitted) { |
| 474 | + treeStatement.execute(String.format("UNLOAD MODEL %s FROM DEVICES '%s'", modelId, devices)); |
| 475 | + checkModelNotOnSpecifiedDevice(treeStatement, modelId, devices); |
| 476 | + } |
| 477 | + } |
| 478 | + } |
| 479 | + |
| 480 | + private void assertLoadedModelCallInferenceSucceeds(Statement statement, String modelId) |
| 481 | + throws SQLException { |
| 482 | + String callInferenceSQL = |
| 483 | + String.format( |
| 484 | + CALL_INFERENCE_SQL_TEMPLATE, |
| 485 | + modelId, |
| 486 | + 0, |
| 487 | + LOADED_MODEL_SMOKE_INPUT_LENGTH, |
| 488 | + LOADED_MODEL_SMOKE_OUTPUT_LENGTH); |
| 489 | + try (ResultSet resultSet = statement.executeQuery(callInferenceSQL)) { |
| 490 | + ResultSetMetaData resultSetMetaData = resultSet.getMetaData(); |
| 491 | + checkHeader(resultSetMetaData, "Time,output"); |
| 492 | + Assert.assertEquals(Types.DOUBLE, resultSetMetaData.getColumnType(2)); |
| 493 | + int count = 0; |
| 494 | + while (resultSet.next()) { |
| 495 | + resultSet.getDouble("output"); |
| 496 | + count++; |
| 497 | + } |
| 498 | + Assert.assertEquals(LOADED_MODEL_SMOKE_OUTPUT_LENGTH, count); |
| 499 | + } |
| 500 | + } |
| 501 | + |
| 502 | + private void assertLoadedModelForecastSucceeds(Statement statement, String modelId) |
| 503 | + throws SQLException { |
| 504 | + String forecastTableFunctionSQL = |
| 505 | + String.format( |
| 506 | + FORECAST_TABLE_FUNCTION_SQL_TEMPLATE, |
| 507 | + modelId, |
| 508 | + 0, |
| 509 | + 5760, |
| 510 | + LOADED_MODEL_SMOKE_INPUT_LENGTH, |
| 511 | + 5760, |
| 512 | + LOADED_MODEL_SMOKE_OUTPUT_LENGTH, |
| 513 | + 1, |
| 514 | + "time"); |
| 515 | + try (ResultSet resultSet = statement.executeQuery(forecastTableFunctionSQL)) { |
| 516 | + int count = 0; |
| 517 | + while (resultSet.next()) { |
| 518 | + count++; |
| 519 | + } |
| 520 | + Assert.assertEquals(LOADED_MODEL_SMOKE_OUTPUT_LENGTH, count); |
| 521 | + } |
| 522 | + } |
| 523 | + |
441 | 524 | @Test |
442 | 525 | public void concurrentForecastTest() throws SQLException, InterruptedException { |
443 | 526 | for (FakeModelInfo modelInfo : CONCURRENT_FORECAST_MODELS) { |
|
0 commit comments