TEST( gpu_device_load_and_unload, callbacks_test ) { // Run in a loop: load, validate,work_item, unload for( int i = 0; i < 2; ++i ) { // nn_device_load EXPECT_LT( nn_device_load( nullptr ), 0 ); // no error on invalid pointer nn_device_description_t dd; const auto invalid_first = static_cast< decltype( dd.version_first ) >( -1 ); const auto invalid_last = static_cast< decltype( dd.version_first ) >( -2 ); dd.version_first = invalid_first; dd.version_last = invalid_last; EXPECT_EQ( 0, nn_device_load( &dd ) ); // non-zero return code on valid call EXPECT_NE( invalid_first, dd.version_first ); // nn_device_description_t::version_first is incorrect EXPECT_NE( invalid_last, dd.version_last ); // nn_device_description_t::version_last is incorrect EXPECT_LE( dd.version_first, dd.version_last ); // nn_device_description_t::version_first is greater than // ::version_last // nn_device_interface_open & close { uint8_t buffer[4096]; // nn_device_interface_open parameter validation EXPECT_GT( 0, nn_device_interface_open( invalid_last, buffer ) ); // no error on invalid // version EXPECT_GT( 0, nn_device_interface_open( dd.version_first, nullptr) ); // no error on invalid // buffer // nn_device_interface_close parameter validation EXPECT_GT( 0, nn_device_interface_close( nullptr ) ); // no error on invalid // interface pointer } { // interface version 0 const uint16_t interface_version = 0; nn_device_interface_0_t di; if( ( interface_version >= dd.version_first ) && ( interface_version <= dd.version_last ) ) { EXPECT_EQ( 0, nn_device_interface_open( interface_version, &di ) ); EXPECT_EQ( interface_version, di.version ); // returned version matches requested EXPECT_NE( nullptr, di.device ); // non-null device returned EXPECT_NE( nullptr, di.workflow_item_validate_function ); // non-null function pointer returned EXPECT_NE( nullptr, di.workflow_item_delete_function ); // non-null function pointer returned EXPECT_NE( nullptr, di.parameter_set_function ); // non-null function pointer returned EXPECT_NE( nullptr, di.parameter_get_function ); // non-null function pointer returned } EXPECT_EQ( true, run_convolve_test( di, 1, 1, 2, 2, 1, 1, 1, 1, 1, NN_ACTIVATION_FUNCTION_NONE ) ); EXPECT_EQ( 0, nn_device_interface_close( &di ) ); // successful close of interface } // nn_device_unload EXPECT_EQ( 0, nn_device_unload() ); // successful unload } }
TEST( cpu_int16_device_load_and_unload, callbacks_test ) { // nn_device_load EXPECT_LT(nn_device_load(nullptr), 0); // no error on invalid pointer nn_device_description_t dd; const auto invalid_first = static_cast<decltype(dd.version_first)>(-1); const auto invalid_last = static_cast<decltype(dd.version_first)>(-2); dd.version_first = invalid_first; dd.version_last = invalid_last; EXPECT_EQ(0, nn_device_load(&dd)); // non-zero return code on valid call EXPECT_NE(invalid_first, dd.version_first); // nn_device_description_t::version_first is incorrect EXPECT_NE(invalid_last, dd.version_last); // nn_device_description_t::version_last is incorrect EXPECT_LE(dd.version_first, dd.version_last); // nn_device_description_t::version_first is greater than ::version_last // nn_device_interface_open & close { uint8_t buffer[4096]; // nn_device_interface_open parameter validation EXPECT_GT(0, nn_device_interface_open(invalid_last, buffer)); // no error on invalid version EXPECT_GT(0, nn_device_interface_open(dd.version_first, nullptr)); // no error on invalid buffer // nn_device_interface_close parameter validation EXPECT_GT(0, nn_device_interface_close(nullptr)); // no error on invalid interface pointer } { // interface version 0 const uint16_t interface_version = 0; nn_device_interface_0_t di; if(interface_version>=dd.version_first && interface_version<=dd.version_last) { EXPECT_EQ(0, nn_device_interface_open(interface_version, &di)); EXPECT_EQ(interface_version, di.version); // returned version matches requested EXPECT_NE(nullptr, di.device); // non-null device returned EXPECT_NE(nullptr, di.workflow_create_function); // non-null function pointer returned EXPECT_NE(nullptr, di.workflow_delete_function); // non-null function pointer returned EXPECT_NE(nullptr, di.workflow_metrics_query_function); // non-null function pointer returned EXPECT_NE(nullptr, di.workflow_metrics_delete_function); // non-null function pointer returned EXPECT_NE(nullptr, di.workflow_compile_function); // non-null function pointer returned EXPECT_NE(nullptr, di.workload_execute_function); // non-null function pointer returned EXPECT_NE(nullptr, di.workload_delete_function); // non-null function pointer returned EXPECT_NE(nullptr, di.workflow_item_create_function); // non-null function pointer returned EXPECT_NE(nullptr, di.workflow_item_validate_function); // non-null function pointer returned EXPECT_NE(nullptr, di.workflow_item_delete_function); // non-null function pointer returned EXPECT_NE(nullptr, di.parameter_get_function); // non-null function pointer returned EXPECT_NE(nullptr, di.parameter_set_function); // non-null function pointer returned EXPECT_NE(nullptr, di.translate_api_status_function); // non-null function pointer returned EXPECT_EQ(0, nn_device_interface_close(&di)); // successful close of interface } } // nn_device_unload EXPECT_EQ(0, nn_device_unload()); // successful unload }
static bool ult_nn_fc_interface_run(nn_workload_item* work_item) { bool retvalue = true; // Use optimized routine. nn_device_description_t device_description; nn_device_interface_0_t device_interface_0; nn_device_load(&device_description); nn_device_interface_open(0, &device_interface_0); int16_fixedpoint::run_multithreaded_fully_connected_fixedpoint_work_item(work_item, reinterpret_cast<nn_device_internal*>(device_interface_0.device)); nn_device_interface_close(&device_interface_0); nn_device_unload(); return retvalue; }
TEST( gpu_device_interface_0, start_work_item_test ) { // 1. Initialize and check if interface 0 is supported nn_device_description_t dd; const auto invalid_first = static_cast< decltype( dd.version_first ) >( -1 ); const auto invalid_last = static_cast< decltype( dd.version_first ) >( -2 ); dd.version_first = invalid_first; dd.version_last = invalid_last; EXPECT_EQ( 0, nn_device_load( &dd ) ); // non-zero return code on valid call EXPECT_NE( invalid_first, dd.version_first ); // nn_device_description_t::version_first is incorrect EXPECT_EQ( 0, dd.version_first ); // First supported interface version should be 0 // 2. Get interface 0 const uint16_t interface_version = 0; nn_device_interface_0_t di; if( ( interface_version >= dd.version_first ) && ( interface_version <= dd.version_last ) ) { EXPECT_EQ( 0, nn_device_interface_open( interface_version, &di) ); EXPECT_EQ( interface_version, di.version ); // returned version matches requested EXPECT_NE( nullptr, di.device ); // non-null device returned EXPECT_NE( nullptr, di.workflow_item_validate_function ); // non-null function pointer returned EXPECT_NE( nullptr, di.workflow_item_delete_function ); // non-null function pointer returned EXPECT_NE( nullptr, di.parameter_set_function ); // non-null function pointer returned EXPECT_NE( nullptr, di.parameter_get_function ); // non-null function pointer returned //assert(0);//TODO: Add other interface functions just above } EXPECT_EQ( NN_API_STATUS_ERROR_INVALID_POINTER, di.workflow_item_validate_function( di.device, nullptr ) ); // test invalid pointer case EXPECT_EQ( true, run_softmax_test( di, // interface 10, // length of input to be processed (softmax normalize) 3) ); EXPECT_EQ( 0, nn_device_interface_close( &di ) ); // successful close of interface //// nn_device_unload EXPECT_EQ( 0, nn_device_unload() ); // successful unload }
static void ult_nn_fc_initialize_work_item( nn_workload_item* &work_item, nn_workload_item* &input_item, int16_t *const input, int32_t*const biases, T_output_type *const output, int16_t *const kernel, uint32_t num_input_neurons, uint32_t num_output_neurons, uint32_t batch_size, uint8_t accumulator_fraction, uint8_t output_fraction, NN_ACTIVATION_FUNCTION activation) { nn_workload_data_layout_t in_layout = nn::layout_t<nn::layout_pnzxyq_i16>::layout; nn_workload_data_layout_t out_layout = std::is_same<T_output_type, int16_t>::value ? nn::layout_t<nn::layout_pnzxyq_i16>::layout : nn::layout_t<nn::layout_pnzxyq_i32>::layout; nn_workload_data_layout_t bias_layout = nn::layout_t<nn::layout_xzynpq_i32>::layout; nn_workload_data_layout_t weight_layout = nn::layout_t<nn::layout_xzynpq_i16>::layout; nn_workload_data_coords_t input_coords = { batch_size, 1, 1, num_input_neurons / 2, 2, 1 }; nn_workload_data_coords_t output_coords = { batch_size, 1, 1, num_output_neurons / 2, 2, 1 }; nn_workload_data_coords_t bias_coords = { 1, 1, 1, num_output_neurons, 1, 1 }; nn_workload_data_coords_t weight_coords = { 1, 2, num_input_neurons / 2, C_simd_width, //8 num_output_neurons / C_simd_width, 1 }; nn::workload_data<T_output_type> *output_data = new nn::workload_data<T_output_type>(output_coords, out_layout); nn::workload_data<int32_t> *bias_data = new nn::workload_data<int32_t>(bias_coords, bias_layout); nn::workload_data<int16_t> *weight_data = new nn::workload_data<int16_t>(weight_coords, weight_layout); work_item = new nn_workload_item(); work_item->type = work_item_helper<T_output_type>::work_item_type; auto &arguments = work_item_helper<T_output_type>::get_arguments(work_item); arguments.activation.basic_arguments.function = activation; arguments.activation.fractions.accumulator = accumulator_fraction; arguments.activation.fractions.output = output_fraction; work_item->output.push_back(output_data); arguments.biases = bias_data; arguments.weights = weight_data; memcpy(work_item->output[0]->parent->data_buffer, output, work_item->output[0]->parent->buffer_size); memcpy(arguments.biases->parent->data_buffer, biases, arguments.biases->parent->buffer_size); memcpy(arguments.weights->parent->data_buffer, kernel, arguments.weights->parent->buffer_size); input_item = new nn_workload_item(); input_item->type = NN_WORK_ITEM_TYPE_INPUT; input_item->primitive = nullptr; nn::workload_data<int16_t> *input_data = new nn::workload_data<int16_t>(input_coords, in_layout); memcpy(input_data->parent->data_buffer, input, input_data->parent->buffer_size); input_item->output.push_back(input_data); work_item->input.push_back({ input_item, 0 }); // Create primitive nn_device_description_t device_description; nn_device_interface_0_t device_interface_0; nn_device_load(&device_description); nn_device_interface_open(0, &device_interface_0); work_item->primitive = new int16_fixedpoint::fully_connected_i16<T_output_type>( num_input_neurons, num_output_neurons, arguments.activation, batch_size, reinterpret_cast<nn_device_internal*>(device_interface_0.device)); // Create primitive output delete work_item->output[0]; work_item->output[0] = static_cast<int16_fixedpoint::fully_connected_i16<T_output_type> *>(work_item->primitive)->create_outputs(false)[0]; }