Exemplo n.º 1
0
void bli_packv_release
     (
       obj_t*   p,
       packv_t* cntl
     )
{
	if ( !bli_cntl_is_noop( cntl ) )
		bli_obj_release_pack( p );
}
Exemplo n.º 2
0
void bli_packv_init
     (
       obj_t*   a,
       obj_t*   p,
       cntx_t*  cntx,
       packv_t* cntl
     )
{
	// The purpose of packm_init() is to initialize an object P so that

	// a source object A can be packed into P via one of the packv
	// implementations. This initialization includes acquiring a suitable
	// block of memory from the memory allocator, if such a block of memory
	// has not already been allocated previously.

	pack_t   pack_schema;
	bszid_t  bmult_id;

	// Check parameters.
	if ( bli_error_checking_is_enabled() )
		bli_packv_check( a, p, cntx );

	// First check if we are to skip this operation because the control tree
	// is NULL, and if so, simply alias the object to its packed counterpart.
	if ( bli_cntl_is_noop( cntl ) )
	{
		bli_obj_alias_to( a, p );
		return;
	}

	// At this point, we can be assured that cntl is not NULL. Let us now
	// check to see if the object has already been packed to the desired
	// schema (as encoded in the control tree). If so, we can alias and
	// return, as above.
	// Note that in most cases, bli_obj_pack_schema() will return
	// BLIS_NOT_PACKED and thus packing will be called for (but in some
	// cases packing has already taken place). Also, not all combinations
	// of current pack status and desired pack schema are valid.
	if ( bli_obj_pack_schema( a ) == cntl_pack_schema( cntl ) )
	{
		bli_obj_alias_to( a, p );
		return;
	}

	// Now, if we are not skipping the pack operation, then the only question
	// left is whether we are to typecast vector a before packing.
	if ( bli_obj_dt( a ) != bli_obj_target_dt( a ) )
		bli_abort();

	// Extract various fields from the control tree and pass them in
	// explicitly into _init_pack(). This allows external code generators
	// the option of bypassing usage of control trees altogether.
	pack_schema = cntl_pack_schema( cntl );
	bmult_id    = cntl_bmid( cntl );

	// Initialize object p for the final packed vector.
	bli_packv_init_pack
	(
	  pack_schema,
	  bmult_id,
	  &a,
	  p,
	  cntx
	);

	// Now p is ready to be packed.
}
Exemplo n.º 3
0
void bli_unpackv_int( obj_t*     p,
                      obj_t*     a,
                      cntx_t*    cntx,
                      unpackv_t* cntl )
{
	// The unpackv operation consists of an optional casting post-process.
	// (This post-process is analogous to the cast pre-process in packv.)
	// Here are the following possible ways unpackv can execute:
	//  1. unpack and cast: Unpack to a temporary vector c and then cast
	//     c to a.
	//  2. unpack only: Unpack directly to vector a since typecasting is
	//     not needed.
	//  3. cast only: Not yet supported / not used.
	//  4. no-op: The control tree directs us to skip the unpack operation
	//     entirely. No action is taken.

	obj_t     c;

	varnum_t  n;
	impl_t    i;
	FUNCPTR_T f;

	// Check parameters.
	if ( bli_error_checking_is_enabled() )
		bli_unpackv_check( p, a, cntx );

	// Sanity check; A should never have a zero dimension. If we must support
	// it, then we should fold it into the next alias-and-early-exit block.
	if ( bli_obj_has_zero_dim( *a ) ) bli_abort();

	// First check if we are to skip this operation because the control tree
	// is NULL, and if so, simply return.
	if ( bli_cntl_is_noop( cntl ) )
	{
		return;
	}

	// If p was aliased to a during the pack stage (because it was already
	// in an acceptable packed/contiguous format), then no unpack is actually
	// necessary, so we return.
	if ( bli_obj_is_alias_of( *p, *a ) )
	{
		return;
	}

	// Now, if we are not skipping the unpack operation, then the only
	// question left is whether we are to typecast vector a after unpacking.
	if ( bli_obj_datatype( *p ) != bli_obj_datatype( *a ) )
		bli_abort();
/*
	if ( bli_obj_datatype( *p ) != bli_obj_datatype( *a ) )
	{
		// Initialize an object c for the intermediate typecast vector.
		bli_unpackv_init_cast( p,
		                       a,
		                       &c );
	}
	else
*/
	{
		// If no cast is needed, then aliasing object c to the original
		// vector serves as a minor optimization. This causes the unpackv
		// implementation to unpack directly into vector a.
		bli_obj_alias_to( *a, c );
	}

	// Now we are ready to proceed with the unpacking.

	// Extract the variant number and implementation type.
	n = bli_cntl_var_num( cntl );
	i = bli_cntl_impl_type( cntl );

	// Index into the variant array to extract the correct function pointer.
	f = vars[n][i];

	// Invoke the variant.
	f( p,
	   &c,
	   cntx,
	   cntl );

	// Now, if necessary, we cast the contents of c to vector a. If casting
	// was not necessary, then we are done because the call to the unpackv
	// implementation would have unpacked directly to vector a.
/*
	if ( bli_obj_datatype( *p ) != bli_obj_datatype( *a ) )
	{
		// Copy/typecast vector c to vector a.
		// NOTE: Here, we use copynzv instead of copym because, in the cases
		// where we are unpacking/typecasting a real vector c to a complex
		// vector a, we want to touch only the real components of a, rather
		// than also set the imaginary components to zero. This comes about
		// because of the fact that, if we are unpacking real-to-complex,
		// then it is because all of the computation occurred in the real
		// domain, and so we would want to leave whatever imaginary values
		// there are in vector a untouched. Notice that for unpackings that
		// entail complex-to-complex data movements, the copynzv operation
		// behaves exactly as copym, so no use cases are lost (at least none
		// that I can think of).
		bli_copynzv( &c,
		             a );

		// NOTE: The above code/comment is outdated. What should happen is
		// as follows:
		// - If dt(a) is complex and dt(p) is real, then create an alias of
		//   a and then tweak it so that it looks like a real domain object.
		//   This will involve:
		//   - projecting the datatype to real domain
		//   - scaling both the row and column strides by 2
		//   ALL OF THIS should be done in the front-end, NOT here, as
		//   unpackv() won't even be needed in that case.
	}
*/
}
Exemplo n.º 4
0
void bli_packm_int( obj_t*   a,
                    obj_t*   p,
                    cntx_t*  cntx,
                    packm_t* cntl,
                    thrinfo_t* thread )
{
	varnum_t  n;
	impl_t    i;
	FUNCPTR_T f;

	// Check parameters.
	if ( bli_error_checking_is_enabled() )
		bli_packm_int_check( a, p, cntx );

	// Sanity check; A should never have a zero dimension. If we must support
	// it, then we should fold it into the next alias-and-early-exit block.
	//if ( bli_obj_has_zero_dim( *a ) ) bli_abort();

	// First check if we are to skip this operation because the control tree
	// is NULL. We return without taking any action because a was already
	// aliased to p in packm_init().
	if ( bli_cntl_is_noop( cntl ) )
	{
		return;
	}

	// Let us now check to see if the object has already been packed. First
	// we check if it has been packed to an unspecified (row or column)
	// format, in which case we can return, since by now aliasing has already
	// taken place in packm_init().
	// NOTE: The reason we don't need to even look at the control tree in
	// this case is as follows: an object's pack status is only set to
	// BLIS_PACKED_UNSPEC for situations when the actual format used is
	// not important, as long as its packed into contiguous rows or
	// contiguous columns. A good example of this is packing for matrix
	// operands in the level-2 operations.
	if ( bli_obj_pack_schema( *a ) == BLIS_PACKED_UNSPEC )
	{
		return;
	}

	// At this point, we can be assured that cntl is not NULL. Now we check
	// if the object has already been packed to the desired schema (as en-
	// coded in the control tree). If so, we can return, as above.
	// NOTE: In most cases, an object's pack status will be BLIS_NOT_PACKED
	// and thus packing will be called for (but in some cases packing has
	// already taken place, or does not need to take place, and so that will
	// be indicated by the pack status). Also, not all combinations of
	// current pack status and desired pack schema are valid.
	if ( bli_obj_pack_schema( *a ) == cntl_pack_schema( cntl ) )
	{
		return;
	}

	// If the object is marked as being filled with zeros, then we can skip
	// the packm operation entirely.
	if ( bli_obj_is_zeros( *a ) )
	{
		return;
	}


	// Extract the variant number and implementation type.
	n = bli_cntl_var_num( cntl );
	i = bli_cntl_impl_type( cntl );

	// Index into the variant array to extract the correct function pointer.
	f = vars[n][i];

	// Invoke the variant with kappa_use.
	f( a,
	   p,
	   cntx,
       thread );

    // Barrier so that packing is done before computation
    bli_thread_obarrier( thread );
}