jcuda.Pointer Maven / Gradle / Ivy
/*
*
* * Copyright 2015 Skymind,Inc.
* *
* * Licensed under the Apache License, Version 2.0 (the "License");
* * you may not use this file except in compliance with the License.
* * You may obtain a copy of the License at
* *
* * http://www.apache.org/licenses/LICENSE-2.0
* *
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS,
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* * See the License for the specific language governing permissions and
* * limitations under the License.
*
*
*/
package jcuda;
import java.nio.*;
import java.util.Arrays;
/**
* A Java representation of a void pointer.
*/
public class Pointer extends NativePointerObject
{
/**
* The offset from the nativePointer, in bytes
*/
private long byteOffset;
/**
* The buffer the pointer points to
*/
private Buffer buffer;
/**
* The array of NativePointerObjects this pointer points to
*/
private NativePointerObject pointers[];
/**
* Creates a new Pointer to the given values.
*
* @param values The values the pointer should point to
* @return The pointer
*/
public static Pointer to(byte values[])
{
return new Pointer(ByteBuffer.wrap(values));
}
/**
* Creates a new Pointer to the given values.
* The values may not be null.
*
* @param values The values the pointer should point to
* @return The pointer
*/
public static Pointer to(char values[])
{
return new Pointer(CharBuffer.wrap(values));
}
/**
* Creates a new Pointer to the given values.
* The values may not be null.
*
* @param values The values the pointer should point to
* @return The pointer
*/
public static Pointer to(short values[])
{
return new Pointer(ShortBuffer.wrap(values));
}
/**
* Creates a new Pointer to the given values.
* The values may not be null.
*
* @param values The values the pointer should point to
* @return The pointer
*/
public static Pointer to(int values[])
{
return new Pointer(IntBuffer.wrap(values));
}
/**
* Creates a new Pointer to the given values.
* The values may not be null.
*
* @param values The values the pointer should point to
* @return The pointer
*/
public static Pointer to(float values[])
{
return new Pointer(FloatBuffer.wrap(values));
}
/**
* Creates a new Pointer to the given values.
* The values may not be null.
*
* @param values The values the pointer should point to
* @return The pointer
*/
public static Pointer to(long values[])
{
return new Pointer(LongBuffer.wrap(values));
}
/**
* Creates a new Pointer to the given values.
* The values may not be null.
*
* @param values The values the pointer should point to
* @return The pointer
*/
public static Pointer to(double values[])
{
return new Pointer(DoubleBuffer.wrap(values));
}
/**
* NOTE: This method does not take into account the position
* and array offset of the given buffer. In order to create a
* pointer that takes the position and array offset into account,
* use the {@link #toBuffer(Buffer)} method.
*
*
* If the given buffer has a backing array, then the returned
* pointer will in any case point to the start of the array,
* even if the buffer has been created using the slice
* method (like {@link ByteBuffer#slice()}). If the buffer is
* direct, then this method will return a Pointer to the address
* of the direct buffer. If the buffer has been created using the
* slice
method, then this will be the actual start
* of the slice. Although this implies a different treatment of
* direct- and non direct buffers, the method is kept for
* backward compatibility.
*
* In both cases, for direct and array-based buffers, this method
* does not take into account the position of the given buffer.
*
* The buffer must not be null, and either be a direct buffer, or
* have a backing array
*
* @param buffer The buffer the pointer should point to
* @return The pointer
* @throws IllegalArgumentException If the given buffer
* is null or is neither direct nor has a backing array
*/
public static Pointer to(Buffer buffer)
{
if (buffer == null || (!buffer.isDirect() && !buffer.hasArray()))
{
throw new IllegalArgumentException(
"Buffer may not be null and must have an array or be direct");
}
return new Pointer(buffer);
}
/**
* Creates a new Pointer to the given buffer.
*
* Note that this method takes into account the array offset and position
* of the given buffer, in contrast to the {@link #to(Buffer)} method.
*
* @param buffer The buffer
* @return The new pointer
* @throws IllegalArgumentException If the given buffer
* is null or is neither direct nor has a backing array
*/
public static Pointer toBuffer(Buffer buffer)
{
if (buffer == null || (!buffer.isDirect() && !buffer.hasArray()))
{
throw new IllegalArgumentException(
"Buffer may not be null and must have an array or be direct");
}
if (buffer instanceof ByteBuffer)
{
return computePointer((ByteBuffer)buffer);
}
if (buffer instanceof ShortBuffer)
{
return computePointer((ShortBuffer)buffer);
}
if (buffer instanceof IntBuffer)
{
return computePointer((IntBuffer)buffer);
}
if (buffer instanceof LongBuffer)
{
return computePointer((LongBuffer)buffer);
}
if (buffer instanceof FloatBuffer)
{
return computePointer((FloatBuffer)buffer);
}
if (buffer instanceof DoubleBuffer)
{
return computePointer((DoubleBuffer)buffer);
}
throw new IllegalArgumentException(
"Unknown buffer type: "+buffer);
}
/**
* Creates a new Pointer to the given buffer, taking into
* account the position and array offset of the given buffer.
* The buffer is assumed to be non-null
, and
* be either direct or have a backing array.
*
* @param buffer The buffer
* @return The pointer
*/
private static Pointer computePointer(ByteBuffer buffer)
{
Pointer result = null;
if (buffer.isDirect())
{
int oldPosition = buffer.position();
buffer.position(0);
result = Pointer.to(buffer.slice()).withByteOffset(
oldPosition * Sizeof.BYTE);
buffer.position(oldPosition);
}
else if (buffer.hasArray())
{
ByteBuffer t = ByteBuffer.wrap(buffer.array());
int elementOffset = buffer.position() + buffer.arrayOffset();
result = Pointer.to(t).withByteOffset(
elementOffset * Sizeof.BYTE);
}
return result;
}
/**
* Creates a new Pointer to the given buffer, taking into
* account the position and array offset of the given buffer.
* The buffer is assumed to be non-null
, and
* be either direct or have a backing array.
*
* @param buffer The buffer
* @return The pointer
*/
private static Pointer computePointer(ShortBuffer buffer)
{
Pointer result = null;
if (buffer.isDirect())
{
int oldPosition = buffer.position();
buffer.position(0);
result = Pointer.to(buffer.slice()).withByteOffset(
oldPosition * Sizeof.SHORT);
buffer.position(oldPosition);
}
else if (buffer.hasArray())
{
ShortBuffer t = ShortBuffer.wrap(buffer.array());
int elementOffset = buffer.position() + buffer.arrayOffset();
result = Pointer.to(t).withByteOffset(
elementOffset * Sizeof.SHORT);
}
return result;
}
/**
* Creates a new Pointer to the given buffer, taking into
* account the position and array offset of the given buffer.
* The buffer is assumed to be non-null
, and
* be either direct or have a backing array.
*
* @param buffer The buffer
* @return The pointer
*/
private static Pointer computePointer(IntBuffer buffer)
{
Pointer result = null;
if (buffer.isDirect())
{
int oldPosition = buffer.position();
buffer.position(0);
result = Pointer.to(buffer.slice()).withByteOffset(
oldPosition * Sizeof.INT);
buffer.position(oldPosition);
}
else if (buffer.hasArray())
{
IntBuffer t = IntBuffer.wrap(buffer.array());
int elementOffset = buffer.position() + buffer.arrayOffset();
result = Pointer.to(t).withByteOffset(
elementOffset * Sizeof.INT);
}
return result;
}
/**
* Creates a new Pointer to the given buffer, taking into
* account the position and array offset of the given buffer.
* The buffer is assumed to be non-null
, and
* be either direct or have a backing array.
*
* @param buffer The buffer
* @return The pointer
*/
private static Pointer computePointer(LongBuffer buffer)
{
Pointer result = null;
if (buffer.isDirect())
{
int oldPosition = buffer.position();
buffer.position(0);
result = Pointer.to(buffer.slice()).withByteOffset(
oldPosition * Sizeof.LONG);
buffer.position(oldPosition);
}
else if (buffer.hasArray())
{
LongBuffer t = LongBuffer.wrap(buffer.array());
int elementOffset = buffer.position() + buffer.arrayOffset();
result = Pointer.to(t).withByteOffset(
elementOffset * Sizeof.LONG);
}
return result;
}
/**
* Creates a new Pointer to the given buffer, taking into
* account the position and array offset of the given buffer.
* The buffer is assumed to be non-null
, and
* be either direct or have a backing array.
*
* @param buffer The buffer
* @return The pointer
*/
private static Pointer computePointer(FloatBuffer buffer)
{
Pointer result = null;
if (buffer.isDirect())
{
int oldPosition = buffer.position();
buffer.position(0);
result = Pointer.to(buffer.slice()).withByteOffset(
oldPosition * Sizeof.FLOAT);
buffer.position(oldPosition);
}
else if (buffer.hasArray())
{
FloatBuffer t = FloatBuffer.wrap(buffer.array());
int elementOffset = buffer.position() + buffer.arrayOffset();
result = Pointer.to(t).withByteOffset(
elementOffset * Sizeof.FLOAT);
}
return result;
}
/**
* Creates a new Pointer to the given buffer, taking into
* account the position and array offset of the given buffer.
* The buffer is assumed to be non-null
, and
* be either direct or have a backing array.
*
* @param buffer The buffer
* @return The pointer
*/
private static Pointer computePointer(DoubleBuffer buffer)
{
Pointer result = null;
if (buffer.isDirect())
{
int oldPosition = buffer.position();
buffer.position(0);
result = Pointer.to(buffer.slice()).withByteOffset(
oldPosition * Sizeof.DOUBLE);
buffer.position(oldPosition);
}
else if (buffer.hasArray())
{
DoubleBuffer t = DoubleBuffer.wrap(buffer.array());
int elementOffset = buffer.position() + buffer.arrayOffset();
result = Pointer.to(t).withByteOffset(
elementOffset * Sizeof.DOUBLE);
}
return result;
}
/**
* Creates a new Pointer to the given Pointers. The array
* of pointers may not be null
, and may not
* contain null
elements.
*
* @param pointers The pointers the pointer should point to
* @return The new pointer
* @throws IllegalArgumentException If the given array
* is null
*/
public static Pointer to(NativePointerObject ... pointers)
{
if (pointers == null)
{
throw new IllegalArgumentException(
"Pointer may not point to null objects");
}
return new Pointer(pointers);
}
/**
* Creates a new (null
) Pointer
*/
public Pointer()
{
buffer = null;
pointers = null;
byteOffset = 0;
}
/**
* Constructor which accepts a constant value as the pointer value.
* Solely for the constant pointer instances in the JCudaDriver
* class, to create the CU_LAUNCH_PARAM_END,
* CU_LAUNCH_PARAM_BUFFER_POINTER, and CU_LAUNCH_PARAM_BUFFER_SIZE
* pointer constants.
*
* @param nativePointerValue The native pointer value
*/
protected Pointer(long nativePointerValue)
{
super(nativePointerValue);
buffer = null;
pointers = null;
byteOffset = 0;
}
/**
* Creates a Pointer to the given Buffer
*
* @param buffer The buffer to point to
*/
private Pointer(Buffer buffer)
{
this.buffer = buffer;
pointers = null;
byteOffset = 0;
}
/**
* Creates a Pointer to the given array of pointers
*
* @param pointers The array the pointer points to
*/
private Pointer(NativePointerObject pointers[])
{
buffer = null;
this.pointers = pointers;
byteOffset = 0;
}
/**
* Copy constructor
*
* @param other The other Pointer
*/
protected Pointer(Pointer other) {
super(other.getNativePointer());
this.buffer = other.buffer;
this.pointers = other.pointers;
this.byteOffset = other.byteOffset;
}
/**
* Creates a copy of the given pointer, with an
* additional byte offset
*
* @param other The other pointer
* @param byteOffset The additional byte offset
*/
protected Pointer(Pointer other, long byteOffset)
{
this(other);
this.byteOffset += byteOffset;
}
/**
* Returns a new pointer with an offset of the given number
* of bytes
*
* @param byteOffset The byte offset for the pointer
* @return The new pointer with the given byte offset
*/
public Pointer withByteOffset(long byteOffset)
{
return new Pointer(this, byteOffset);
}
/**
* Returns a ByteBuffer that corresponds to the specified
* segment of the memory that this pointer points to.
*
* This function may only be applied to pointers that
* have been set to point to a region of host memory
* using either of the methods
* {@link jcuda.driver.JCudaDriver#cuMemAllocHost(Pointer, long)},
* {@link jcuda.driver.JCudaDriver#cuMemHostAlloc(Pointer, long, int)},
* {@link jcuda.runtime.JCuda#cudaMallocHost(Pointer, long)} or
* {@link jcuda.runtime.JCuda#cudaHostAlloc(Pointer, long, int)},
* or pointers that have been created with
* {@link Pointer#to(byte[])}.
*
* For other pointer types, null
is returned.
*
* @param byteOffset The offset in bytes
* @param byteSize The size of the byte buffer, in bytes
* @return The byte buffer
*/
public ByteBuffer getByteBuffer(long byteOffset, long byteSize)
{
if (buffer == null)
{
return null;
}
if (!(buffer instanceof ByteBuffer))
{
return null;
}
ByteBuffer byteBuffer = (ByteBuffer)buffer;
byteBuffer.limit((int)(byteOffset + byteSize));
byteBuffer.position((int)byteOffset);
return byteBuffer.slice();
}
/**
* Returns the byte offset
*
* @return The byte offset
*/
protected long getByteOffset()
{
return byteOffset;
}
/**
* Returns a String representation of this object.
*
* @return A String representation of this object.
*/
@Override
public String toString()
{
if (buffer != null)
{
return "Pointer["+
"buffer="+buffer+","+
"byteOffset="+byteOffset+"]";
}
else if (pointers != null)
{
return "Pointer["+
"pointers="+Arrays.toString(pointers)+","+
"byteOffset="+byteOffset+"]";
}
else
{
return "Pointer["+
"nativePointer=0x"+Long.toHexString(getNativePointer())+","+
"byteOffset="+byteOffset+"]";
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy