deal float32 float16 quantized-u8
#if NCNN_STDIO
int Convolution::load_model (FILE* binfp)
{
int nread;
union
{
struct
{
unsigned char f0;
unsigned char f1;
unsigned char f2;
unsigned char f3;
};
unsigned int tag;
} flag_struct;
nread = fread (&flag_struct, sizeof (flag_struct), 1 , binfp);
if (nread != 1 )
{
fprintf (stderr, " Convolution read flag_struct failed %d\n " , nread);
return -1 ;
}
unsigned int flag = flag_struct.f0 + flag_struct.f1 + flag_struct.f2 + flag_struct.f3 ;
weight_data.create (weight_data_size);
if (weight_data.empty ())
return -100 ;
if (flag_struct.tag == 0x01306B47 )
{
// half-precision weight data
int align_weight_data_size = alignSize (weight_data_size * sizeof (unsigned short ), 4 );
std::vector<unsigned short > float16_weights;
float16_weights.resize (align_weight_data_size);
nread = fread (float16_weights.data (), align_weight_data_size, 1 , binfp);
if (nread != 1 )
{
fprintf (stderr, " Convolution read float16_weights failed %d\n " , nread);
return -1 ;
}
weight_data = Mat::from_float16 (float16_weights.data (), weight_data_size);
if (weight_data.empty ())
return -100 ;
}
else if (flag != 0 )
{
// quantized weight data
float quantization_value[256 ];
nread = fread (quantization_value, 256 * sizeof (float ), 1 , binfp);
if (nread != 1 )
{
fprintf (stderr, " Convolution read quantization_value failed %d\n " , nread);
return -1 ;
}
int align_weight_data_size = alignSize (weight_data_size * sizeof (unsigned char ), 4 );
std::vector<unsigned char > index_array;
index_array.resize (align_weight_data_size);
nread = fread (index_array.data (), align_weight_data_size, 1 , binfp);
if (nread != 1 )
{
fprintf (stderr, " Convolution read index_array failed %d\n " , nread);
return -1 ;
}
float * weight_data_ptr = weight_data;
for (int i = 0 ; i < weight_data_size; i++)
{
weight_data_ptr[i] = quantization_value[ index_array[i] ];
}
}
else if (flag_struct.f0 == 0 )
{
// raw weight data
nread = fread (weight_data, weight_data_size * sizeof (float ), 1 , binfp);
if (nread != 1 )
{
fprintf (stderr, " Convolution read weight_data failed %d\n " , nread);
return -1 ;
}
}
if (bias_term)
{
bias_data.create (num_output);
if (bias_data.empty ())
return -100 ;
nread = fread (bias_data, num_output * sizeof (float ), 1 , binfp);
if (nread != 1 )
{
fprintf (stderr, " Convolution read bias_data failed %d\n " , nread);
return -1 ;
}
}
return 0 ;
}
#endif // NCNN_STDIO
int Convolution::load_model (const unsigned char *& mem)
{
union
{
struct
{
unsigned char f0;
unsigned char f1;
unsigned char f2;
unsigned char f3;
};
unsigned int tag;
} flag_struct;
memcpy (&flag_struct, mem, sizeof (flag_struct));
mem += sizeof (flag_struct);
unsigned int flag = flag_struct.f0 + flag_struct.f1 + flag_struct.f2 + flag_struct.f3 ;
if (flag_struct.tag == 0x01306B47 )
{
// half-precision weight data
weight_data = Mat::from_float16 ((unsigned short *)mem, weight_data_size);
mem += alignSize (weight_data_size * sizeof (unsigned short ), 4 );
if (weight_data.empty ())
return -100 ;
}
else if (flag != 0 )
{
// quantized weight data
const float * quantization_value = (const float *)mem;
mem += 256 * sizeof (float );
const unsigned char * index_array = (const unsigned char *)mem;
mem += alignSize (weight_data_size * sizeof (unsigned char ), 4 );
weight_data.create (weight_data_size);
if (weight_data.empty ())
return -100 ;
float * weight_data_ptr = weight_data;
for (int i = 0 ; i < weight_data_size; i++)
{
weight_data_ptr[i] = quantization_value[ index_array[i] ];
}
}
else if (flag_struct.f0 == 0 )
{
// raw weight data
weight_data = Mat (weight_data_size, (float *)mem);
mem += weight_data_size * sizeof (float );
}
if (bias_term)
{
bias_data = Mat (num_output, (float *)mem);
mem += num_output * sizeof (float );
}
return 0 ;
}
new model load api proposed
int Convolution::load_model (const ModelBin& mb)
{
// auto detect element type
weight_data = mb.load (weight_data_size, 0 );
if (weight_data.empty ())
return -100 ;
if (bias_term)
{
// certain type specified
bias_data = mb.load (num_output, 1 );
if (bias_data.empty ())
return -100 ;
}
return 0 ;
}