1/*
2 * Copyright (C) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include <cstdio>
17#include <stddef.h>
18#include <stdint.h>
19#include <iostream>
20#include "mindspore_fuzzer.h"
21#include "../data.h"
22#include "include/c_api/context_c.h"
23#include "include/c_api/model_c.h"
24#include "../../utils/model_utils.h"
25#include "context_c_fuzzer.h"
26
27bool MSPreparedModelFuzzTest(const uint8_t* data, size_t size) {
28    if (data == nullptr) {
29        return false;
30    }
31
32    OH_AI_ContextHandle context = OH_AI_ContextCreate();
33    if (context == nullptr) {
34        printf("create context failed.\n");
35        return false;
36    }
37    OH_AI_ContextSetThreadNum(context, 4);
38
39    OH_AI_DeviceInfoHandle cpuDeviceInfo = OH_AI_DeviceInfoCreate(OH_AI_DEVICETYPE_CPU);
40    if (cpuDeviceInfo == NULL) {
41        printf("OH_AI_DeviceInfoCreate failed.\n");
42        OH_AI_ContextDestroy(&context);
43        return false;
44    }
45    OH_AI_ContextAddDeviceInfo(context, cpuDeviceInfo);
46
47    OH_AI_ModelHandle model = OH_AI_ModelCreate();
48    if (model == nullptr) {
49        printf("create model failed.\n");
50        return false;
51    }
52
53    OH_AI_ContextDestroy(&context);
54    OH_AI_ModelDestroy(&model);
55    return true;
56}
57
58bool MSContextFuzzTest_Null(const uint8_t* data, size_t size) {
59    OH_AI_ContextHandle context = nullptr;
60
61    OH_AI_ContextSetThreadNum(context, 4);
62    auto retThreadNum = OH_AI_ContextGetThreadNum(context);
63    if (retThreadNum != 0) {
64        printf("OH_AI_ContextGetThreadNum failed.\n");
65        return false;
66    }
67
68    OH_AI_ContextSetThreadAffinityMode(context, 1);
69    auto ret = OH_AI_ContextGetThreadAffinityMode(context);
70    if (ret != 0) {
71        printf("OH_AI_ContextGetThreadAffinityMode failed.\n");
72        return false;
73    }
74
75    OH_AI_ContextSetThreadAffinityCoreList(context, nullptr, 0);
76    auto retCoreList = OH_AI_ContextGetThreadAffinityCoreList(context, nullptr);
77    if (retCoreList != 0) {
78        printf("OH_AI_ContextGetThreadAffinityCoreList failed.\n");
79        return false;
80    }
81
82    OH_AI_ContextSetEnableParallel(context, true);
83    auto retParallel = OH_AI_ContextGetEnableParallel(context);
84    if (retParallel != false) {
85        printf("OH_AI_ContextGetEnableParallel failed.\n");
86        return false;
87    }
88
89
90    OH_AI_DeviceInfoHandle deviceInfo = OH_AI_DeviceInfoCreate(OH_AI_DEVICETYPE_CPU);
91    if (deviceInfo == nullptr) {
92        printf("OH_AI_DeviceInfoCreate cpu failed.\n");
93        return false;
94    }
95    OH_AI_DeviceInfoDestroy(&deviceInfo);
96
97    deviceInfo = OH_AI_DeviceInfoCreate(OH_AI_DEVICETYPE_INVALID);
98    if (deviceInfo != nullptr) {
99        printf("OH_AI_DeviceInfoCreate failed.\n");
100        return false;
101    }
102    OH_AI_ContextAddDeviceInfo(context, deviceInfo);
103    OH_AI_DeviceInfoSetProvider(deviceInfo, nullptr);
104    auto retProvider = OH_AI_DeviceInfoGetProvider(deviceInfo);
105    if (retProvider != nullptr) {
106        printf("OH_AI_DeviceInfoGetProvider failed.\n");
107        return false;
108    }
109
110    OH_AI_DeviceInfoSetProviderDevice(deviceInfo, nullptr);
111    auto retProDevice = OH_AI_DeviceInfoGetProviderDevice(deviceInfo);
112    if (retProDevice != nullptr) {
113        printf("OH_AI_DeviceInfoGetProviderDevice failed.\n");
114        return false;
115    }
116    auto deviceType = OH_AI_DeviceInfoGetDeviceType(deviceInfo);
117    if (deviceType != OH_AI_DEVICETYPE_INVALID) {
118        printf("OH_AI_DeviceInfoGetDeviceType failed.\n");
119        return false;
120    }
121
122    OH_AI_DeviceInfoSetEnableFP16(deviceInfo, true);
123    auto retEnableFp16 = OH_AI_DeviceInfoGetEnableFP16(deviceInfo);
124    if (retEnableFp16 != false) {
125        printf("OH_AI_DeviceInfoGetEnableFP16 failed.\n");
126        return false;
127    }
128    OH_AI_DeviceInfoSetFrequency(deviceInfo, 1);
129    auto retFrequency = OH_AI_DeviceInfoGetFrequency(deviceInfo);
130    if (retFrequency != -1) {
131        printf("OH_AI_DeviceInfoGetFrequency failed.\n");
132        return false;
133    }
134
135    OH_AI_DeviceInfoSetDeviceId(deviceInfo, 1);
136    auto retDeviceId = OH_AI_DeviceInfoGetDeviceId(deviceInfo);
137    if (retDeviceId != 0) {
138        printf("OH_AI_DeviceInfoGetDeviceId failed.\n");
139        return false;
140    }
141    OH_AI_DeviceInfoSetPerformanceMode(deviceInfo, OH_AI_PERFORMANCE_HIGH);
142    auto retPerMode = OH_AI_DeviceInfoGetPerformanceMode(deviceInfo);
143    if (retPerMode != OH_AI_PERFORMANCE_NONE) {
144        printf("OH_AI_DeviceInfoGetPerformanceMode failed.\n");
145        return false;
146    }
147    OH_AI_DeviceInfoSetPriority(deviceInfo, OH_AI_PRIORITY_HIGH);
148    auto retPriority = OH_AI_DeviceInfoGetPriority(deviceInfo);
149    if (retPriority != OH_AI_PRIORITY_NONE) {
150        printf("OH_AI_DeviceInfoGetPriority failed.\n");
151        return false;
152    }
153    auto retExt = OH_AI_DeviceInfoAddExtension(deviceInfo, nullptr, nullptr, 0);
154    if (retExt != OH_AI_STATUS_LITE_NULLPTR) {
155        printf("OH_AI_DeviceInfoAddExtension failed.\n");
156        return false;
157    }
158    return true;
159}
160
161bool MSTensorFuzzTest_Null(const uint8_t* data, size_t size) {
162    OH_AI_TensorHandle tensor = OH_AI_TensorCreate(nullptr, OH_AI_DATATYPE_NUMBERTYPE_FLOAT32, nullptr, 0, nullptr, 0);
163    OH_AI_TensorDestroy(&tensor);
164
165    auto retClone = OH_AI_TensorClone(tensor);
166    if (retClone != nullptr) {
167        printf("OH_AI_TensorClone failed.\n");
168        return false;
169    }
170    OH_AI_TensorSetName(tensor, nullptr);
171    auto retGetName = OH_AI_TensorGetName(tensor);
172    if (retGetName != nullptr) {
173        printf("OH_AI_TensorGetName failed.\n");
174        return false;
175    }
176    OH_AI_TensorSetDataType(tensor, OH_AI_DATATYPE_NUMBERTYPE_INT64);
177    auto retGetDataType = OH_AI_TensorGetDataType(tensor);
178    if (retGetDataType != OH_AI_DATATYPE_UNKNOWN) {
179        printf("OH_AI_TensorGetDataType failed.\n");
180        return false;
181    }
182    OH_AI_TensorSetShape(tensor, nullptr, 0);
183    auto retGetShape = OH_AI_TensorGetShape(tensor, nullptr);
184    if (retGetShape != nullptr) {
185        printf("OH_AI_TensorGetShape failed.\n");
186        return false;
187    }
188    OH_AI_TensorSetFormat(tensor, OH_AI_FORMAT_KHWC);
189    auto retGetFormat = OH_AI_TensorGetFormat(tensor);
190    if (retGetFormat != OH_AI_FORMAT_NHWC) {
191        printf("OH_AI_TensorGetFormat failed.\n");
192        return false;
193    }
194    OH_AI_TensorSetData(tensor, nullptr);
195    auto retSetUserData = OH_AI_TensorSetUserData(tensor, nullptr, 0);
196    if (retSetUserData != OH_AI_STATUS_LITE_NULLPTR) {
197        printf("OH_AI_TensorSetUserData failed.\n");
198        return false;
199    }
200    auto retGetData = OH_AI_TensorGetData(tensor);
201    if (retGetData != nullptr) {
202        printf("OH_AI_TensorGetData failed.\n");
203        return false;
204    }
205    auto retMutaData = OH_AI_TensorGetMutableData(tensor);
206    if (retMutaData != nullptr) {
207        printf("OH_AI_TensorGetMutableData failed.\n");
208        return false;
209    }
210    auto retEleNum = OH_AI_TensorGetElementNum(tensor);
211    if (retEleNum != 0) {
212        printf("OH_AI_TensorGetElementNum failed.\n");
213        return false;
214    }
215    auto retDataSize = OH_AI_TensorGetDataSize(tensor);
216    if (retDataSize != 0) {
217        printf("OH_AI_TensorGetDataSize failed.\n");
218        return false;
219    }
220    return true;
221}
222
223bool MSModelFuzzTest_Null(const uint8_t* data, size_t size) {
224    OH_AI_ModelHandle model = OH_AI_ModelCreate();
225    if (model == nullptr) {
226        printf("create model failed.\n");
227        return false;
228    }
229    OH_AI_ModelDestroy(&model);
230    OH_AI_ModelSetWorkspace(model, nullptr, 0);
231    OH_AI_ModelCalcWorkspaceSize(model);
232    auto ret = OH_AI_ModelBuild(model, nullptr, 0, OH_AI_MODELTYPE_MINDIR, nullptr);
233    if (ret != OH_AI_STATUS_LITE_NULLPTR) {
234        printf("OH_AI_ModelBuild failed.\n");
235        return false;
236    }
237    ret = OH_AI_ModelBuildFromFile(model, nullptr, OH_AI_MODELTYPE_MINDIR, nullptr);
238    if (ret != OH_AI_STATUS_LITE_NULLPTR) {
239        printf("OH_AI_ModelBuildFromFile failed.\n");
240        return false;
241    }
242    ret = OH_AI_ModelResize(model, {0, nullptr}, nullptr, 0);
243    if (ret != OH_AI_STATUS_LITE_NULLPTR) {
244        printf("OH_AI_ModelResize failed.\n");
245        return false;
246    }
247    OH_AI_TensorHandleArray outputs = {0, nullptr};
248    ret = OH_AI_ModelPredict(model, {0, nullptr}, &outputs, nullptr, nullptr);
249    if (ret != OH_AI_STATUS_LITE_NULLPTR) {
250        printf("OH_AI_ModelPredict failed.\n");
251        return false;
252    }
253    OH_AI_ModelRunStep(model, nullptr, nullptr);
254    OH_AI_ModelExportWeight(model, nullptr);
255    auto retInputs = OH_AI_ModelGetInputs(model);
256    if (retInputs.handle_list != nullptr) {
257        printf("OH_AI_ModelGetInputs failed.\n");
258        return false;
259    }
260    auto retOutputs = OH_AI_ModelGetOutputs(model);
261    if (retOutputs.handle_list != nullptr) {
262        printf("OH_AI_ModelGetOutputs failed.\n");
263        return false;
264    }
265    OH_AI_ModelGetInputByTensorName(model, nullptr);
266    OH_AI_ModelGetOutputByTensorName(model, nullptr);
267    auto trainCfg = OH_AI_TrainCfgCreate();
268    if (trainCfg == nullptr) {
269        printf("OH_AI_TrainCfgCreate failed.\n");
270        return false;
271    }
272    OH_AI_TrainCfgDestroy(&trainCfg);
273    auto retLossName = OH_AI_TrainCfgGetLossName(trainCfg, nullptr);
274    if (retLossName != nullptr) {
275        printf("OH_AI_TrainCfgGetLossName failed.\n");
276        return false;
277    }
278    OH_AI_TrainCfgSetLossName(trainCfg, nullptr, 0);
279    auto retOptLevel = OH_AI_TrainCfgGetOptimizationLevel(trainCfg);
280    if (retOptLevel != OH_AI_KO0) {
281        printf("OH_AI_TrainCfgGetOptimizationLevel failed.\n");
282        return false;
283    }
284    OH_AI_TrainCfgSetOptimizationLevel(trainCfg, OH_AI_KAUTO);
285    ret = OH_AI_TrainModelBuild(model, nullptr, 0, OH_AI_MODELTYPE_MINDIR, nullptr, trainCfg);
286    if (ret != OH_AI_STATUS_LITE_NULLPTR) {
287        printf("OH_AI_TrainModelBuild failed.\n");
288        return false;
289    }
290    ret = OH_AI_TrainModelBuildFromFile(model, nullptr, OH_AI_MODELTYPE_MINDIR, nullptr, trainCfg);
291    if (ret != OH_AI_STATUS_LITE_NULLPTR) {
292        printf("OH_AI_TrainModelBuildFromFile failed.\n");
293        return false;
294    }
295    ret = OH_AI_ModelSetLearningRate(model, 0.0f);
296    if (ret != OH_AI_STATUS_LITE_PARAM_INVALID) {
297        printf("OH_AI_ModelSetLearningRate failed.\n");
298        return false;
299    }
300    OH_AI_ModelGetLearningRate(model);
301    ret = OH_AI_RunStep(model, nullptr, nullptr);
302    if (ret != OH_AI_STATUS_LITE_PARAM_INVALID) {
303        printf("OH_AI_RunStep failed.\n");
304        return false;
305    }
306    auto retGetWeights = OH_AI_ModelGetWeights(model);
307    if (retGetWeights.handle_list != nullptr) {
308        printf("OH_AI_ModelGetWeights failed.\n");
309        return false;
310    }
311    ret = OH_AI_ModelUpdateWeights(model, {0, nullptr});
312    if (ret != OH_AI_STATUS_LITE_PARAM_INVALID) {
313        printf("OH_AI_ModelUpdateWeights failed.\n");
314        return false;
315    }
316    auto retTrainMode = OH_AI_ModelGetTrainMode(model);
317    if (retTrainMode != false) {
318        printf("OH_AI_ModelGetTrainMode failed.\n");
319        return false;
320    }
321    ret = OH_AI_ModelSetTrainMode(model, true);
322    if (ret != OH_AI_STATUS_LITE_PARAM_INVALID) {
323        printf("OH_AI_ModelSetTrainMode failed.\n");
324        return false;
325    }
326    ret = OH_AI_ModelSetupVirtualBatch(model, 0, 0.0f, 0.0f);
327    if (ret != OH_AI_STATUS_LITE_PARAM_INVALID) {
328        printf("OH_AI_ModelSetupVirtualBatch failed.\n");
329        return false;
330    }
331    ret = OH_AI_ExportModel(model, OH_AI_MODELTYPE_MINDIR, nullptr, OH_AI_UNKNOWN_QUANT_TYPE, true, nullptr, 0);
332    if (ret != OH_AI_STATUS_LITE_PARAM_INVALID) {
333        printf("OH_AI_ExportModel failed.\n");
334        return false;
335    }
336    ret = OH_AI_ExportModelBuffer(model, OH_AI_MODELTYPE_MINDIR, nullptr, nullptr, OH_AI_FULL_QUANT, true, nullptr, 0);
337    if (ret != OH_AI_STATUS_LITE_PARAM_INVALID) {
338        printf("OH_AI_ExportModelBuffer failed.\n");
339        return false;
340    }
341    ret = OH_AI_ExportWeightsCollaborateWithMicro(model, OH_AI_MODELTYPE_MINDIR, nullptr, true, true, nullptr, 0);
342    if (ret != OH_AI_STATUS_LITE_PARAM_INVALID) {
343        printf("OH_AI_ExportWeightsCollaborateWithMicro failed.\n");
344        return false;
345    }
346    return true;
347}
348
349/* Fuzzer entry point */
350extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
351{
352    if (data == nullptr) {
353        LOGE("Pass data is nullptr.");
354        return 0;
355    }
356
357    if (size < 4) {
358        LOGE("Pass size is too small.");
359        return 0;
360    }
361
362    MSPreparedModelFuzzTest(data, size);
363    MSModelFuzzTest_Null(data, size);
364    MSContextFuzzTest_Null(data, size);
365    MSTensorFuzzTest_Null(data, size);
366    return 0;
367}